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

/**
 * Autogenerated by Thrift Compiler (0.9.2)
 *
 * DO NOT EDIT UNLESS YOU ARE SURE THAT YOU KNOW WHAT YOU ARE DOING
 *  @generated
 */
package org.apache.airavata.api;

import org.apache.thrift.scheme.IScheme;
import org.apache.thrift.scheme.SchemeFactory;
import org.apache.thrift.scheme.StandardScheme;

import org.apache.thrift.scheme.TupleScheme;
import org.apache.thrift.protocol.TTupleProtocol;
import org.apache.thrift.protocol.TProtocolException;
import org.apache.thrift.EncodingUtils;
import org.apache.thrift.TException;
import org.apache.thrift.async.AsyncMethodCallback;
import org.apache.thrift.server.AbstractNonblockingServer.*;
import java.util.List;
import java.util.ArrayList;
import java.util.Map;
import java.util.HashMap;
import java.util.EnumMap;
import java.util.Set;
import java.util.HashSet;
import java.util.EnumSet;
import java.util.Collections;
import java.util.BitSet;
import java.nio.ByteBuffer;
import java.util.Arrays;
import javax.annotation.Generated;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

@SuppressWarnings({"cast", "rawtypes", "serial", "unchecked"})
@Generated(value = "Autogenerated by Thrift Compiler (0.9.2)", date = "2015-11-16")
public class Airavata {

  public interface Iface {

    /**
     * Fetch Apache Airavata API version
     * 
     * @param authzToken
     */
    public String getAPIVersion(org.apache.airavata.model.security.AuthzToken authzToken) throws org.apache.airavata.model.error.InvalidRequestException, org.apache.airavata.model.error.AiravataClientException, org.apache.airavata.model.error.AiravataSystemException, org.apache.airavata.model.error.AuthorizationException, org.apache.thrift.TException;

    public String addGateway(org.apache.airavata.model.security.AuthzToken authzToken, org.apache.airavata.model.workspace.Gateway gateway) throws org.apache.airavata.model.error.InvalidRequestException, org.apache.airavata.model.error.AiravataClientException, org.apache.airavata.model.error.AiravataSystemException, org.apache.airavata.model.error.AuthorizationException, org.apache.thrift.TException;

    public void updateGateway(org.apache.airavata.model.security.AuthzToken authzToken, String gatewayId, org.apache.airavata.model.workspace.Gateway updatedGateway) throws org.apache.airavata.model.error.InvalidRequestException, org.apache.airavata.model.error.AiravataClientException, org.apache.airavata.model.error.AiravataSystemException, 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, String gatewayId) throws org.apache.airavata.model.error.InvalidRequestException, org.apache.airavata.model.error.AiravataClientException, org.apache.airavata.model.error.AiravataSystemException, org.apache.airavata.model.error.AuthorizationException, org.apache.thrift.TException;

    public boolean deleteGateway(org.apache.airavata.model.security.AuthzToken authzToken, String gatewayId) throws org.apache.airavata.model.error.InvalidRequestException, org.apache.airavata.model.error.AiravataClientException, org.apache.airavata.model.error.AiravataSystemException, org.apache.airavata.model.error.AuthorizationException, org.apache.thrift.TException;

    public List<org.apache.airavata.model.workspace.Gateway> getAllGateways(org.apache.airavata.model.security.AuthzToken authzToken) throws org.apache.airavata.model.error.InvalidRequestException, org.apache.airavata.model.error.AiravataClientException, org.apache.airavata.model.error.AiravataSystemException, org.apache.airavata.model.error.AuthorizationException, org.apache.thrift.TException;

    public boolean isGatewayExist(org.apache.airavata.model.security.AuthzToken authzToken, String gatewayId) throws org.apache.airavata.model.error.InvalidRequestException, org.apache.airavata.model.error.AiravataClientException, org.apache.airavata.model.error.AiravataSystemException, org.apache.airavata.model.error.AuthorizationException, org.apache.thrift.TException;

    /**
     * Generate and Register SSH Key Pair with Airavata Credential Store.
     * 
     * @param gatewayId
     *    The identifier for the requested gateway.
     * 
     * @param userName
     *    The User for which the credential should be registered. For community accounts, this user is the name of the
     *    community user name. For computational resources, this user name need not be the same user name on resoruces.
     * 
     * @return airavataCredStoreToken
     *   An SSH Key pair is generated and stored in the credential store and associated with users or community account
     *   belonging to a gateway.
     * 
     * 
     * 
     * @param authzToken
     * @param gatewayId
     * @param userName
     */
    public String generateAndRegisterSSHKeys(org.apache.airavata.model.security.AuthzToken authzToken, String gatewayId, String userName) throws org.apache.airavata.model.error.InvalidRequestException, org.apache.airavata.model.error.AiravataClientException, org.apache.airavata.model.error.AiravataSystemException, org.apache.thrift.TException;

    public String getSSHPubKey(org.apache.airavata.model.security.AuthzToken authzToken, String airavataCredStoreToken, String gatewayId) throws org.apache.airavata.model.error.InvalidRequestException, org.apache.airavata.model.error.AiravataClientException, org.apache.airavata.model.error.AiravataSystemException, org.apache.thrift.TException;

    public Map<String,String> getAllUserSSHPubKeys(org.apache.airavata.model.security.AuthzToken authzToken, String userName) throws org.apache.airavata.model.error.InvalidRequestException, org.apache.airavata.model.error.AiravataClientException, org.apache.airavata.model.error.AiravataSystemException, org.apache.thrift.TException;

    /**
     * Creates a Project with basic metadata.
     *    A Project is a container of experiments.
     * 
     * @param gatewayId
     *    The identifier for the requested gateway.
     * 
     * @param Project
     *    The Project Object described in the workspace_model
     * 
     * 
     * @param authzToken
     * @param gatewayId
     * @param project
     */
    public String createProject(org.apache.airavata.model.security.AuthzToken authzToken, String gatewayId, org.apache.airavata.model.workspace.Project project) throws org.apache.airavata.model.error.InvalidRequestException, org.apache.airavata.model.error.AiravataClientException, org.apache.airavata.model.error.AiravataSystemException, org.apache.airavata.model.error.AuthorizationException, org.apache.thrift.TException;

    /**
     * Update a Project
     * 
     * 
     * @param authzToken
     * @param projectId
     * @param updatedProject
     */
    public void updateProject(org.apache.airavata.model.security.AuthzToken authzToken, String projectId, org.apache.airavata.model.workspace.Project updatedProject) throws org.apache.airavata.model.error.InvalidRequestException, org.apache.airavata.model.error.AiravataClientException, org.apache.airavata.model.error.AiravataSystemException, org.apache.airavata.model.error.ProjectNotFoundException, org.apache.airavata.model.error.AuthorizationException, org.apache.thrift.TException;

    /**
     * Get a Project by ID
     * 
     * 
     * @param authzToken
     * @param projectId
     */
    public org.apache.airavata.model.workspace.Project getProject(org.apache.airavata.model.security.AuthzToken authzToken, String projectId) throws org.apache.airavata.model.error.InvalidRequestException, org.apache.airavata.model.error.AiravataClientException, org.apache.airavata.model.error.AiravataSystemException, org.apache.airavata.model.error.ProjectNotFoundException, org.apache.airavata.model.error.AuthorizationException, org.apache.thrift.TException;

    public boolean deleteProject(org.apache.airavata.model.security.AuthzToken authzToken, String projectId) throws org.apache.airavata.model.error.InvalidRequestException, org.apache.airavata.model.error.AiravataClientException, org.apache.airavata.model.error.AiravataSystemException, org.apache.airavata.model.error.ProjectNotFoundException, org.apache.airavata.model.error.AuthorizationException, org.apache.thrift.TException;

    /**
     *   * Get all Project by user with pagination. Results will be ordered based
     *   * on creation time DESC
     *   *
     *   * @param gatewayId
     *   *    The identifier for the requested gateway.
     *   * @param userName
     *   *    The identifier of the user
     *   * @param limit
     *   *    The amount results to be fetched
     *   * @param offset
     *   *    The starting point of the results to be fetched
     * *
     * 
     * @param authzToken
     * @param gatewayId
     * @param userName
     * @param limit
     * @param offset
     */
    public List<org.apache.airavata.model.workspace.Project> getUserProjects(org.apache.airavata.model.security.AuthzToken authzToken, String gatewayId, String userName, int limit, int offset) throws org.apache.airavata.model.error.InvalidRequestException, org.apache.airavata.model.error.AiravataClientException, org.apache.airavata.model.error.AiravataSystemException, org.apache.airavata.model.error.AuthorizationException, org.apache.thrift.TException;

    /**
     * Get all Project for user by project name with pagination.Results will be ordered based
     * on creation time DESC
     * 
     * @param gatewayId
     *    The identifier for the requested gateway.
     * @param userName
     *    The identifier of the user
     * @param projectName
     *    The name of the project on which the results to be fetched
     * @param limit
     *    The amount results to be fetched
     * @param offset
     *    The starting point of the results to be fetched
     * 
     * @param authzToken
     * @param gatewayId
     * @param userName
     * @param projectName
     * @param limit
     * @param offset
     */
    public List<org.apache.airavata.model.workspace.Project> searchProjectsByProjectName(org.apache.airavata.model.security.AuthzToken authzToken, String gatewayId, String userName, String projectName, int limit, int offset) throws org.apache.airavata.model.error.InvalidRequestException, org.apache.airavata.model.error.AiravataClientException, org.apache.airavata.model.error.AiravataSystemException, org.apache.airavata.model.error.AuthorizationException, org.apache.thrift.TException;

    /**
     * Search and get all Projects for user by project description with pagination. Results
     * will be ordered based on creation time DESC
     * 
     * @param gatewayId
     *    The identifier for the requested gateway.
     * @param userName
     *    The identifier of the user
     * @param description
     *    The description to be matched
     * @param limit
     *    The amount results to be fetched
     * @param offset
     *    The starting point of the results to be fetched
     * 
     * @param authzToken
     * @param gatewayId
     * @param userName
     * @param description
     * @param limit
     * @param offset
     */
    public List<org.apache.airavata.model.workspace.Project> searchProjectsByProjectDesc(org.apache.airavata.model.security.AuthzToken authzToken, String gatewayId, String userName, String description, int limit, int offset) throws org.apache.airavata.model.error.InvalidRequestException, org.apache.airavata.model.error.AiravataClientException, org.apache.airavata.model.error.AiravataSystemException, org.apache.airavata.model.error.AuthorizationException, org.apache.thrift.TException;

    /**
     * Search Experiments by experiment name with pagination. Results will be sorted
     * based on creation time DESC
     * 
     * @param gatewayId
     *       Identifier of the requested gateway
     * @param userName
     *       Username of the requested user
     * @param expName
     *       Experiment name to be matched
     * @param limit
     *       Amount of results to be fetched
     * @param offset
     *       The starting point of the results to be fetched
     * 
     * @param authzToken
     * @param gatewayId
     * @param userName
     * @param expName
     * @param limit
     * @param offset
     */
    public List<org.apache.airavata.model.experiment.ExperimentSummaryModel> searchExperimentsByName(org.apache.airavata.model.security.AuthzToken authzToken, String gatewayId, String userName, String expName, int limit, int offset) throws org.apache.airavata.model.error.InvalidRequestException, org.apache.airavata.model.error.AiravataClientException, org.apache.airavata.model.error.AiravataSystemException, org.apache.airavata.model.error.AuthorizationException, org.apache.thrift.TException;

    /**
     * Search Experiments by experiment name with pagination. Results will be sorted
     * based on creation time DESC
     * 
     * @param gatewayId
     *       Identifier of the requested gateway
     * @param userName
     *       Username of the requested user
     * @param description
     *       Experiment description to be matched
     * @param limit
     *       Amount of results to be fetched
     * @param offset
     *       The starting point of the results to be fetched
     * 
     * @param authzToken
     * @param gatewayId
     * @param userName
     * @param description
     * @param limit
     * @param offset
     */
    public List<org.apache.airavata.model.experiment.ExperimentSummaryModel> searchExperimentsByDesc(org.apache.airavata.model.security.AuthzToken authzToken, String gatewayId, String userName, String description, int limit, int offset) throws org.apache.airavata.model.error.InvalidRequestException, org.apache.airavata.model.error.AiravataClientException, org.apache.airavata.model.error.AiravataSystemException, org.apache.airavata.model.error.AuthorizationException, org.apache.thrift.TException;

    /**
     * Search Experiments by application id with pagination. Results will be sorted
     * based on creation time DESC
     * 
     * @param gatewayId
     *       Identifier of the requested gateway
     * @param userName
     *       Username of the requested user
     * @param applicationId
     *       Application id to be matched
     * @param limit
     *       Amount of results to be fetched
     * @param offset
     *       The starting point of the results to be fetched
     * 
     * @param authzToken
     * @param gatewayId
     * @param userName
     * @param applicationId
     * @param limit
     * @param offset
     */
    public List<org.apache.airavata.model.experiment.ExperimentSummaryModel> searchExperimentsByApplication(org.apache.airavata.model.security.AuthzToken authzToken, String gatewayId, String userName, String applicationId, int limit, int offset) throws org.apache.airavata.model.error.InvalidRequestException, org.apache.airavata.model.error.AiravataClientException, org.apache.airavata.model.error.AiravataSystemException, org.apache.airavata.model.error.AuthorizationException, org.apache.thrift.TException;

    /**
     * Search Experiments by experiment status with pagination. Results will be sorted
     * based on creation time DESC
     * 
     * @param gatewayId
     *       Identifier of the requested gateway
     * @param userName
     *       Username of the requested user
     * @param experimentState
     *       Experiement state to be matched
     * @param limit
     *       Amount of results to be fetched
     * @param offset
     *       The starting point of the results to be fetched
     * 
     * @param authzToken
     * @param gatewayId
     * @param userName
     * @param experimentState
     * @param limit
     * @param offset
     */
    public List<org.apache.airavata.model.experiment.ExperimentSummaryModel> searchExperimentsByStatus(org.apache.airavata.model.security.AuthzToken authzToken, String gatewayId, String userName, org.apache.airavata.model.status.ExperimentState experimentState, int limit, int offset) throws org.apache.airavata.model.error.InvalidRequestException, org.apache.airavata.model.error.AiravataClientException, org.apache.airavata.model.error.AiravataSystemException, org.apache.airavata.model.error.AuthorizationException, org.apache.thrift.TException;

    /**
     * Search Experiments by experiment creation time with pagination. Results will be sorted
     * based on creation time DESC
     * 
     * @param gatewayId
     *       Identifier of the requested gateway
     * @param userName
     *       Username of the requested user
     * @param fromTime
     *       Start time of the experiments creation time
     * @param toTime
     *       End time of the  experiement creation time
     * @param limit
     *       Amount of results to be fetched
     * @param offset
     *       The starting point of the results to be fetched
     * 
     * @param authzToken
     * @param gatewayId
     * @param userName
     * @param fromTime
     * @param toTime
     * @param limit
     * @param offset
     */
    public List<org.apache.airavata.model.experiment.ExperimentSummaryModel> searchExperimentsByCreationTime(org.apache.airavata.model.security.AuthzToken authzToken, String gatewayId, String userName, long fromTime, long toTime, int limit, int offset) throws org.apache.airavata.model.error.InvalidRequestException, org.apache.airavata.model.error.AiravataClientException, org.apache.airavata.model.error.AiravataSystemException, org.apache.airavata.model.error.AuthorizationException, org.apache.thrift.TException;

    /**
     * Search Experiments by using multiple filter criteria with pagination. Results will be sorted
     * based on creation time DESC
     * 
     * @param gatewayId
     *       Identifier of the requested gateway
     * @param userName
     *       Username of the requested user
     * @param filters
     *       map of multiple filter criteria.
     * @param limit
     *       Amount of results to be fetched
     * @param offset
     *       The starting point of the results to be fetched
     * 
     * @param authzToken
     * @param gatewayId
     * @param userName
     * @param filters
     * @param limit
     * @param offset
     */
    public List<org.apache.airavata.model.experiment.ExperimentSummaryModel> searchExperiments(org.apache.airavata.model.security.AuthzToken authzToken, String gatewayId, String userName, Map<org.apache.airavata.model.experiment.ExperimentSearchFields,String> filters, int limit, int offset) throws org.apache.airavata.model.error.InvalidRequestException, org.apache.airavata.model.error.AiravataClientException, org.apache.airavata.model.error.AiravataSystemException, org.apache.airavata.model.error.AuthorizationException, org.apache.thrift.TException;

    /**
     * Get Experiment Statisitics for the given gateway for a specific time period
     * @param gatewayId
     *       Identifier of the requested gateway
     * @param fromTime
     *       Starting date time
     * @param toTime
     *       Ending data time
     * 
     * 
     * @param authzToken
     * @param gatewayId
     * @param fromTime
     * @param toTime
     */
    public org.apache.airavata.model.experiment.ExperimentStatistics getExperimentStatistics(org.apache.airavata.model.security.AuthzToken authzToken, String gatewayId, long fromTime, long toTime) throws org.apache.airavata.model.error.InvalidRequestException, org.apache.airavata.model.error.AiravataClientException, org.apache.airavata.model.error.AiravataSystemException, org.apache.airavata.model.error.AuthorizationException, org.apache.thrift.TException;

    /**
     * Get Experiments within project with pagination. Results will be sorted
     * based on creation time DESC
     * 
     * @param projectId
     *       Identifier of the project
     * @param limit
     *       Amount of results to be fetched
     * @param offset
     *       The starting point of the results to be fetched
     * 
     * @param authzToken
     * @param projectId
     * @param limit
     * @param offset
     */
    public List<org.apache.airavata.model.experiment.ExperimentModel> getExperimentsInProject(org.apache.airavata.model.security.AuthzToken authzToken, String projectId, int limit, int offset) throws org.apache.airavata.model.error.InvalidRequestException, org.apache.airavata.model.error.AiravataClientException, org.apache.airavata.model.error.AiravataSystemException, org.apache.airavata.model.error.ProjectNotFoundException, org.apache.airavata.model.error.AuthorizationException, org.apache.thrift.TException;

    /**
     * Get experiments by user with pagination. Results will be sorted
     * based on creation time DESC
     * 
     * @param gatewayId
     *       Identifier of the requesting gateway
     * @param userName
     *       Username of the requested user
     * @param limit
     *       Amount of results to be fetched
     * @param offset
     *       The starting point of the results to be fetched
     * 
     * @param authzToken
     * @param gatewayId
     * @param userName
     * @param limit
     * @param offset
     */
    public List<org.apache.airavata.model.experiment.ExperimentModel> getUserExperiments(org.apache.airavata.model.security.AuthzToken authzToken, String gatewayId, String userName, int limit, int offset) throws org.apache.airavata.model.error.InvalidRequestException, org.apache.airavata.model.error.AiravataClientException, org.apache.airavata.model.error.AiravataSystemException, org.apache.airavata.model.error.AuthorizationException, org.apache.thrift.TException;

    /**
     * Create an experiment for the specified user belonging to the gateway. The gateway identity is not explicitly passed
     *   but inferred from the authentication header. This experiment is just a persistent place holder. The client
     *   has to subsequently configure and launch the created experiment. No action is taken on Airavata Server except
     *   registering the experiment in a persistent store.
     * 
     * @param basicExperimentMetadata
     *    The create experiment will require the basic experiment metadata like the name and description, intended user,
     *      the gateway identifer and if the experiment should be shared public by defualt. During the creation of an experiment
     *      the ExperimentMetadata is a required field.
     * 
     * @return
     *   The server-side generated.airavata.registry.core.experiment.globally unique identifier.
     * 
     * @throws org.apache.airavata.model.error.InvalidRequestException
     *    For any incorrect forming of the request itself.
     * 
     * @throws org.apache.airavata.model.error.AiravataClientException
     *    The following list of exceptions are thrown which Airavata Client can take corrective actions to resolve:
     * 
     *      UNKNOWN_GATEWAY_ID - If a Gateway is not registered with Airavata as a one time administrative
     *         step, then Airavata Registry will not have a provenance area setup. The client has to follow
     *         gateway registration steps and retry this request.
     * 
     *      AUTHENTICATION_FAILURE - How Authentication will be implemented is yet to be determined.
     *         For now this is a place holder.
     * 
     *      INVALID_AUTHORIZATION - This will throw an authorization exception. When a more robust security hand-shake
     *         is implemented, the authorization will be more substantial.
     * 
     * @throws org.apache.airavata.model.error.AiravataSystemException
     *    This exception will be thrown for any Airavata Server side issues and if the problem cannot be corrected by the client
     *       rather an Airavata Administrator will be notified to take corrective action.
     * 
     * 
     * @param authzToken
     * @param gatewayId
     * @param experiment
     */
    public String createExperiment(org.apache.airavata.model.security.AuthzToken authzToken, String gatewayId, org.apache.airavata.model.experiment.ExperimentModel experiment) throws org.apache.airavata.model.error.InvalidRequestException, org.apache.airavata.model.error.AiravataClientException, org.apache.airavata.model.error.AiravataSystemException, org.apache.airavata.model.error.AuthorizationException, org.apache.thrift.TException;

    /**
     * If the experiment is not already launched experiment can be deleted.
     * 
     * @param authzToken
     * @param experiementId
     * 
     * @return boolean identifier for the success or failure of the deletion operation
     * 
     * 
     * @param authzToken
     * @param experimentId
     */
    public boolean deleteExperiment(org.apache.airavata.model.security.AuthzToken authzToken, String experimentId) throws org.apache.airavata.model.error.InvalidRequestException, org.apache.airavata.model.error.AiravataClientException, org.apache.airavata.model.error.AiravataSystemException, org.apache.airavata.model.error.AuthorizationException, org.apache.thrift.TException;

    /**
     * Fetch previously created experiment metadata.
     * 
     * @param airavataExperimentId
     *    The identifier for the requested experiment. This is returned during the create experiment step.
     * 
     * @return experimentMetada
     *   This method will return the previously stored experiment metadata.
     * 
     * @throws org.apache.airavata.model.error.InvalidRequestException
     *    For any incorrect forming of the request itself.
     * 
     * @throws org.apache.airavata.model.error.ExperimentNotFoundException
     *    If the specified experiment is not previously created, then an Experiment Not Found Exception is thrown.
     * 
     * @throws org.apache.airavata.model.error.AiravataClientException
     *    The following list of exceptions are thrown which Airavata Client can take corrective actions to resolve:
     *      
     *      UNKNOWN_GATEWAY_ID - If a Gateway is not registered with Airavata as a one time administrative
     *         step, then Airavata Registry will not have a provenance area setup. The client has to follow
     *         gateway registration steps and retry this request.
     * 
     *      AUTHENTICATION_FAILURE - How Authentication will be implemented is yet to be determined.
     *         For now this is a place holder.
     * 
     *      INVALID_AUTHORIZATION - This will throw an authorization exception. When a more robust security hand-shake
     *         is implemented, the authorization will be more substantial.
     * 
     * @throws org.apache.airavata.model.error.AiravataSystemException
     *    This exception will be thrown for any Airavata Server side issues and if the problem cannot be corrected by the client
     *       rather an Airavata Administrator will be notified to take corrective action.
     * 
     * 
     * @param authzToken
     * @param airavataExperimentId
     */
    public org.apache.airavata.model.experiment.ExperimentModel getExperiment(org.apache.airavata.model.security.AuthzToken authzToken, String airavataExperimentId) throws org.apache.airavata.model.error.InvalidRequestException, org.apache.airavata.model.error.ExperimentNotFoundException, org.apache.airavata.model.error.AiravataClientException, org.apache.airavata.model.error.AiravataSystemException, org.apache.airavata.model.error.AuthorizationException, org.apache.thrift.TException;

    /**
     * Fetch the completed nested tree structue of previously created experiment metadata which includes processes ->
     * tasks -> jobs information.
     * 
     * @param airavataExperimentId
     *    The identifier for the requested experiment. This is returned during the create experiment step.
     * 
     * @return experimentMetada
     *   This method will return the previously stored experiment metadata.
     * 
     * @throws org.apache.airavata.model.error.InvalidRequestException
     *    For any incorrect forming of the request itself.
     * 
     * @throws org.apache.airavata.model.error.ExperimentNotFoundException
     *    If the specified experiment is not previously created, then an Experiment Not Found Exception is thrown.
     * 
     * @throws org.apache.airavata.model.error.AiravataClientException
     *    The following list of exceptions are thrown which Airavata Client can take corrective actions to resolve:
     * 
     *      UNKNOWN_GATEWAY_ID - If a Gateway is not registered with Airavata as a one time administrative
     *         step, then Airavata Registry will not have a provenance area setup. The client has to follow
     *         gateway registration steps and retry this request.
     * 
     *      AUTHENTICATION_FAILURE - How Authentication will be implemented is yet to be determined.
     *         For now this is a place holder.
     * 
     *      INVALID_AUTHORIZATION - This will throw an authorization exception. When a more robust security hand-shake
     *         is implemented, the authorization will be more substantial.
     * 
     * @throws org.apache.airavata.model.error.AiravataSystemException
     *    This exception will be thrown for any Airavata Server side issues and if the problem cannot be corrected by the client
     *       rather an Airavata Administrator will be notified to take corrective action.
     * 
     * 
     * @param authzToken
     * @param airavataExperimentId
     */
    public org.apache.airavata.model.experiment.ExperimentModel getDetailedExperimentTree(org.apache.airavata.model.security.AuthzToken authzToken, String airavataExperimentId) throws org.apache.airavata.model.error.InvalidRequestException, org.apache.airavata.model.error.ExperimentNotFoundException, org.apache.airavata.model.error.AiravataClientException, org.apache.airavata.model.error.AiravataSystemException, org.apache.airavata.model.error.AuthorizationException, org.apache.thrift.TException;

    /**
     * Configure a previously created experiment with required inputs, scheduling and other quality of service
     *   parameters. This method only updates the experiment object within the registry. The experiment has to be launched
     *   to make it actionable by the server.
     * 
     * @param airavataExperimentId
     *    The identifier for the requested experiment. This is returned during the create experiment step.
     * 
     * @param experimentConfigurationData
     *    The configuration information of the experiment with application input parameters, computational resource scheduling
     *      information, special input output handling and additional quality of service parameters.
     * 
     * @return
     *   This method call does not have a return value.
     * 
     * @throws org.apache.airavata.model.error.InvalidRequestException
     *    For any incorrect forming of the request itself.
     * 
     * @throws org.apache.airavata.model.error.ExperimentNotFoundException
     *    If the specified experiment is not previously created, then an Experiment Not Found Exception is thrown.
     * 
     * @throws org.apache.airavata.model.error.AiravataClientException
     *    The following list of exceptions are thrown which Airavata Client can take corrective actions to resolve:
     *      
     *      UNKNOWN_GATEWAY_ID - If a Gateway is not registered with Airavata as a one time administrative
     *         step, then Airavata Registry will not have a provenance area setup. The client has to follow
     *         gateway registration steps and retry this request.
     * 
     *      AUTHENTICATION_FAILURE - How Authentication will be implemented is yet to be determined.
     *         For now this is a place holder.
     * 
     *      INVALID_AUTHORIZATION - This will throw an authorization exception. When a more robust security hand-shake
     *         is implemented, the authorization will be more substantial.
     * 
     * @throws org.apache.airavata.model.error.AiravataSystemException
     *    This exception will be thrown for any Airavata Server side issues and if the problem cannot be corrected by the client
     *       rather an Airavata Administrator will be notified to take corrective action.
     * 
     * 
     * @param authzToken
     * @param airavataExperimentId
     * @param experiment
     */
    public void updateExperiment(org.apache.airavata.model.security.AuthzToken authzToken, String airavataExperimentId, org.apache.airavata.model.experiment.ExperimentModel experiment) throws org.apache.airavata.model.error.InvalidRequestException, org.apache.airavata.model.error.ExperimentNotFoundException, org.apache.airavata.model.error.AiravataClientException, org.apache.airavata.model.error.AiravataSystemException, org.apache.airavata.model.error.AuthorizationException, org.apache.thrift.TException;

    public void updateExperimentConfiguration(org.apache.airavata.model.security.AuthzToken authzToken, String airavataExperimentId, org.apache.airavata.model.experiment.UserConfigurationDataModel userConfiguration) throws org.apache.airavata.model.error.AuthorizationException, org.apache.thrift.TException;

    public void updateResourceScheduleing(org.apache.airavata.model.security.AuthzToken authzToken, String airavataExperimentId, org.apache.airavata.model.scheduling.ComputationalResourceSchedulingModel resourceScheduling) throws org.apache.airavata.model.error.AuthorizationException, org.apache.thrift.TException;

    /**
     *  *
     *  * Validate experiment configuration. A true in general indicates, the experiment is ready to be launched.
     *  *
     *  * @param experimentID
     *  * @return sucess/failure
     *  *
     * *
     * 
     * @param authzToken
     * @param airavataExperimentId
     */
    public boolean validateExperiment(org.apache.airavata.model.security.AuthzToken authzToken, String airavataExperimentId) throws org.apache.airavata.model.error.InvalidRequestException, org.apache.airavata.model.error.ExperimentNotFoundException, org.apache.airavata.model.error.AiravataClientException, org.apache.airavata.model.error.AiravataSystemException, org.apache.airavata.model.error.AuthorizationException, org.apache.thrift.TException;

    /**
     * Launch a previously created and configured experiment. Airavata Server will then start processing the request and appropriate
     *   notifications and intermediate and output data will be subsequently available for this experiment.
     * 
     * @param airavataExperimentId
     *    The identifier for the requested experiment. This is returned during the create experiment step.
     * 
     * @return
     *   This method call does not have a return value.
     * 
     * @throws org.apache.airavata.model.error.InvalidRequestException
     *    For any incorrect forming of the request itself.
     * 
     * @throws org.apache.airavata.model.error.ExperimentNotFoundException
     *    If the specified experiment is not previously created, then an Experiment Not Found Exception is thrown.
     * 
     * @throws org.apache.airavata.model.error.AiravataClientException
     *    The following list of exceptions are thrown which Airavata Client can take corrective actions to resolve:
     *      
     *      UNKNOWN_GATEWAY_ID - If a Gateway is not registered with Airavata as a one time administrative
     *         step, then Airavata Registry will not have a provenance area setup. The client has to follow
     *         gateway registration steps and retry this request.
     * 
     *      AUTHENTICATION_FAILURE - How Authentication will be implemented is yet to be determined.
     *         For now this is a place holder.
     * 
     *      INVALID_AUTHORIZATION - This will throw an authorization exception. When a more robust security hand-shake
     *         is implemented, the authorization will be more substantial.
     * 
     * @throws org.apache.airavata.model.error.AiravataSystemException
     *    This exception will be thrown for any Airavata Server side issues and if the problem cannot be corrected by the client
     *       rather an Airavata Administrator will be notified to take corrective action.
     * 
     * 
     * @param authzToken
     * @param airavataExperimentId
     * @param gatewayId
     */
    public void launchExperiment(org.apache.airavata.model.security.AuthzToken authzToken, String airavataExperimentId, String gatewayId) throws org.apache.airavata.model.error.InvalidRequestException, org.apache.airavata.model.error.ExperimentNotFoundException, org.apache.airavata.model.error.AiravataClientException, org.apache.airavata.model.error.AiravataSystemException, org.apache.airavata.model.error.AuthorizationException, org.apache.thrift.TException;

    public org.apache.airavata.model.status.ExperimentStatus getExperimentStatus(org.apache.airavata.model.security.AuthzToken authzToken, String airavataExperimentId) throws org.apache.airavata.model.error.InvalidRequestException, org.apache.airavata.model.error.ExperimentNotFoundException, org.apache.airavata.model.error.AiravataClientException, org.apache.airavata.model.error.AiravataSystemException, org.apache.airavata.model.error.AuthorizationException, org.apache.thrift.TException;

    public List<org.apache.airavata.model.application.io.OutputDataObjectType> getExperimentOutputs(org.apache.airavata.model.security.AuthzToken authzToken, String airavataExperimentId) throws org.apache.airavata.model.error.InvalidRequestException, org.apache.airavata.model.error.ExperimentNotFoundException, org.apache.airavata.model.error.AiravataClientException, org.apache.airavata.model.error.AiravataSystemException, org.apache.airavata.model.error.AuthorizationException, org.apache.thrift.TException;

    public List<org.apache.airavata.model.application.io.OutputDataObjectType> getIntermediateOutputs(org.apache.airavata.model.security.AuthzToken authzToken, String airavataExperimentId) throws org.apache.airavata.model.error.InvalidRequestException, org.apache.airavata.model.error.ExperimentNotFoundException, org.apache.airavata.model.error.AiravataClientException, org.apache.airavata.model.error.AiravataSystemException, org.apache.airavata.model.error.AuthorizationException, org.apache.thrift.TException;

    public Map<String,org.apache.airavata.model.status.JobStatus> getJobStatuses(org.apache.airavata.model.security.AuthzToken authzToken, String airavataExperimentId) throws org.apache.airavata.model.error.InvalidRequestException, org.apache.airavata.model.error.ExperimentNotFoundException, org.apache.airavata.model.error.AiravataClientException, org.apache.airavata.model.error.AiravataSystemException, org.apache.airavata.model.error.AuthorizationException, org.apache.thrift.TException;

    public List<org.apache.airavata.model.job.JobModel> getJobDetails(org.apache.airavata.model.security.AuthzToken authzToken, String airavataExperimentId) throws org.apache.airavata.model.error.InvalidRequestException, org.apache.airavata.model.error.ExperimentNotFoundException, org.apache.airavata.model.error.AiravataClientException, org.apache.airavata.model.error.AiravataSystemException, org.apache.airavata.model.error.AuthorizationException, org.apache.thrift.TException;

    /**
     * Clone an specified experiment with a new name. A copy of the experiment configuration is made and is persisted with new metadata.
     *   The client has to subsequently update this configuration if needed and launch the cloned experiment.
     * 
     * @param newExperimentName
     *    experiment name that should be used in the cloned experiment
     * 
     * @param updatedExperiment
     *    Once an experiment is cloned, to disambiguate, the users are suggested to provide new metadata. This will again require
     *      the basic experiment metadata like the name and description, intended user, the gateway identifier and if the experiment
     *      should be shared public by default.
     * 
     * @return
     *   The server-side generated.airavata.registry.core.experiment.globally unique identifier for the newly cloned experiment.
     * 
     * @throws org.apache.airavata.model.error.InvalidRequestException
     *    For any incorrect forming of the request itself.
     * 
     * @throws org.apache.airavata.model.error.ExperimentNotFoundException
     *    If the specified experiment is not previously created, then an Experiment Not Found Exception is thrown.
     * 
     * @throws org.apache.airavata.model.error.AiravataClientException
     *    The following list of exceptions are thrown which Airavata Client can take corrective actions to resolve:
     *      
     *      UNKNOWN_GATEWAY_ID - If a Gateway is not registered with Airavata as a one time administrative
     *         step, then Airavata Registry will not have a provenance area setup. The client has to follow
     *         gateway registration steps and retry this request.
     * 
     *      AUTHENTICATION_FAILURE - How Authentication will be implemented is yet to be determined.
     *         For now this is a place holder.
     * 
     *      INVALID_AUTHORIZATION - This will throw an authorization exception. When a more robust security hand-shake
     *         is implemented, the authorization will be more substantial.
     * 
     * @throws org.apache.airavata.model.error.AiravataSystemException
     *    This exception will be thrown for any Airavata Server side issues and if the problem cannot be corrected by the client
     *       rather an Airavata Administrator will be notified to take corrective action.
     * 
     * 
     * @param authzToken
     * @param existingExperimentID
     * @param newExperimentName
     */
    public String cloneExperiment(org.apache.airavata.model.security.AuthzToken authzToken, String existingExperimentID, String newExperimentName) throws org.apache.airavata.model.error.InvalidRequestException, org.apache.airavata.model.error.ExperimentNotFoundException, org.apache.airavata.model.error.AiravataClientException, org.apache.airavata.model.error.AiravataSystemException, org.apache.airavata.model.error.AuthorizationException, org.apache.thrift.TException;

    /**
     * Terminate a running experiment.
     * 
     * @param airavataExperimentId
     *    The identifier for the requested experiment. This is returned during the create experiment step.
     * 
     * @return
     *   This method call does not have a return value.
     * 
     * @throws org.apache.airavata.model.error.InvalidRequestException
     *    For any incorrect forming of the request itself.
     * 
     * @throws org.apache.airavata.model.error.ExperimentNotFoundException
     *    If the specified experiment is not previously created, then an Experiment Not Found Exception is thrown.
     * 
     * @throws org.apache.airavata.model.error.AiravataClientException
     *    The following list of exceptions are thrown which Airavata Client can take corrective actions to resolve:
     *      
     *      UNKNOWN_GATEWAY_ID - If a Gateway is not registered with Airavata as a one time administrative
     *         step, then Airavata Registry will not have a provenance area setup. The client has to follow
     *         gateway registration steps and retry this request.
     * 
     *      AUTHENTICATION_FAILURE - How Authentication will be implemented is yet to be determined.
     *         For now this is a place holder.
     * 
     *      INVALID_AUTHORIZATION - This will throw an authorization exception. When a more robust security hand-shake
     *         is implemented, the authorization will be more substantial.
     * 
     * @throws org.apache.airavata.model.error.AiravataSystemException
     *    This exception will be thrown for any Airavata Server side issues and if the problem cannot be corrected by the client
     *       rather an Airavata Administrator will be notified to take corrective action.
     * 
     * 
     * @param authzToken
     * @param airavataExperimentId
     * @param gatewayId
     */
    public void terminateExperiment(org.apache.airavata.model.security.AuthzToken authzToken, String airavataExperimentId, String gatewayId) throws org.apache.airavata.model.error.InvalidRequestException, org.apache.airavata.model.error.ExperimentNotFoundException, org.apache.airavata.model.error.AiravataClientException, org.apache.airavata.model.error.AiravataSystemException, org.apache.airavata.model.error.AuthorizationException, org.apache.thrift.TException;

    /**
     * Register a Application Module.
     * 
     * @param applicationModule
     *    Application Module Object created from the datamodel.
     * 
     * @return appModuleId
     *   Returns a server-side generated airavata appModule globally unique identifier.
     * 
     * 
     * @param authzToken
     * @param gatewayId
     * @param applicationModule
     */
    public String registerApplicationModule(org.apache.airavata.model.security.AuthzToken authzToken, String gatewayId, org.apache.airavata.model.appcatalog.appdeployment.ApplicationModule applicationModule) throws org.apache.airavata.model.error.InvalidRequestException, org.apache.airavata.model.error.AiravataClientException, org.apache.airavata.model.error.AiravataSystemException, org.apache.airavata.model.error.AuthorizationException, org.apache.thrift.TException;

    /**
     * Fetch a Application Module.
     * 
     * @param appModuleId
     *   The identifier for the requested application module
     * 
     * @return applicationModule
     *   Returns a application Module Object.
     * 
     * 
     * @param authzToken
     * @param appModuleId
     */
    public org.apache.airavata.model.appcatalog.appdeployment.ApplicationModule getApplicationModule(org.apache.airavata.model.security.AuthzToken authzToken, String appModuleId) throws org.apache.airavata.model.error.InvalidRequestException, org.apache.airavata.model.error.AiravataClientException, org.apache.airavata.model.error.AiravataSystemException, org.apache.airavata.model.error.AuthorizationException, org.apache.thrift.TException;

    /**
     * Update a Application Module.
     * 
     * @param appModuleId
     *   The identifier for the requested application module to be updated.
     * 
     * @param applicationModule
     *    Application Module Object created from the datamodel.
     * 
     * @return status
     *   Returns a success/failure of the update.
     * 
     * 
     * @param authzToken
     * @param appModuleId
     * @param applicationModule
     */
    public boolean updateApplicationModule(org.apache.airavata.model.security.AuthzToken authzToken, String appModuleId, org.apache.airavata.model.appcatalog.appdeployment.ApplicationModule applicationModule) throws org.apache.airavata.model.error.InvalidRequestException, org.apache.airavata.model.error.AiravataClientException, org.apache.airavata.model.error.AiravataSystemException, org.apache.airavata.model.error.AuthorizationException, org.apache.thrift.TException;

    public List<org.apache.airavata.model.appcatalog.appdeployment.ApplicationModule> getAllAppModules(org.apache.airavata.model.security.AuthzToken authzToken, String gatewayId) throws org.apache.airavata.model.error.InvalidRequestException, org.apache.airavata.model.error.AiravataClientException, org.apache.airavata.model.error.AiravataSystemException, org.apache.airavata.model.error.AuthorizationException, org.apache.thrift.TException;

    /**
     * Delete a Application Module.
     * 
     * @param appModuleId
     *   The identifier for the requested application module to be deleted.
     * 
     * @return status
     *   Returns a success/failure of the deletion.
     * 
     * 
     * @param authzToken
     * @param appModuleId
     */
    public boolean deleteApplicationModule(org.apache.airavata.model.security.AuthzToken authzToken, String appModuleId) throws org.apache.airavata.model.error.InvalidRequestException, org.apache.airavata.model.error.AiravataClientException, org.apache.airavata.model.error.AiravataSystemException, org.apache.airavata.model.error.AuthorizationException, org.apache.thrift.TException;

    /**
     * Register a Application Deployment.
     * 
     * @param applicationModule
     *    Application Module Object created from the datamodel.
     * 
     * @return appDeploymentId
     *   Returns a server-side generated airavata appDeployment globally unique identifier.
     * 
     * 
     * @param authzToken
     * @param gatewayId
     * @param applicationDeployment
     */
    public String registerApplicationDeployment(org.apache.airavata.model.security.AuthzToken authzToken, String gatewayId, org.apache.airavata.model.appcatalog.appdeployment.ApplicationDeploymentDescription applicationDeployment) throws org.apache.airavata.model.error.InvalidRequestException, org.apache.airavata.model.error.AiravataClientException, org.apache.airavata.model.error.AiravataSystemException, org.apache.airavata.model.error.AuthorizationException, org.apache.thrift.TException;

    /**
     * Fetch a Application Deployment.
     * 
     * @param appDeploymentId
     *   The identifier for the requested application module
     * 
     * @return applicationDeployment
     *   Returns a application Deployment Object.
     * 
     * 
     * @param authzToken
     * @param appDeploymentId
     */
    public org.apache.airavata.model.appcatalog.appdeployment.ApplicationDeploymentDescription getApplicationDeployment(org.apache.airavata.model.security.AuthzToken authzToken, String appDeploymentId) throws org.apache.airavata.model.error.InvalidRequestException, org.apache.airavata.model.error.AiravataClientException, org.apache.airavata.model.error.AiravataSystemException, org.apache.airavata.model.error.AuthorizationException, org.apache.thrift.TException;

    /**
     * Update a Application Deployment.
     * 
     * @param appDeploymentId
     *   The identifier for the requested application deployment to be updated.
     * 
     * @param appDeployment
     *    Application Deployment Object created from the datamodel.
     * 
     * @return status
     *   Returns a success/failure of the update.
     * 
     * 
     * @param authzToken
     * @param appDeploymentId
     * @param applicationDeployment
     */
    public boolean updateApplicationDeployment(org.apache.airavata.model.security.AuthzToken authzToken, String appDeploymentId, org.apache.airavata.model.appcatalog.appdeployment.ApplicationDeploymentDescription applicationDeployment) throws org.apache.airavata.model.error.InvalidRequestException, org.apache.airavata.model.error.AiravataClientException, org.apache.airavata.model.error.AiravataSystemException, org.apache.airavata.model.error.AuthorizationException, org.apache.thrift.TException;

    /**
     * Delete a Application deployment.
     * 
     * @param appDeploymentId
     *   The identifier for the requested application deployment to be deleted.
     * 
     * @return status
     *   Returns a success/failure of the deletion.
     * 
     * 
     * @param authzToken
     * @param appDeploymentId
     */
    public boolean deleteApplicationDeployment(org.apache.airavata.model.security.AuthzToken authzToken, String appDeploymentId) throws org.apache.airavata.model.error.InvalidRequestException, org.apache.airavata.model.error.AiravataClientException, org.apache.airavata.model.error.AiravataSystemException, org.apache.airavata.model.error.AuthorizationException, org.apache.thrift.TException;

    /**
     * Fetch all Application Deployment Descriptions.
     * 
     * @return list<applicationDeployment.
     *   Returns the list of all application Deployment Objects.
     * 
     * 
     * @param authzToken
     * @param gatewayId
     */
    public List<org.apache.airavata.model.appcatalog.appdeployment.ApplicationDeploymentDescription> getAllApplicationDeployments(org.apache.airavata.model.security.AuthzToken authzToken, String gatewayId) throws org.apache.airavata.model.error.InvalidRequestException, org.apache.airavata.model.error.AiravataClientException, org.apache.airavata.model.error.AiravataSystemException, org.apache.airavata.model.error.AuthorizationException, org.apache.thrift.TException;

    /**
     * Fetch a list of Deployed Compute Hosts.
     * 
     * @param appModuleId
     *   The identifier for the requested application module
     * 
     * @return list<string>
     *   Returns a list of Deployed Resources.
     * 
     * 
     * @param authzToken
     * @param appModuleId
     */
    public List<String> getAppModuleDeployedResources(org.apache.airavata.model.security.AuthzToken authzToken, String appModuleId) throws org.apache.airavata.model.error.InvalidRequestException, org.apache.airavata.model.error.AiravataClientException, org.apache.airavata.model.error.AiravataSystemException, org.apache.airavata.model.error.AuthorizationException, org.apache.thrift.TException;

    /**
     * Register a Application Interface.
     * 
     * @param applicationModule
     *    Application Module Object created from the datamodel.
     * 
     * @return appInterfaceId
     *   Returns a server-side generated airavata application interface globally unique identifier.
     * 
     * 
     * @param authzToken
     * @param gatewayId
     * @param applicationInterface
     */
    public String registerApplicationInterface(org.apache.airavata.model.security.AuthzToken authzToken, String gatewayId, org.apache.airavata.model.appcatalog.appinterface.ApplicationInterfaceDescription applicationInterface) throws org.apache.airavata.model.error.InvalidRequestException, org.apache.airavata.model.error.AiravataClientException, org.apache.airavata.model.error.AiravataSystemException, org.apache.airavata.model.error.AuthorizationException, org.apache.thrift.TException;

    /**
     * Fetch a Application Interface.
     * 
     * @param appInterfaceId
     *   The identifier for the requested application module
     * 
     * @return applicationInterface
     *   Returns a application Interface Object.
     * 
     * 
     * 
     * @param authzToken
     * @param appInterfaceId
     */
    public org.apache.airavata.model.appcatalog.appinterface.ApplicationInterfaceDescription getApplicationInterface(org.apache.airavata.model.security.AuthzToken authzToken, String appInterfaceId) throws org.apache.airavata.model.error.InvalidRequestException, org.apache.airavata.model.error.AiravataClientException, org.apache.airavata.model.error.AiravataSystemException, org.apache.airavata.model.error.AuthorizationException, org.apache.thrift.TException;

    /**
     * Update a Application Interface.
     * 
     * @param appInterfaceId
     *   The identifier for the requested application deployment to be updated.
     * 
     * @param appInterface
     *    Application Interface Object created from the datamodel.
     * 
     * @return status
     *   Returns a success/failure of the update.
     * 
     * 
     * 
     * @param authzToken
     * @param appInterfaceId
     * @param applicationInterface
     */
    public boolean updateApplicationInterface(org.apache.airavata.model.security.AuthzToken authzToken, String appInterfaceId, org.apache.airavata.model.appcatalog.appinterface.ApplicationInterfaceDescription applicationInterface) throws org.apache.airavata.model.error.InvalidRequestException, org.apache.airavata.model.error.AiravataClientException, org.apache.airavata.model.error.AiravataSystemException, org.apache.airavata.model.error.AuthorizationException, org.apache.thrift.TException;

    /**
     * Delete a Application Interface.
     * 
     * @param appInterfaceId
     *   The identifier for the requested application interface to be deleted.
     * 
     * @return status
     *   Returns a success/failure of the deletion.
     * 
     * 
     * 
     * @param authzToken
     * @param appInterfaceId
     */
    public boolean deleteApplicationInterface(org.apache.airavata.model.security.AuthzToken authzToken, String appInterfaceId) throws org.apache.airavata.model.error.InvalidRequestException, org.apache.airavata.model.error.AiravataClientException, org.apache.airavata.model.error.AiravataSystemException, org.apache.airavata.model.error.AuthorizationException, org.apache.thrift.TException;

    /**
     * Fetch name and id of  Application Interface documents.
     * 
     * 
     * @return map<applicationId, applicationInterfaceNames>
     *   Returns a list of application interfaces with corresponsing id's
     * 
     * 
     * @param authzToken
     * @param gatewayId
     */
    public Map<String,String> getAllApplicationInterfaceNames(org.apache.airavata.model.security.AuthzToken authzToken, String gatewayId) throws org.apache.airavata.model.error.InvalidRequestException, org.apache.airavata.model.error.AiravataClientException, org.apache.airavata.model.error.AiravataSystemException, org.apache.airavata.model.error.AuthorizationException, org.apache.thrift.TException;

    /**
     * Fetch all Application Interface documents.
     * 
     * 
     * @return map<applicationId, applicationInterfaceNames>
     *   Returns a list of application interfaces documents
     * 
     * 
     * @param authzToken
     * @param gatewayId
     */
    public List<org.apache.airavata.model.appcatalog.appinterface.ApplicationInterfaceDescription> getAllApplicationInterfaces(org.apache.airavata.model.security.AuthzToken authzToken, String gatewayId) throws org.apache.airavata.model.error.InvalidRequestException, org.apache.airavata.model.error.AiravataClientException, org.apache.airavata.model.error.AiravataSystemException, org.apache.airavata.model.error.AuthorizationException, org.apache.thrift.TException;

    /**
     * Fetch the list of Application Inputs.
     * 
     * @param appInterfaceId
     *   The identifier for the requested application interface
     * 
     * @return list<application_interface_model.InputDataObjectType>
     *   Returns a list of application inputs.
     * 
     * 
     * @param authzToken
     * @param appInterfaceId
     */
    public List<org.apache.airavata.model.application.io.InputDataObjectType> getApplicationInputs(org.apache.airavata.model.security.AuthzToken authzToken, String appInterfaceId) throws org.apache.airavata.model.error.InvalidRequestException, org.apache.airavata.model.error.AiravataClientException, org.apache.airavata.model.error.AiravataSystemException, org.apache.airavata.model.error.AuthorizationException, org.apache.thrift.TException;

    /**
     * Fetch the list of Application Outputs.
     * 
     * @param appInterfaceId
     *   The identifier for the requested application interface
     * 
     * @return list<application_interface_model.OutputDataObjectType>
     *   Returns a list of application outputs.
     * 
     * 
     * @param authzToken
     * @param appInterfaceId
     */
    public List<org.apache.airavata.model.application.io.OutputDataObjectType> getApplicationOutputs(org.apache.airavata.model.security.AuthzToken authzToken, String appInterfaceId) throws org.apache.airavata.model.error.InvalidRequestException, org.apache.airavata.model.error.AiravataClientException, org.apache.airavata.model.error.AiravataSystemException, org.apache.airavata.model.error.AuthorizationException, org.apache.thrift.TException;

    /**
     * Fetch a list of all deployed Compute Hosts for a given application interfaces.
     * 
     * @param appInterfaceId
     *   The identifier for the requested application interface
     * 
     * @return map<computeResourceId, computeResourceName>
     *   A map of registered compute resource id's and their corresponding hostnames.
     *    Deployments of each modules listed within the interfaces will be listed.
     * 
     * 
     * @param authzToken
     * @param appInterfaceId
     */
    public Map<String,String> getAvailableAppInterfaceComputeResources(org.apache.airavata.model.security.AuthzToken authzToken, String appInterfaceId) throws org.apache.airavata.model.error.InvalidRequestException, org.apache.airavata.model.error.AiravataClientException, org.apache.airavata.model.error.AiravataSystemException, org.apache.airavata.model.error.AuthorizationException, org.apache.thrift.TException;

    /**
     * Register a Compute Resource.
     * 
     * @param computeResourceDescription
     *    Compute Resource Object created from the datamodel.
     * 
     * @return computeResourceId
     *   Returns a server-side generated airavata compute resource globally unique identifier.
     * 
     * 
     * @param authzToken
     * @param computeResourceDescription
     */
    public String registerComputeResource(org.apache.airavata.model.security.AuthzToken authzToken, org.apache.airavata.model.appcatalog.computeresource.ComputeResourceDescription computeResourceDescription) throws org.apache.airavata.model.error.InvalidRequestException, org.apache.airavata.model.error.AiravataClientException, org.apache.airavata.model.error.AiravataSystemException, org.apache.airavata.model.error.AuthorizationException, org.apache.thrift.TException;

    /**
     * Fetch the given Compute Resource.
     * 
     * @param computeResourceId
     *   The identifier for the requested compute resource
     * 
     * @return computeResourceDescription
     *    Compute Resource Object created from the datamodel..
     * 
     * 
     * @param authzToken
     * @param computeResourceId
     */
    public org.apache.airavata.model.appcatalog.computeresource.ComputeResourceDescription getComputeResource(org.apache.airavata.model.security.AuthzToken authzToken, String computeResourceId) throws org.apache.airavata.model.error.InvalidRequestException, org.apache.airavata.model.error.AiravataClientException, org.apache.airavata.model.error.AiravataSystemException, org.apache.airavata.model.error.AuthorizationException, org.apache.thrift.TException;

    /**
     * Fetch all registered Compute Resources.
     * 
     * @return A map of registered compute resource id's and thier corresponding hostnames.
     *    Compute Resource Object created from the datamodel..
     * 
     * 
     * @param authzToken
     */
    public Map<String,String> getAllComputeResourceNames(org.apache.airavata.model.security.AuthzToken authzToken) throws org.apache.airavata.model.error.InvalidRequestException, org.apache.airavata.model.error.AiravataClientException, org.apache.airavata.model.error.AiravataSystemException, org.apache.airavata.model.error.AuthorizationException, org.apache.thrift.TException;

    /**
     * Update a Compute Resource.
     * 
     * @param computeResourceId
     *   The identifier for the requested compute resource to be updated.
     * 
     * @param computeResourceDescription
     *    Compute Resource Object created from the datamodel.
     * 
     * @return status
     *   Returns a success/failure of the update.
     * 
     * 
     * @param authzToken
     * @param computeResourceId
     * @param computeResourceDescription
     */
    public boolean updateComputeResource(org.apache.airavata.model.security.AuthzToken authzToken, String computeResourceId, org.apache.airavata.model.appcatalog.computeresource.ComputeResourceDescription computeResourceDescription) throws org.apache.airavata.model.error.InvalidRequestException, org.apache.airavata.model.error.AiravataClientException, org.apache.airavata.model.error.AiravataSystemException, org.apache.airavata.model.error.AuthorizationException, org.apache.thrift.TException;

    /**
     * Delete a Compute Resource.
     * 
     * @param computeResourceId
     *   The identifier for the requested compute resource to be deleted.
     * 
     * @return status
     *   Returns a success/failure of the deletion.
     * 
     * 
     * @param authzToken
     * @param computeResourceId
     */
    public boolean deleteComputeResource(org.apache.airavata.model.security.AuthzToken authzToken, String computeResourceId) throws org.apache.airavata.model.error.InvalidRequestException, org.apache.airavata.model.error.AiravataClientException, org.apache.airavata.model.error.AiravataSystemException, org.apache.airavata.model.error.AuthorizationException, org.apache.thrift.TException;

    /**
     * Add a Local Job Submission details to a compute resource
     *  App catalog will return a jobSubmissionInterfaceId which will be added to the jobSubmissionInterfaces.
     * 
     * @param computeResourceId
     *   The identifier of the compute resource to which JobSubmission protocol to be added
     * 
     * @param priorityOrder
     *   Specify the priority of this job manager. If this is the only jobmanager, the priority can be zero.
     * 
     * @param localSubmission
     *   The LOCALSubmission object to be added to the resource.
     * 
     * @return status
     *   Returns the unique job submission id.
     * 
     * 
     * @param authzToken
     * @param computeResourceId
     * @param priorityOrder
     * @param localSubmission
     */
    public String addLocalSubmissionDetails(org.apache.airavata.model.security.AuthzToken authzToken, String computeResourceId, int priorityOrder, org.apache.airavata.model.appcatalog.computeresource.LOCALSubmission localSubmission) throws org.apache.airavata.model.error.InvalidRequestException, org.apache.airavata.model.error.AiravataClientException, org.apache.airavata.model.error.AiravataSystemException, org.apache.airavata.model.error.AuthorizationException, org.apache.thrift.TException;

    /**
     * Update the given Local Job Submission details
     * 
     * @param jobSubmissionInterfaceId
     *   The identifier of the JobSubmission Interface to be updated.
     * 
     * @param localSubmission
     *   The LOCALSubmission object to be updated.
     * 
     * @return status
     *   Returns a success/failure of the deletion.
     * 
     * 
     * @param authzToken
     * @param jobSubmissionInterfaceId
     * @param localSubmission
     */
    public boolean updateLocalSubmissionDetails(org.apache.airavata.model.security.AuthzToken authzToken, String jobSubmissionInterfaceId, org.apache.airavata.model.appcatalog.computeresource.LOCALSubmission localSubmission) throws org.apache.airavata.model.error.InvalidRequestException, org.apache.airavata.model.error.AiravataClientException, org.apache.airavata.model.error.AiravataSystemException, org.apache.airavata.model.error.AuthorizationException, org.apache.thrift.TException;

    /**
     * This method returns localJobSubmission object
     * @param jobSubmissionInterfaceId
     *   The identifier of the JobSubmission Interface to be retrieved.
     *  @return LOCALSubmission instance
     * 
     * 
     * @param authzToken
     * @param jobSubmissionId
     */
    public org.apache.airavata.model.appcatalog.computeresource.LOCALSubmission getLocalJobSubmission(org.apache.airavata.model.security.AuthzToken authzToken, String jobSubmissionId) throws org.apache.airavata.model.error.InvalidRequestException, org.apache.airavata.model.error.AiravataClientException, org.apache.airavata.model.error.AiravataSystemException, org.apache.airavata.model.error.AuthorizationException, org.apache.thrift.TException;

    /**
     * Add a SSH Job Submission details to a compute resource
     *  App catalog will return a jobSubmissionInterfaceId which will be added to the jobSubmissionInterfaces.
     * 
     * @param computeResourceId
     *   The identifier of the compute resource to which JobSubmission protocol to be added
     * 
     * @param priorityOrder
     *   Specify the priority of this job manager. If this is the only jobmanager, the priority can be zero.
     * 
     * @param sshJobSubmission
     *   The SSHJobSubmission object to be added to the resource.
     * 
     * @return status
     *   Returns the unique job submission id.
     * 
     * 
     * @param authzToken
     * @param computeResourceId
     * @param priorityOrder
     * @param sshJobSubmission
     */
    public String addSSHJobSubmissionDetails(org.apache.airavata.model.security.AuthzToken authzToken, String computeResourceId, int priorityOrder, org.apache.airavata.model.appcatalog.computeresource.SSHJobSubmission sshJobSubmission) throws org.apache.airavata.model.error.InvalidRequestException, org.apache.airavata.model.error.AiravataClientException, org.apache.airavata.model.error.AiravataSystemException, org.apache.airavata.model.error.AuthorizationException, org.apache.thrift.TException;

    /**
     * Add a SSH_FORK Job Submission details to a compute resource
     *  App catalog will return a jobSubmissionInterfaceId which will be added to the jobSubmissionInterfaces.
     * 
     * @param computeResourceId
     *   The identifier of the compute resource to which JobSubmission protocol to be added
     * 
     * @param priorityOrder
     *   Specify the priority of this job manager. If this is the only jobmanager, the priority can be zero.
     * 
     * @param sshJobSubmission
     *   The SSHJobSubmission object to be added to the resource.
     * 
     * @return status
     *   Returns the unique job submission id.
     * 
     * 
     * @param authzToken
     * @param computeResourceId
     * @param priorityOrder
     * @param sshJobSubmission
     */
    public String addSSHForkJobSubmissionDetails(org.apache.airavata.model.security.AuthzToken authzToken, String computeResourceId, int priorityOrder, org.apache.airavata.model.appcatalog.computeresource.SSHJobSubmission sshJobSubmission) throws org.apache.airavata.model.error.InvalidRequestException, org.apache.airavata.model.error.AiravataClientException, org.apache.airavata.model.error.AiravataSystemException, org.apache.airavata.model.error.AuthorizationException, org.apache.thrift.TException;

    /**
     * This method returns SSHJobSubmission object
     * @param jobSubmissionInterfaceId
     *   The identifier of the JobSubmission Interface to be retrieved.
     *  @return SSHJobSubmission instance
     * 
     * 
     * @param authzToken
     * @param jobSubmissionId
     */
    public org.apache.airavata.model.appcatalog.computeresource.SSHJobSubmission getSSHJobSubmission(org.apache.airavata.model.security.AuthzToken authzToken, String jobSubmissionId) throws org.apache.airavata.model.error.InvalidRequestException, org.apache.airavata.model.error.AiravataClientException, org.apache.airavata.model.error.AiravataSystemException, org.apache.airavata.model.error.AuthorizationException, org.apache.thrift.TException;

    /**
     * Add a UNICORE Job Submission details to a compute resource
     *  App catalog will return a jobSubmissionInterfaceId which will be added to the jobSubmissionInterfaces.
     * 
     * @param computeResourceId
     *   The identifier of the compute resource to which JobSubmission protocol to be added
     * 
     * @param priorityOrder
     *   Specify the priority of this job manager. If this is the only jobmanager, the priority can be zero.
     * 
     * @param unicoreJobSubmission
     *   The UnicoreJobSubmission object to be added to the resource.
     * 
     * @return status
     *  Returns the unique job submission id.
     * 
     * 
     * @param authzToken
     * @param computeResourceId
     * @param priorityOrder
     * @param unicoreJobSubmission
     */
    public String addUNICOREJobSubmissionDetails(org.apache.airavata.model.security.AuthzToken authzToken, String computeResourceId, int priorityOrder, org.apache.airavata.model.appcatalog.computeresource.UnicoreJobSubmission unicoreJobSubmission) throws org.apache.airavata.model.error.InvalidRequestException, org.apache.airavata.model.error.AiravataClientException, org.apache.airavata.model.error.AiravataSystemException, org.apache.airavata.model.error.AuthorizationException, org.apache.thrift.TException;

    /**
     *   * This method returns UnicoreJobSubmission object
     *   * @param jobSubmissionInterfaceId
     *   *   The identifier of the JobSubmission Interface to be retrieved.
     *   *  @return UnicoreJobSubmission instance
     * *
     * 
     * @param authzToken
     * @param jobSubmissionId
     */
    public org.apache.airavata.model.appcatalog.computeresource.UnicoreJobSubmission getUnicoreJobSubmission(org.apache.airavata.model.security.AuthzToken authzToken, String jobSubmissionId) throws org.apache.airavata.model.error.InvalidRequestException, org.apache.airavata.model.error.AiravataClientException, org.apache.airavata.model.error.AiravataSystemException, org.apache.airavata.model.error.AuthorizationException, org.apache.thrift.TException;

    /**
     *    * Add a Cloud Job Submission details to a compute resource
     *    *  App catalog will return a jobSubmissionInterfaceId which will be added to the jobSubmissionInterfaces.
     *    *
     *    * @param computeResourceId
     *    *   The identifier of the compute resource to which JobSubmission protocol to be added
     *    *
     *    * @param priorityOrder
     *    *   Specify the priority of this job manager. If this is the only jobmanager, the priority can be zero.
     *    *
     *    * @param sshJobSubmission
     *    *   The SSHJobSubmission object to be added to the resource.
     *    *
     *    * @return status
     *    *   Returns the unique job submission id.
     * *
     * 
     * @param authzToken
     * @param computeResourceId
     * @param priorityOrder
     * @param cloudSubmission
     */
    public String addCloudJobSubmissionDetails(org.apache.airavata.model.security.AuthzToken authzToken, String computeResourceId, int priorityOrder, org.apache.airavata.model.appcatalog.computeresource.CloudJobSubmission cloudSubmission) throws org.apache.airavata.model.error.InvalidRequestException, org.apache.airavata.model.error.AiravataClientException, org.apache.airavata.model.error.AiravataSystemException, org.apache.airavata.model.error.AuthorizationException, org.apache.thrift.TException;

    /**
     *    * This method returns cloudJobSubmission object
     *    * @param jobSubmissionInterfaceI
     *        *   The identifier of the JobSubmission Interface to be retrieved.
     *    *  @return CloudJobSubmission instance
     * *
     * 
     * @param authzToken
     * @param jobSubmissionId
     */
    public org.apache.airavata.model.appcatalog.computeresource.CloudJobSubmission getCloudJobSubmission(org.apache.airavata.model.security.AuthzToken authzToken, String jobSubmissionId) throws org.apache.airavata.model.error.InvalidRequestException, org.apache.airavata.model.error.AiravataClientException, org.apache.airavata.model.error.AiravataSystemException, org.apache.airavata.model.error.AuthorizationException, org.apache.thrift.TException;

    /**
     * Update the given SSH Job Submission details
     * 
     * @param jobSubmissionInterfaceId
     *   The identifier of the JobSubmission Interface to be updated.
     * 
     * @param sshJobSubmission
     *   The SSHJobSubmission object to be updated.
     * 
     * @return status
     *   Returns a success/failure of the deletion.
     * 
     * 
     * @param authzToken
     * @param jobSubmissionInterfaceId
     * @param sshJobSubmission
     */
    public boolean updateSSHJobSubmissionDetails(org.apache.airavata.model.security.AuthzToken authzToken, String jobSubmissionInterfaceId, org.apache.airavata.model.appcatalog.computeresource.SSHJobSubmission sshJobSubmission) throws org.apache.airavata.model.error.InvalidRequestException, org.apache.airavata.model.error.AiravataClientException, org.apache.airavata.model.error.AiravataSystemException, org.apache.airavata.model.error.AuthorizationException, org.apache.thrift.TException;

    /**
     * Update the cloud Job Submission details
     * 
     * @param jobSubmissionInterfaceId
     *   The identifier of the JobSubmission Interface to be updated.
     * 
     * @param cloudJobSubmission
     *   The CloudJobSubmission object to be updated.
     * 
     * @return status
     *   Returns a success/failure of the deletion.
     * 
     * 
     * @param authzToken
     * @param jobSubmissionInterfaceId
     * @param sshJobSubmission
     */
    public boolean updateCloudJobSubmissionDetails(org.apache.airavata.model.security.AuthzToken authzToken, String jobSubmissionInterfaceId, org.apache.airavata.model.appcatalog.computeresource.CloudJobSubmission sshJobSubmission) throws org.apache.airavata.model.error.InvalidRequestException, org.apache.airavata.model.error.AiravataClientException, org.apache.airavata.model.error.AiravataSystemException, org.apache.airavata.model.error.AuthorizationException, org.apache.thrift.TException;

    public boolean updateUnicoreJobSubmissionDetails(org.apache.airavata.model.security.AuthzToken authzToken, String jobSubmissionInterfaceId, org.apache.airavata.model.appcatalog.computeresource.UnicoreJobSubmission unicoreJobSubmission) throws org.apache.airavata.model.error.InvalidRequestException, org.apache.airavata.model.error.AiravataClientException, org.apache.airavata.model.error.AiravataSystemException, org.apache.airavata.model.error.AuthorizationException, org.apache.thrift.TException;

    /**
     * Add a Local data movement details to a compute resource
     *  App catalog will return a dataMovementInterfaceId which will be added to the dataMovementInterfaces.
     * 
     * @param computeResourceId
     *   The identifier of the compute resource to which JobSubmission protocol to be added
     * 
     * @param priorityOrder
     *   Specify the priority of this job manager. If this is the only jobmanager, the priority can be zero.
     * 
     * @param localDataMovement
     *   The LOCALDataMovement object to be added to the resource.
     * 
     * @return status
     *   Returns the unique job submission id.
     * 
     * 
     * @param authzToken
     * @param computeResourceId
     * @param priorityOrder
     * @param localDataMovement
     */
    public String addLocalDataMovementDetails(org.apache.airavata.model.security.AuthzToken authzToken, String computeResourceId, int priorityOrder, org.apache.airavata.model.appcatalog.computeresource.LOCALDataMovement localDataMovement) throws org.apache.airavata.model.error.InvalidRequestException, org.apache.airavata.model.error.AiravataClientException, org.apache.airavata.model.error.AiravataSystemException, org.apache.airavata.model.error.AuthorizationException, org.apache.thrift.TException;

    /**
     * Update the given Local data movement details
     * 
     * @param dataMovementInterfaceId
     *   The identifier of the data movement Interface to be updated.
     * 
     * @param localDataMovement
     *   The LOCALDataMovement object to be updated.
     * 
     * @return status
     *   Returns a success/failure of the update.
     * 
     * 
     * @param authzToken
     * @param dataMovementInterfaceId
     * @param localDataMovement
     */
    public boolean updateLocalDataMovementDetails(org.apache.airavata.model.security.AuthzToken authzToken, String dataMovementInterfaceId, org.apache.airavata.model.appcatalog.computeresource.LOCALDataMovement localDataMovement) throws org.apache.airavata.model.error.InvalidRequestException, org.apache.airavata.model.error.AiravataClientException, org.apache.airavata.model.error.AiravataSystemException, org.apache.airavata.model.error.AuthorizationException, org.apache.thrift.TException;

    /**
     *         * This method returns local datamovement object
     *         * @param dataMovementId
     *         *   The identifier of the datamovement Interface to be retrieved.
     *         *  @return LOCALDataMovement instance
     * *
     * 
     * @param authzToken
     * @param dataMovementId
     */
    public org.apache.airavata.model.appcatalog.computeresource.LOCALDataMovement getLocalDataMovement(org.apache.airavata.model.security.AuthzToken authzToken, String dataMovementId) throws org.apache.airavata.model.error.InvalidRequestException, org.apache.airavata.model.error.AiravataClientException, org.apache.airavata.model.error.AiravataSystemException, org.apache.airavata.model.error.AuthorizationException, org.apache.thrift.TException;

    /**
     * Add a SCP data movement details to a compute resource
     *  App catalog will return a dataMovementInterfaceId which will be added to the dataMovementInterfaces.
     * 
     * @param computeResourceId
     *   The identifier of the compute resource to which JobSubmission protocol to be added
     * 
     * @param priorityOrder
     *   Specify the priority of this job manager. If this is the only jobmanager, the priority can be zero.
     * 
     * @param scpDataMovement
     *   The SCPDataMovement object to be added to the resource.
     * 
     * @return status
     *   Returns the unique job submission id.
     * 
     * 
     * @param authzToken
     * @param computeResourceId
     * @param priorityOrder
     * @param scpDataMovement
     */
    public String addSCPDataMovementDetails(org.apache.airavata.model.security.AuthzToken authzToken, String computeResourceId, int priorityOrder, org.apache.airavata.model.appcatalog.computeresource.SCPDataMovement scpDataMovement) throws org.apache.airavata.model.error.InvalidRequestException, org.apache.airavata.model.error.AiravataClientException, org.apache.airavata.model.error.AiravataSystemException, org.apache.airavata.model.error.AuthorizationException, org.apache.thrift.TException;

    /**
     * Update the given scp data movement details
     *  App catalog will return a dataMovementInterfaceId which will be added to the dataMovementInterfaces.
     * 
     * @param dataMovementInterfaceId
     *   The identifier of the data movement Interface to be updated.
     * 
     * @param scpDataMovement
     *   The SCPDataMovement object to be updated.
     * 
     * @return status
     *   Returns a success/failure of the update.
     * 
     * 
     * @param authzToken
     * @param dataMovementInterfaceId
     * @param scpDataMovement
     */
    public boolean updateSCPDataMovementDetails(org.apache.airavata.model.security.AuthzToken authzToken, String dataMovementInterfaceId, org.apache.airavata.model.appcatalog.computeresource.SCPDataMovement scpDataMovement) throws org.apache.airavata.model.error.InvalidRequestException, org.apache.airavata.model.error.AiravataClientException, org.apache.airavata.model.error.AiravataSystemException, org.apache.airavata.model.error.AuthorizationException, org.apache.thrift.TException;

    /**
     *   * This method returns SCP datamovement object
     *   * @param dataMovementId
     *      *   The identifier of the datamovement Interface to be retrieved.
     *      *  @return SCPDataMovement instance
     * *
     * 
     * @param authzToken
     * @param dataMovementId
     */
    public org.apache.airavata.model.appcatalog.computeresource.SCPDataMovement getSCPDataMovement(org.apache.airavata.model.security.AuthzToken authzToken, String dataMovementId) throws org.apache.airavata.model.error.InvalidRequestException, org.apache.airavata.model.error.AiravataClientException, org.apache.airavata.model.error.AiravataSystemException, org.apache.airavata.model.error.AuthorizationException, org.apache.thrift.TException;

    public String addUnicoreDataMovementDetails(org.apache.airavata.model.security.AuthzToken authzToken, String computeResourceId, int priorityOrder, org.apache.airavata.model.appcatalog.computeresource.UnicoreDataMovement unicoreDataMovement) throws org.apache.airavata.model.error.InvalidRequestException, org.apache.airavata.model.error.AiravataClientException, org.apache.airavata.model.error.AiravataSystemException, org.apache.airavata.model.error.AuthorizationException, org.apache.thrift.TException;

    public boolean updateUnicoreDataMovementDetails(org.apache.airavata.model.security.AuthzToken authzToken, String dataMovementInterfaceId, org.apache.airavata.model.appcatalog.computeresource.UnicoreDataMovement unicoreDataMovement) throws org.apache.airavata.model.error.InvalidRequestException, org.apache.airavata.model.error.AiravataClientException, org.apache.airavata.model.error.AiravataSystemException, org.apache.airavata.model.error.AuthorizationException, org.apache.thrift.TException;

    public org.apache.airavata.model.appcatalog.computeresource.UnicoreDataMovement getUnicoreDataMovement(org.apache.airavata.model.security.AuthzToken authzToken, String dataMovementId) throws org.apache.airavata.model.error.InvalidRequestException, org.apache.airavata.model.error.AiravataClientException, org.apache.airavata.model.error.AiravataSystemException, org.apache.airavata.model.error.AuthorizationException, org.apache.thrift.TException;

    /**
     * Add a GridFTP data movement details to a compute resource
     *  App catalog will return a dataMovementInterfaceId which will be added to the dataMovementInterfaces.
     * 
     * @param computeResourceId
     *   The identifier of the compute resource to which JobSubmission protocol to be added
     * 
     * @param priorityOrder
     *   Specify the priority of this job manager. If this is the only jobmanager, the priority can be zero.
     * 
     * @param gridFTPDataMovement
     *   The GridFTPDataMovement object to be added to the resource.
     * 
     * @return status
     *   Returns the unique job submission id.
     * 
     * 
     * @param authzToken
     * @param computeResourceId
     * @param priorityOrder
     * @param gridFTPDataMovement
     */
    public String addGridFTPDataMovementDetails(org.apache.airavata.model.security.AuthzToken authzToken, String computeResourceId, int priorityOrder, org.apache.airavata.model.appcatalog.computeresource.GridFTPDataMovement gridFTPDataMovement) throws org.apache.airavata.model.error.InvalidRequestException, org.apache.airavata.model.error.AiravataClientException, org.apache.airavata.model.error.AiravataSystemException, org.apache.airavata.model.error.AuthorizationException, org.apache.thrift.TException;

    /**
     * Update the given GridFTP data movement details to a compute resource
     *  App catalog will return a dataMovementInterfaceId which will be added to the dataMovementInterfaces.
     * 
     * @param dataMovementInterfaceId
     *   The identifier of the data movement Interface to be updated.
     * 
     * @param gridFTPDataMovement
     *   The GridFTPDataMovement object to be updated.
     * 
     * @return status
     *   Returns a success/failure of the updation.
     * 
     * 
     * @param authzToken
     * @param dataMovementInterfaceId
     * @param gridFTPDataMovement
     */
    public boolean updateGridFTPDataMovementDetails(org.apache.airavata.model.security.AuthzToken authzToken, String dataMovementInterfaceId, org.apache.airavata.model.appcatalog.computeresource.GridFTPDataMovement gridFTPDataMovement) throws org.apache.airavata.model.error.InvalidRequestException, org.apache.airavata.model.error.AiravataClientException, org.apache.airavata.model.error.AiravataSystemException, org.apache.airavata.model.error.AuthorizationException, org.apache.thrift.TException;

    /**
     *   * This method returns GridFTP datamovement object
     *   * @param dataMovementId
     *      *   The identifier of the datamovement Interface to be retrieved.
     *   *  @return GridFTPDataMovement instance
     * *
     * 
     * @param authzToken
     * @param dataMovementId
     */
    public org.apache.airavata.model.appcatalog.computeresource.GridFTPDataMovement getGridFTPDataMovement(org.apache.airavata.model.security.AuthzToken authzToken, String dataMovementId) throws org.apache.airavata.model.error.InvalidRequestException, org.apache.airavata.model.error.AiravataClientException, org.apache.airavata.model.error.AiravataSystemException, org.apache.airavata.model.error.AuthorizationException, org.apache.thrift.TException;

    /**
     * Change the priority of a given job submisison interface
     * 
     * @param jobSubmissionInterfaceId
     *   The identifier of the JobSubmission Interface to be changed
     * 
     * @param priorityOrder
     *   The new priority of the job manager interface.
     * 
     * @return status
     *   Returns a success/failure of the change.
     * 
     * 
     * @param authzToken
     * @param jobSubmissionInterfaceId
     * @param newPriorityOrder
     */
    public boolean changeJobSubmissionPriority(org.apache.airavata.model.security.AuthzToken authzToken, String jobSubmissionInterfaceId, int newPriorityOrder) throws org.apache.airavata.model.error.InvalidRequestException, org.apache.airavata.model.error.AiravataClientException, org.apache.airavata.model.error.AiravataSystemException, org.apache.airavata.model.error.AuthorizationException, org.apache.thrift.TException;

    /**
     * Change the priority of a given data movement interface
     * 
     * @param dataMovementInterfaceId
     *   The identifier of the DataMovement Interface to be changed
     * 
     * @param priorityOrder
     *   The new priority of the data movement interface.
     * 
     * @return status
     *   Returns a success/failure of the change.
     * 
     * 
     * @param authzToken
     * @param dataMovementInterfaceId
     * @param newPriorityOrder
     */
    public boolean changeDataMovementPriority(org.apache.airavata.model.security.AuthzToken authzToken, String dataMovementInterfaceId, int newPriorityOrder) throws org.apache.airavata.model.error.InvalidRequestException, org.apache.airavata.model.error.AiravataClientException, org.apache.airavata.model.error.AiravataSystemException, org.apache.airavata.model.error.AuthorizationException, org.apache.thrift.TException;

    /**
     * Change the priorities of a given set of job submission interfaces
     * 
     * @param jobSubmissionPriorityMap
     *   A Map of identifiers of the JobSubmission Interfaces and thier associated priorities to be set.
     * 
     * @return status
     *   Returns a success/failure of the changes.
     * 
     * 
     * @param authzToken
     * @param jobSubmissionPriorityMap
     */
    public boolean changeJobSubmissionPriorities(org.apache.airavata.model.security.AuthzToken authzToken, Map<String,Integer> jobSubmissionPriorityMap) throws org.apache.airavata.model.error.InvalidRequestException, org.apache.airavata.model.error.AiravataClientException, org.apache.airavata.model.error.AiravataSystemException, org.apache.airavata.model.error.AuthorizationException, org.apache.thrift.TException;

    /**
     * Change the priorities of a given set of data movement interfaces
     * 
     * @param dataMovementPriorityMap
     *   A Map of identifiers of the DataMovement Interfaces and thier associated priorities to be set.
     * 
     * @return status
     *   Returns a success/failure of the changes.
     * 
     * 
     * @param authzToken
     * @param dataMovementPriorityMap
     */
    public boolean changeDataMovementPriorities(org.apache.airavata.model.security.AuthzToken authzToken, Map<String,Integer> dataMovementPriorityMap) throws org.apache.airavata.model.error.InvalidRequestException, org.apache.airavata.model.error.AiravataClientException, org.apache.airavata.model.error.AiravataSystemException, org.apache.airavata.model.error.AuthorizationException, org.apache.thrift.TException;

    /**
     * Delete a given job submisison interface
     * 
     * @param jobSubmissionInterfaceId
     *   The identifier of the JobSubmission Interface to be changed
     * 
     * @return status
     *   Returns a success/failure of the deletion.
     * 
     * 
     * @param authzToken
     * @param computeResourceId
     * @param jobSubmissionInterfaceId
     */
    public boolean deleteJobSubmissionInterface(org.apache.airavata.model.security.AuthzToken authzToken, String computeResourceId, String jobSubmissionInterfaceId) throws org.apache.airavata.model.error.InvalidRequestException, org.apache.airavata.model.error.AiravataClientException, org.apache.airavata.model.error.AiravataSystemException, org.apache.airavata.model.error.AuthorizationException, org.apache.thrift.TException;

    /**
     * Delete a given data movement interface
     * 
     * @param dataMovementInterfaceId
     *   The identifier of the DataMovement Interface to be changed
     * 
     * @return status
     *   Returns a success/failure of the deletion.
     * 
     * 
     * @param authzToken
     * @param computeResourceId
     * @param dataMovementInterfaceId
     */
    public boolean deleteDataMovementInterface(org.apache.airavata.model.security.AuthzToken authzToken, String computeResourceId, String dataMovementInterfaceId) throws org.apache.airavata.model.error.InvalidRequestException, org.apache.airavata.model.error.AiravataClientException, org.apache.airavata.model.error.AiravataSystemException, org.apache.airavata.model.error.AuthorizationException, org.apache.thrift.TException;

    public String registerResourceJobManager(org.apache.airavata.model.security.AuthzToken authzToken, org.apache.airavata.model.appcatalog.computeresource.ResourceJobManager resourceJobManager) throws org.apache.airavata.model.error.InvalidRequestException, org.apache.airavata.model.error.AiravataClientException, org.apache.airavata.model.error.AiravataSystemException, org.apache.airavata.model.error.AuthorizationException, org.apache.thrift.TException;

    public boolean updateResourceJobManager(org.apache.airavata.model.security.AuthzToken authzToken, String resourceJobManagerId, org.apache.airavata.model.appcatalog.computeresource.ResourceJobManager updatedResourceJobManager) throws org.apache.airavata.model.error.InvalidRequestException, org.apache.airavata.model.error.AiravataClientException, org.apache.airavata.model.error.AiravataSystemException, org.apache.airavata.model.error.AuthorizationException, org.apache.thrift.TException;

    public org.apache.airavata.model.appcatalog.computeresource.ResourceJobManager getResourceJobManager(org.apache.airavata.model.security.AuthzToken authzToken, String resourceJobManagerId) throws org.apache.airavata.model.error.InvalidRequestException, org.apache.airavata.model.error.AiravataClientException, org.apache.airavata.model.error.AiravataSystemException, org.apache.airavata.model.error.AuthorizationException, org.apache.thrift.TException;

    public boolean deleteResourceJobManager(org.apache.airavata.model.security.AuthzToken authzToken, String resourceJobManagerId) throws org.apache.airavata.model.error.InvalidRequestException, org.apache.airavata.model.error.AiravataClientException, org.apache.airavata.model.error.AiravataSystemException, org.apache.airavata.model.error.AuthorizationException, org.apache.thrift.TException;

    public boolean deleteBatchQueue(org.apache.airavata.model.security.AuthzToken authzToken, String computeResourceId, String queueName) throws org.apache.airavata.model.error.InvalidRequestException, org.apache.airavata.model.error.AiravataClientException, org.apache.airavata.model.error.AiravataSystemException, org.apache.airavata.model.error.AuthorizationException, org.apache.thrift.TException;

    /**
     * Register a Gateway Resource Profile.
     * 
     * @param gatewayResourceProfile
     *    Gateway Resource Profile Object.
     *    The GatewayID should be obtained from Airavata gateway registration and passed to register a corresponding
     *      resource profile.
     * 
     * @return status
     *   Returns a success/failure of the update.
     * 
     * 
     * @param authzToken
     * @param gatewayResourceProfile
     */
    public String registerGatewayResourceProfile(org.apache.airavata.model.security.AuthzToken authzToken, org.apache.airavata.model.appcatalog.gatewayprofile.GatewayResourceProfile gatewayResourceProfile) throws org.apache.airavata.model.error.InvalidRequestException, org.apache.airavata.model.error.AiravataClientException, org.apache.airavata.model.error.AiravataSystemException, org.apache.airavata.model.error.AuthorizationException, org.apache.thrift.TException;

    /**
     * Fetch the given Gateway Resource Profile.
     * 
     * @param gatewayID
     *   The identifier for the requested gateway resource
     * 
     * @return gatewayResourceProfile
     *    Gateway Resource Profile Object.
     * 
     * 
     * @param authzToken
     * @param gatewayID
     */
    public org.apache.airavata.model.appcatalog.gatewayprofile.GatewayResourceProfile getGatewayResourceProfile(org.apache.airavata.model.security.AuthzToken authzToken, String gatewayID) throws org.apache.airavata.model.error.InvalidRequestException, org.apache.airavata.model.error.AiravataClientException, org.apache.airavata.model.error.AiravataSystemException, org.apache.airavata.model.error.AuthorizationException, org.apache.thrift.TException;

    /**
     * Update a Gateway Resource Profile.
     * 
     * @param gatewayID
     *   The identifier for the requested gateway resource to be updated.
     * 
     * @param gatewayResourceProfile
     *    Gateway Resource Profile Object.
     * 
     * @return status
     *   Returns a success/failure of the update.
     * 
     * 
     * @param authzToken
     * @param gatewayID
     * @param gatewayResourceProfile
     */
    public boolean updateGatewayResourceProfile(org.apache.airavata.model.security.AuthzToken authzToken, String gatewayID, org.apache.airavata.model.appcatalog.gatewayprofile.GatewayResourceProfile gatewayResourceProfile) throws org.apache.airavata.model.error.InvalidRequestException, org.apache.airavata.model.error.AiravataClientException, org.apache.airavata.model.error.AiravataSystemException, org.apache.airavata.model.error.AuthorizationException, org.apache.thrift.TException;

    /**
     * Delete the given Gateway Resource Profile.
     * 
     * @param gatewayID
     *   The identifier for the requested gateway resource to be deleted.
     * 
     * @return status
     *   Returns a success/failure of the deletion.
     * 
     * 
     * @param authzToken
     * @param gatewayID
     */
    public boolean deleteGatewayResourceProfile(org.apache.airavata.model.security.AuthzToken authzToken, String gatewayID) throws org.apache.airavata.model.error.InvalidRequestException, org.apache.airavata.model.error.AiravataClientException, org.apache.airavata.model.error.AiravataSystemException, org.apache.airavata.model.error.AuthorizationException, org.apache.thrift.TException;

    /**
     * Add a Compute Resource Preference to a registered gateway profile.
     * 
     * @param gatewayID
     *   The identifier for the gateway profile to be added.
     * 
     * @param computeResourceId
     *   Preferences related to a particular compute resource
     * 
     * @param computeResourcePreference
     *   The ComputeResourcePreference object to be added to the resource profile.
     * 
     * @return status
     *   Returns a success/failure of the addition. If a profile already exists, this operation will fail.
     *    Instead an update should be used.
     * 
     * 
     * @param authzToken
     * @param gatewayID
     * @param computeResourceId
     * @param computeResourcePreference
     */
    public boolean addGatewayComputeResourcePreference(org.apache.airavata.model.security.AuthzToken authzToken, String gatewayID, String computeResourceId, org.apache.airavata.model.appcatalog.gatewayprofile.ComputeResourcePreference computeResourcePreference) throws org.apache.airavata.model.error.InvalidRequestException, org.apache.airavata.model.error.AiravataClientException, org.apache.airavata.model.error.AiravataSystemException, org.apache.airavata.model.error.AuthorizationException, org.apache.thrift.TException;

    public boolean addGatewayDataStoragePreference(org.apache.airavata.model.security.AuthzToken authzToken, String gatewayID, String dataMoveId, org.apache.airavata.model.appcatalog.gatewayprofile.DataStoragePreference dataStoragePreference) throws org.apache.airavata.model.error.InvalidRequestException, org.apache.airavata.model.error.AiravataClientException, org.apache.airavata.model.error.AiravataSystemException, org.apache.airavata.model.error.AuthorizationException, org.apache.thrift.TException;

    /**
     * Fetch a Compute Resource Preference of a registered gateway profile.
     * 
     * @param gatewayID
     *   The identifier for the gateway profile to be requested
     * 
     * @param computeResourceId
     *   Preferences related to a particular compute resource
     * 
     * @return computeResourcePreference
     *   Returns the ComputeResourcePreference object.
     * 
     * 
     * @param authzToken
     * @param gatewayID
     * @param computeResourceId
     */
    public org.apache.airavata.model.appcatalog.gatewayprofile.ComputeResourcePreference getGatewayComputeResourcePreference(org.apache.airavata.model.security.AuthzToken authzToken, String gatewayID, String computeResourceId) throws org.apache.airavata.model.error.InvalidRequestException, org.apache.airavata.model.error.AiravataClientException, org.apache.airavata.model.error.AiravataSystemException, org.apache.airavata.model.error.AuthorizationException, org.apache.thrift.TException;

    public org.apache.airavata.model.appcatalog.gatewayprofile.DataStoragePreference getGatewayDataStoragePreference(org.apache.airavata.model.security.AuthzToken authzToken, String gatewayID, String dataMoveId) throws org.apache.airavata.model.error.InvalidRequestException, org.apache.airavata.model.error.AiravataClientException, org.apache.airavata.model.error.AiravataSystemException, org.apache.airavata.model.error.AuthorizationException, org.apache.thrift.TException;

    /**
     * Fetch all Compute Resource Preferences of a registered gateway profile.
     * 
     * @param gatewayID
     *   The identifier for the gateway profile to be requested
     * 
     * @return computeResourcePreference
     *   Returns the ComputeResourcePreference object.
     * 
     * 
     * @param authzToken
     * @param gatewayID
     */
    public List<org.apache.airavata.model.appcatalog.gatewayprofile.ComputeResourcePreference> getAllGatewayComputeResourcePreferences(org.apache.airavata.model.security.AuthzToken authzToken, String gatewayID) throws org.apache.airavata.model.error.InvalidRequestException, org.apache.airavata.model.error.AiravataClientException, org.apache.airavata.model.error.AiravataSystemException, org.apache.airavata.model.error.AuthorizationException, org.apache.thrift.TException;

    public List<org.apache.airavata.model.appcatalog.gatewayprofile.DataStoragePreference> getAllGatewayDataStoragePreferences(org.apache.airavata.model.security.AuthzToken authzToken, String gatewayID) throws org.apache.airavata.model.error.InvalidRequestException, org.apache.airavata.model.error.AiravataClientException, org.apache.airavata.model.error.AiravataSystemException, org.apache.airavata.model.error.AuthorizationException, org.apache.thrift.TException;

    /**
     * Fetch all gateway profiles registered
     * 
     * 
     * @param authzToken
     */
    public List<org.apache.airavata.model.appcatalog.gatewayprofile.GatewayResourceProfile> getAllGatewayResourceProfiles(org.apache.airavata.model.security.AuthzToken authzToken) throws org.apache.airavata.model.error.InvalidRequestException, org.apache.airavata.model.error.AiravataClientException, org.apache.airavata.model.error.AiravataSystemException, org.apache.airavata.model.error.AuthorizationException, org.apache.thrift.TException;

    /**
     * Update a Compute Resource Preference to a registered gateway profile.
     * 
     * @param gatewayID
     *   The identifier for the gateway profile to be updated.
     * 
     * @param computeResourceId
     *   Preferences related to a particular compute resource
     * 
     * @param computeResourcePreference
     *   The ComputeResourcePreference object to be updated to the resource profile.
     * 
     * @return status
     *   Returns a success/failure of the updation.
     * 
     * 
     * @param authzToken
     * @param gatewayID
     * @param computeResourceId
     * @param computeResourcePreference
     */
    public boolean updateGatewayComputeResourcePreference(org.apache.airavata.model.security.AuthzToken authzToken, String gatewayID, String computeResourceId, org.apache.airavata.model.appcatalog.gatewayprofile.ComputeResourcePreference computeResourcePreference) throws org.apache.airavata.model.error.InvalidRequestException, org.apache.airavata.model.error.AiravataClientException, org.apache.airavata.model.error.AiravataSystemException, org.apache.airavata.model.error.AuthorizationException, org.apache.thrift.TException;

    public boolean updateGatewayDataStoragePreference(org.apache.airavata.model.security.AuthzToken authzToken, String gatewayID, String dataMoveId, org.apache.airavata.model.appcatalog.gatewayprofile.DataStoragePreference dataStoragePreference) throws org.apache.airavata.model.error.InvalidRequestException, org.apache.airavata.model.error.AiravataClientException, org.apache.airavata.model.error.AiravataSystemException, org.apache.airavata.model.error.AuthorizationException, org.apache.thrift.TException;

    /**
     * Delete the Compute Resource Preference of a registered gateway profile.
     * 
     * @param gatewayID
     *   The identifier for the gateway profile to be deleted.
     * 
     * @param computeResourceId
     *   Preferences related to a particular compute resource
     * 
     * @return status
     *   Returns a success/failure of the deletion.
     * 
     * 
     * @param authzToken
     * @param gatewayID
     * @param computeResourceId
     */
    public boolean deleteGatewayComputeResourcePreference(org.apache.airavata.model.security.AuthzToken authzToken, String gatewayID, String computeResourceId) throws org.apache.airavata.model.error.InvalidRequestException, org.apache.airavata.model.error.AiravataClientException, org.apache.airavata.model.error.AiravataSystemException, org.apache.airavata.model.error.AuthorizationException, org.apache.thrift.TException;

    public boolean deleteGatewayDataStoragePreference(org.apache.airavata.model.security.AuthzToken authzToken, String gatewayID, String dataMoveId) throws org.apache.airavata.model.error.InvalidRequestException, org.apache.airavata.model.error.AiravataClientException, org.apache.airavata.model.error.AiravataSystemException, org.apache.airavata.model.error.AuthorizationException, org.apache.thrift.TException;

    public List<String> getAllWorkflows(org.apache.airavata.model.security.AuthzToken authzToken, String gatewayId) throws org.apache.airavata.model.error.InvalidRequestException, org.apache.airavata.model.error.AiravataClientException, org.apache.airavata.model.error.AiravataSystemException, org.apache.airavata.model.error.AuthorizationException, org.apache.thrift.TException;

    public org.apache.airavata.model.Workflow getWorkflow(org.apache.airavata.model.security.AuthzToken authzToken, String workflowTemplateId) throws org.apache.airavata.model.error.InvalidRequestException, org.apache.airavata.model.error.AiravataClientException, org.apache.airavata.model.error.AiravataSystemException, org.apache.airavata.model.error.AuthorizationException, org.apache.thrift.TException;

    public void deleteWorkflow(org.apache.airavata.model.security.AuthzToken authzToken, String workflowTemplateId) throws org.apache.airavata.model.error.InvalidRequestException, org.apache.airavata.model.error.AiravataClientException, org.apache.airavata.model.error.AiravataSystemException, org.apache.airavata.model.error.AuthorizationException, org.apache.thrift.TException;

    public String registerWorkflow(org.apache.airavata.model.security.AuthzToken authzToken, String gatewayId, org.apache.airavata.model.Workflow workflow) throws org.apache.airavata.model.error.InvalidRequestException, org.apache.airavata.model.error.AiravataClientException, org.apache.airavata.model.error.AiravataSystemException, org.apache.airavata.model.error.AuthorizationException, org.apache.thrift.TException;

    public void updateWorkflow(org.apache.airavata.model.security.AuthzToken authzToken, String workflowTemplateId, org.apache.airavata.model.Workflow workflow) throws org.apache.airavata.model.error.InvalidRequestException, org.apache.airavata.model.error.AiravataClientException, org.apache.airavata.model.error.AiravataSystemException, org.apache.airavata.model.error.AuthorizationException, org.apache.thrift.TException;

    public String getWorkflowTemplateId(org.apache.airavata.model.security.AuthzToken authzToken, String workflowName) throws org.apache.airavata.model.error.InvalidRequestException, org.apache.airavata.model.error.AiravataClientException, org.apache.airavata.model.error.AiravataSystemException, org.apache.airavata.model.error.AuthorizationException, org.apache.thrift.TException;

    public boolean isWorkflowExistWithName(org.apache.airavata.model.security.AuthzToken authzToken, String workflowName) throws org.apache.airavata.model.error.InvalidRequestException, org.apache.airavata.model.error.AiravataClientException, org.apache.airavata.model.error.AiravataSystemException, org.apache.airavata.model.error.AuthorizationException, org.apache.thrift.TException;

  }

  public interface AsyncIface {

    public void getAPIVersion(org.apache.airavata.model.security.AuthzToken authzToken, org.apache.thrift.async.AsyncMethodCallback resultHandler) throws org.apache.thrift.TException;

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

    public void updateGateway(org.apache.airavata.model.security.AuthzToken authzToken, String gatewayId, org.apache.airavata.model.workspace.Gateway updatedGateway, org.apache.thrift.async.AsyncMethodCallback resultHandler) throws org.apache.thrift.TException;

    public void getGateway(org.apache.airavata.model.security.AuthzToken authzToken, String gatewayId, org.apache.thrift.async.AsyncMethodCallback resultHandler) throws org.apache.thrift.TException;

    public void deleteGateway(org.apache.airavata.model.security.AuthzToken authzToken, String gatewayId, org.apache.thrift.async.AsyncMethodCallback resultHandler) throws org.apache.thrift.TException;

    public void getAllGateways(org.apache.airavata.model.security.AuthzToken authzToken, org.apache.thrift.async.AsyncMethodCallback resultHandler) throws org.apache.thrift.TException;

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

    public void generateAndRegisterSSHKeys(org.apache.airavata.model.security.AuthzToken authzToken, String gatewayId, String userName, org.apache.thrift.async.AsyncMethodCallback resultHandler) throws org.apache.thrift.TException;

    public void getSSHPubKey(org.apache.airavata.model.security.AuthzToken authzToken, String airavataCredStoreToken, String gatewayId, org.apache.thrift.async.AsyncMethodCallback resultHandler) throws org.apache.thrift.TException;

    public void getAllUserSSHPubKeys(org.apache.airavata.model.security.AuthzToken authzToken, String userName, org.apache.thrift.async.AsyncMethodCallback resultHandler) throws org.apache.thrift.TException;

    public void createProject(org.apache.airavata.model.security.AuthzToken authzToken, String gatewayId, org.apache.airavata.model.workspace.Project project, org.apache.thrift.async.AsyncMethodCallback resultHandler) throws org.apache.thrift.TException;

    public void updateProject(org.apache.airavata.model.security.AuthzToken authzToken, String projectId, org.apache.airavata.model.workspace.Project updatedProject, org.apache.thrift.async.AsyncMethodCallback resultHandler) throws org.apache.thrift.TException;

    public void getProject(org.apache.airavata.model.security.AuthzToken authzToken, String projectId, org.apache.thrift.async.AsyncMethodCallback resultHandler) throws org.apache.thrift.TException;

    public void deleteProject(org.apache.airavata.model.security.AuthzToken authzToken, String projectId, org.apache.thrift.async.AsyncMethodCallback resultHandler) throws org.apache.thrift.TException;

    public void getUserProjects(org.apache.airavata.model.security.AuthzToken authzToken, String gatewayId, String userName, int limit, int offset, org.apache.thrift.async.AsyncMethodCallback resultHandler) throws org.apache.thrift.TException;

    public void searchProjectsByProjectName(org.apache.airavata.model.security.AuthzToken authzToken, String gatewayId, String userName, String projectName, int limit, int offset, org.apache.thrift.async.AsyncMethodCallback resultHandler) throws org.apache.thrift.TException;

    public void searchProjectsByProjectDesc(org.apache.airavata.model.security.AuthzToken authzToken, String gatewayId, String userName, String description, int limit, int offset, org.apache.thrift.async.AsyncMethodCallback resultHandler) throws org.apache.thrift.TException;

    public void searchExperimentsByName(org.apache.airavata.model.security.AuthzToken authzToken, String gatewayId, String userName, String expName, int limit, int offset, org.apache.thrift.async.AsyncMethodCallback resultHandler) throws org.apache.thrift.TException;

    public void searchExperimentsByDesc(org.apache.airavata.model.security.AuthzToken authzToken, String gatewayId, String userName, String description, int limit, int offset, org.apache.thrift.async.AsyncMethodCallback resultHandler) throws org.apache.thrift.TException;

    public void searchExperimentsByApplication(org.apache.airavata.model.security.AuthzToken authzToken, String gatewayId, String userName, String applicationId, int limit, int offset, org.apache.thrift.async.AsyncMethodCallback resultHandler) throws org.apache.thrift.TException;

    public void searchExperimentsByStatus(org.apache.airavata.model.security.AuthzToken authzToken, String gatewayId, String userName, org.apache.airavata.model.status.ExperimentState experimentState, int limit, int offset, org.apache.thrift.async.AsyncMethodCallback resultHandler) throws org.apache.thrift.TException;

    public void searchExperimentsByCreationTime(org.apache.airavata.model.security.AuthzToken authzToken, String gatewayId, String userName, long fromTime, long toTime, int limit, int offset, org.apache.thrift.async.AsyncMethodCallback resultHandler) throws org.apache.thrift.TException;

    public void searchExperiments(org.apache.airavata.model.security.AuthzToken authzToken, String gatewayId, String userName, Map<org.apache.airavata.model.experiment.ExperimentSearchFields,String> filters, int limit, int offset, org.apache.thrift.async.AsyncMethodCallback resultHandler) throws org.apache.thrift.TException;

    public void getExperimentStatistics(org.apache.airavata.model.security.AuthzToken authzToken, String gatewayId, long fromTime, long toTime, org.apache.thrift.async.AsyncMethodCallback resultHandler) throws org.apache.thrift.TException;

    public void getExperimentsInProject(org.apache.airavata.model.security.AuthzToken authzToken, String projectId, int limit, int offset, org.apache.thrift.async.AsyncMethodCallback resultHandler) throws org.apache.thrift.TException;

    public void getUserExperiments(org.apache.airavata.model.security.AuthzToken authzToken, String gatewayId, String userName, int limit, int offset, org.apache.thrift.async.AsyncMethodCallback resultHandler) throws org.apache.thrift.TException;

    public void createExperiment(org.apache.airavata.model.security.AuthzToken authzToken, String gatewayId, org.apache.airavata.model.experiment.ExperimentModel experiment, org.apache.thrift.async.AsyncMethodCallback resultHandler) throws org.apache.thrift.TException;

    public void deleteExperiment(org.apache.airavata.model.security.AuthzToken authzToken, String experimentId, org.apache.thrift.async.AsyncMethodCallback resultHandler) throws org.apache.thrift.TException;

    public void getExperiment(org.apache.airavata.model.security.AuthzToken authzToken, String airavataExperimentId, org.apache.thrift.async.AsyncMethodCallback resultHandler) throws org.apache.thrift.TException;

    public void getDetailedExperimentTree(org.apache.airavata.model.security.AuthzToken authzToken, String airavataExperimentId, org.apache.thrift.async.AsyncMethodCallback resultHandler) throws org.apache.thrift.TException;

    public void updateExperiment(org.apache.airavata.model.security.AuthzToken authzToken, String airavataExperimentId, org.apache.airavata.model.experiment.ExperimentModel experiment, org.apache.thrift.async.AsyncMethodCallback resultHandler) throws org.apache.thrift.TException;

    public void updateExperimentConfiguration(org.apache.airavata.model.security.AuthzToken authzToken, String airavataExperimentId, org.apache.airavata.model.experiment.UserConfigurationDataModel userConfiguration, org.apache.thrift.async.AsyncMethodCallback resultHandler) throws org.apache.thrift.TException;

    public void updateResourceScheduleing(org.apache.airavata.model.security.AuthzToken authzToken, String airavataExperimentId, org.apache.airavata.model.scheduling.ComputationalResourceSchedulingModel resourceScheduling, org.apache.thrift.async.AsyncMethodCallback resultHandler) throws org.apache.thrift.TException;

    public void validateExperiment(org.apache.airavata.model.security.AuthzToken authzToken, String airavataExperimentId, org.apache.thrift.async.AsyncMethodCallback resultHandler) throws org.apache.thrift.TException;

    public void launchExperiment(org.apache.airavata.model.security.AuthzToken authzToken, String airavataExperimentId, String gatewayId, org.apache.thrift.async.AsyncMethodCallback resultHandler) throws org.apache.thrift.TException;

    public void getExperimentStatus(org.apache.airavata.model.security.AuthzToken authzToken, String airavataExperimentId, org.apache.thrift.async.AsyncMethodCallback resultHandler) throws org.apache.thrift.TException;

    public void getExperimentOutputs(org.apache.airavata.model.security.AuthzToken authzToken, String airavataExperimentId, org.apache.thrift.async.AsyncMethodCallback resultHandler) throws org.apache.thrift.TException;

    public void getIntermediateOutputs(org.apache.airavata.model.security.AuthzToken authzToken, String airavataExperimentId, org.apache.thrift.async.AsyncMethodCallback resultHandler) throws org.apache.thrift.TException;

    public void getJobStatuses(org.apache.airavata.model.security.AuthzToken authzToken, String airavataExperimentId, org.apache.thrift.async.AsyncMethodCallback resultHandler) throws org.apache.thrift.TException;

    public void getJobDetails(org.apache.airavata.model.security.AuthzToken authzToken, String airavataExperimentId, org.apache.thrift.async.AsyncMethodCallback resultHandler) throws org.apache.thrift.TException;

    public void cloneExperiment(org.apache.airavata.model.security.AuthzToken authzToken, String existingExperimentID, String newExperimentName, org.apache.thrift.async.AsyncMethodCallback resultHandler) throws org.apache.thrift.TException;

    public void terminateExperiment(org.apache.airavata.model.security.AuthzToken authzToken, String airavataExperimentId, String gatewayId, org.apache.thrift.async.AsyncMethodCallback resultHandler) throws org.apache.thrift.TException;

    public void registerApplicationModule(org.apache.airavata.model.security.AuthzToken authzToken, String gatewayId, org.apache.airavata.model.appcatalog.appdeployment.ApplicationModule applicationModule, org.apache.thrift.async.AsyncMethodCallback resultHandler) throws org.apache.thrift.TException;

    public void getApplicationModule(org.apache.airavata.model.security.AuthzToken authzToken, String appModuleId, org.apache.thrift.async.AsyncMethodCallback resultHandler) throws org.apache.thrift.TException;

    public void updateApplicationModule(org.apache.airavata.model.security.AuthzToken authzToken, String appModuleId, org.apache.airavata.model.appcatalog.appdeployment.ApplicationModule applicationModule, org.apache.thrift.async.AsyncMethodCallback resultHandler) throws org.apache.thrift.TException;

    public void getAllAppModules(org.apache.airavata.model.security.AuthzToken authzToken, String gatewayId, org.apache.thrift.async.AsyncMethodCallback resultHandler) throws org.apache.thrift.TException;

    public void deleteApplicationModule(org.apache.airavata.model.security.AuthzToken authzToken, String appModuleId, org.apache.thrift.async.AsyncMethodCallback resultHandler) throws org.apache.thrift.TException;

    public void registerApplicationDeployment(org.apache.airavata.model.security.AuthzToken authzToken, String gatewayId, org.apache.airavata.model.appcatalog.appdeployment.ApplicationDeploymentDescription applicationDeployment, org.apache.thrift.async.AsyncMethodCallback resultHandler) throws org.apache.thrift.TException;

    public void getApplicationDeployment(org.apache.airavata.model.security.AuthzToken authzToken, String appDeploymentId, org.apache.thrift.async.AsyncMethodCallback resultHandler) throws org.apache.thrift.TException;

    public void updateApplicationDeployment(org.apache.airavata.model.security.AuthzToken authzToken, String appDeploymentId, org.apache.airavata.model.appcatalog.appdeployment.ApplicationDeploymentDescription applicationDeployment, org.apache.thrift.async.AsyncMethodCallback resultHandler) throws org.apache.thrift.TException;

    public void deleteApplicationDeployment(org.apache.airavata.model.security.AuthzToken authzToken, String appDeploymentId, org.apache.thrift.async.AsyncMethodCallback resultHandler) throws org.apache.thrift.TException;

    public void getAllApplicationDeployments(org.apache.airavata.model.security.AuthzToken authzToken, String gatewayId, org.apache.thrift.async.AsyncMethodCallback resultHandler) throws org.apache.thrift.TException;

    public void getAppModuleDeployedResources(org.apache.airavata.model.security.AuthzToken authzToken, String appModuleId, org.apache.thrift.async.AsyncMethodCallback resultHandler) throws org.apache.thrift.TException;

    public void registerApplicationInterface(org.apache.airavata.model.security.AuthzToken authzToken, String gatewayId, org.apache.airavata.model.appcatalog.appinterface.ApplicationInterfaceDescription applicationInterface, org.apache.thrift.async.AsyncMethodCallback resultHandler) throws org.apache.thrift.TException;

    public void getApplicationInterface(org.apache.airavata.model.security.AuthzToken authzToken, String appInterfaceId, org.apache.thrift.async.AsyncMethodCallback resultHandler) throws org.apache.thrift.TException;

    public void updateApplicationInterface(org.apache.airavata.model.security.AuthzToken authzToken, String appInterfaceId, org.apache.airavata.model.appcatalog.appinterface.ApplicationInterfaceDescription applicationInterface, org.apache.thrift.async.AsyncMethodCallback resultHandler) throws org.apache.thrift.TException;

    public void deleteApplicationInterface(org.apache.airavata.model.security.AuthzToken authzToken, String appInterfaceId, org.apache.thrift.async.AsyncMethodCallback resultHandler) throws org.apache.thrift.TException;

    public void getAllApplicationInterfaceNames(org.apache.airavata.model.security.AuthzToken authzToken, String gatewayId, org.apache.thrift.async.AsyncMethodCallback resultHandler) throws org.apache.thrift.TException;

    public void getAllApplicationInterfaces(org.apache.airavata.model.security.AuthzToken authzToken, String gatewayId, org.apache.thrift.async.AsyncMethodCallback resultHandler) throws org.apache.thrift.TException;

    public void getApplicationInputs(org.apache.airavata.model.security.AuthzToken authzToken, String appInterfaceId, org.apache.thrift.async.AsyncMethodCallback resultHandler) throws org.apache.thrift.TException;

    public void getApplicationOutputs(org.apache.airavata.model.security.AuthzToken authzToken, String appInterfaceId, org.apache.thrift.async.AsyncMethodCallback resultHandler) throws org.apache.thrift.TException;

    public void getAvailableAppInterfaceComputeResources(org.apache.airavata.model.security.AuthzToken authzToken, String appInterfaceId, org.apache.thrift.async.AsyncMethodCallback resultHandler) throws org.apache.thrift.TException;

    public void registerComputeResource(org.apache.airavata.model.security.AuthzToken authzToken, org.apache.airavata.model.appcatalog.computeresource.ComputeResourceDescription computeResourceDescription, org.apache.thrift.async.AsyncMethodCallback resultHandler) throws org.apache.thrift.TException;

    public void getComputeResource(org.apache.airavata.model.security.AuthzToken authzToken, String computeResourceId, org.apache.thrift.async.AsyncMethodCallback resultHandler) throws org.apache.thrift.TException;

    public void getAllComputeResourceNames(org.apache.airavata.model.security.AuthzToken authzToken, org.apache.thrift.async.AsyncMethodCallback resultHandler) throws org.apache.thrift.TException;

    public void updateComputeResource(org.apache.airavata.model.security.AuthzToken authzToken, String computeResourceId, org.apache.airavata.model.appcatalog.computeresource.ComputeResourceDescription computeResourceDescription, org.apache.thrift.async.AsyncMethodCallback resultHandler) throws org.apache.thrift.TException;

    public void deleteComputeResource(org.apache.airavata.model.security.AuthzToken authzToken, String computeResourceId, org.apache.thrift.async.AsyncMethodCallback resultHandler) throws org.apache.thrift.TException;

    public void addLocalSubmissionDetails(org.apache.airavata.model.security.AuthzToken authzToken, String computeResourceId, int priorityOrder, org.apache.airavata.model.appcatalog.computeresource.LOCALSubmission localSubmission, org.apache.thrift.async.AsyncMethodCallback resultHandler) throws org.apache.thrift.TException;

    public void updateLocalSubmissionDetails(org.apache.airavata.model.security.AuthzToken authzToken, String jobSubmissionInterfaceId, org.apache.airavata.model.appcatalog.computeresource.LOCALSubmission localSubmission, org.apache.thrift.async.AsyncMethodCallback resultHandler) throws org.apache.thrift.TException;

    public void getLocalJobSubmission(org.apache.airavata.model.security.AuthzToken authzToken, String jobSubmissionId, org.apache.thrift.async.AsyncMethodCallback resultHandler) throws org.apache.thrift.TException;

    public void addSSHJobSubmissionDetails(org.apache.airavata.model.security.AuthzToken authzToken, String computeResourceId, int priorityOrder, org.apache.airavata.model.appcatalog.computeresource.SSHJobSubmission sshJobSubmission, org.apache.thrift.async.AsyncMethodCallback resultHandler) throws org.apache.thrift.TException;

    public void addSSHForkJobSubmissionDetails(org.apache.airavata.model.security.AuthzToken authzToken, String computeResourceId, int priorityOrder, org.apache.airavata.model.appcatalog.computeresource.SSHJobSubmission sshJobSubmission, org.apache.thrift.async.AsyncMethodCallback resultHandler) throws org.apache.thrift.TException;

    public void getSSHJobSubmission(org.apache.airavata.model.security.AuthzToken authzToken, String jobSubmissionId, org.apache.thrift.async.AsyncMethodCallback resultHandler) throws org.apache.thrift.TException;

    public void addUNICOREJobSubmissionDetails(org.apache.airavata.model.security.AuthzToken authzToken, String computeResourceId, int priorityOrder, org.apache.airavata.model.appcatalog.computeresource.UnicoreJobSubmission unicoreJobSubmission, org.apache.thrift.async.AsyncMethodCallback resultHandler) throws org.apache.thrift.TException;

    public void getUnicoreJobSubmission(org.apache.airavata.model.security.AuthzToken authzToken, String jobSubmissionId, org.apache.thrift.async.AsyncMethodCallback resultHandler) throws org.apache.thrift.TException;

    public void addCloudJobSubmissionDetails(org.apache.airavata.model.security.AuthzToken authzToken, String computeResourceId, int priorityOrder, org.apache.airavata.model.appcatalog.computeresource.CloudJobSubmission cloudSubmission, org.apache.thrift.async.AsyncMethodCallback resultHandler) throws org.apache.thrift.TException;

    public void getCloudJobSubmission(org.apache.airavata.model.security.AuthzToken authzToken, String jobSubmissionId, org.apache.thrift.async.AsyncMethodCallback resultHandler) throws org.apache.thrift.TException;

    public void updateSSHJobSubmissionDetails(org.apache.airavata.model.security.AuthzToken authzToken, String jobSubmissionInterfaceId, org.apache.airavata.model.appcatalog.computeresource.SSHJobSubmission sshJobSubmission, org.apache.thrift.async.AsyncMethodCallback resultHandler) throws org.apache.thrift.TException;

    public void updateCloudJobSubmissionDetails(org.apache.airavata.model.security.AuthzToken authzToken, String jobSubmissionInterfaceId, org.apache.airavata.model.appcatalog.computeresource.CloudJobSubmission sshJobSubmission, org.apache.thrift.async.AsyncMethodCallback resultHandler) throws org.apache.thrift.TException;

    public void updateUnicoreJobSubmissionDetails(org.apache.airavata.model.security.AuthzToken authzToken, String jobSubmissionInterfaceId, org.apache.airavata.model.appcatalog.computeresource.UnicoreJobSubmission unicoreJobSubmission, org.apache.thrift.async.AsyncMethodCallback resultHandler) throws org.apache.thrift.TException;

    public void addLocalDataMovementDetails(org.apache.airavata.model.security.AuthzToken authzToken, String computeResourceId, int priorityOrder, org.apache.airavata.model.appcatalog.computeresource.LOCALDataMovement localDataMovement, org.apache.thrift.async.AsyncMethodCallback resultHandler) throws org.apache.thrift.TException;

    public void updateLocalDataMovementDetails(org.apache.airavata.model.security.AuthzToken authzToken, String dataMovementInterfaceId, org.apache.airavata.model.appcatalog.computeresource.LOCALDataMovement localDataMovement, org.apache.thrift.async.AsyncMethodCallback resultHandler) throws org.apache.thrift.TException;

    public void getLocalDataMovement(org.apache.airavata.model.security.AuthzToken authzToken, String dataMovementId, org.apache.thrift.async.AsyncMethodCallback resultHandler) throws org.apache.thrift.TException;

    public void addSCPDataMovementDetails(org.apache.airavata.model.security.AuthzToken authzToken, String computeResourceId, int priorityOrder, org.apache.airavata.model.appcatalog.computeresource.SCPDataMovement scpDataMovement, org.apache.thrift.async.AsyncMethodCallback resultHandler) throws org.apache.thrift.TException;

    public void updateSCPDataMovementDetails(org.apache.airavata.model.security.AuthzToken authzToken, String dataMovementInterfaceId, org.apache.airavata.model.appcatalog.computeresource.SCPDataMovement scpDataMovement, org.apache.thrift.async.AsyncMethodCallback resultHandler) throws org.apache.thrift.TException;

    public void getSCPDataMovement(org.apache.airavata.model.security.AuthzToken authzToken, String dataMovementId, org.apache.thrift.async.AsyncMethodCallback resultHandler) throws org.apache.thrift.TException;

    public void addUnicoreDataMovementDetails(org.apache.airavata.model.security.AuthzToken authzToken, String computeResourceId, int priorityOrder, org.apache.airavata.model.appcatalog.computeresource.UnicoreDataMovement unicoreDataMovement, org.apache.thrift.async.AsyncMethodCallback resultHandler) throws org.apache.thrift.TException;

    public void updateUnicoreDataMovementDetails(org.apache.airavata.model.security.AuthzToken authzToken, String dataMovementInterfaceId, org.apache.airavata.model.appcatalog.computeresource.UnicoreDataMovement unicoreDataMovement, org.apache.thrift.async.AsyncMethodCallback resultHandler) throws org.apache.thrift.TException;

    public void getUnicoreDataMovement(org.apache.airavata.model.security.AuthzToken authzToken, String dataMovementId, org.apache.thrift.async.AsyncMethodCallback resultHandler) throws org.apache.thrift.TException;

    public void addGridFTPDataMovementDetails(org.apache.airavata.model.security.AuthzToken authzToken, String computeResourceId, int priorityOrder, org.apache.airavata.model.appcatalog.computeresource.GridFTPDataMovement gridFTPDataMovement, org.apache.thrift.async.AsyncMethodCallback resultHandler) throws org.apache.thrift.TException;

    public void updateGridFTPDataMovementDetails(org.apache.airavata.model.security.AuthzToken authzToken, String dataMovementInterfaceId, org.apache.airavata.model.appcatalog.computeresource.GridFTPDataMovement gridFTPDataMovement, org.apache.thrift.async.AsyncMethodCallback resultHandler) throws org.apache.thrift.TException;

    public void getGridFTPDataMovement(org.apache.airavata.model.security.AuthzToken authzToken, String dataMovementId, org.apache.thrift.async.AsyncMethodCallback resultHandler) throws org.apache.thrift.TException;

    public void changeJobSubmissionPriority(org.apache.airavata.model.security.AuthzToken authzToken, String jobSubmissionInterfaceId, int newPriorityOrder, org.apache.thrift.async.AsyncMethodCallback resultHandler) throws org.apache.thrift.TException;

    public void changeDataMovementPriority(org.apache.airavata.model.security.AuthzToken authzToken, String dataMovementInterfaceId, int newPriorityOrder, org.apache.thrift.async.AsyncMethodCallback resultHandler) throws org.apache.thrift.TException;

    public void changeJobSubmissionPriorities(org.apache.airavata.model.security.AuthzToken authzToken, Map<String,Integer> jobSubmissionPriorityMap, org.apache.thrift.async.AsyncMethodCallback resultHandler) throws org.apache.thrift.TException;

    public void changeDataMovementPriorities(org.apache.airavata.model.security.AuthzToken authzToken, Map<String,Integer> dataMovementPriorityMap, org.apache.thrift.async.AsyncMethodCallback resultHandler) throws org.apache.thrift.TException;

    public void deleteJobSubmissionInterface(org.apache.airavata.model.security.AuthzToken authzToken, String computeResourceId, String jobSubmissionInterfaceId, org.apache.thrift.async.AsyncMethodCallback resultHandler) throws org.apache.thrift.TException;

    public void deleteDataMovementInterface(org.apache.airavata.model.security.AuthzToken authzToken, String computeResourceId, String dataMovementInterfaceId, org.apache.thrift.async.AsyncMethodCallback resultHandler) throws org.apache.thrift.TException;

    public void registerResourceJobManager(org.apache.airavata.model.security.AuthzToken authzToken, org.apache.airavata.model.appcatalog.computeresource.ResourceJobManager resourceJobManager, org.apache.thrift.async.AsyncMethodCallback resultHandler) throws org.apache.thrift.TException;

    public void updateResourceJobManager(org.apache.airavata.model.security.AuthzToken authzToken, String resourceJobManagerId, org.apache.airavata.model.appcatalog.computeresource.ResourceJobManager updatedResourceJobManager, org.apache.thrift.async.AsyncMethodCallback resultHandler) throws org.apache.thrift.TException;

    public void getResourceJobManager(org.apache.airavata.model.security.AuthzToken authzToken, String resourceJobManagerId, org.apache.thrift.async.AsyncMethodCallback resultHandler) throws org.apache.thrift.TException;

    public void deleteResourceJobManager(org.apache.airavata.model.security.AuthzToken authzToken, String resourceJobManagerId, org.apache.thrift.async.AsyncMethodCallback resultHandler) throws org.apache.thrift.TException;

    public void deleteBatchQueue(org.apache.airavata.model.security.AuthzToken authzToken, String computeResourceId, String queueName, org.apache.thrift.async.AsyncMethodCallback resultHandler) throws org.apache.thrift.TException;

    public void registerGatewayResourceProfile(org.apache.airavata.model.security.AuthzToken authzToken, org.apache.airavata.model.appcatalog.gatewayprofile.GatewayResourceProfile gatewayResourceProfile, org.apache.thrift.async.AsyncMethodCallback resultHandler) throws org.apache.thrift.TException;

    public void getGatewayResourceProfile(org.apache.airavata.model.security.AuthzToken authzToken, String gatewayID, org.apache.thrift.async.AsyncMethodCallback resultHandler) throws org.apache.thrift.TException;

    public void updateGatewayResourceProfile(org.apache.airavata.model.security.AuthzToken authzToken, String gatewayID, org.apache.airavata.model.appcatalog.gatewayprofile.GatewayResourceProfile gatewayResourceProfile, org.apache.thrift.async.AsyncMethodCallback resultHandler) throws org.apache.thrift.TException;

    public void deleteGatewayResourceProfile(org.apache.airavata.model.security.AuthzToken authzToken, String gatewayID, org.apache.thrift.async.AsyncMethodCallback resultHandler) throws org.apache.thrift.TException;

    public void addGatewayComputeResourcePreference(org.apache.airavata.model.security.AuthzToken authzToken, String gatewayID, String computeResourceId, org.apache.airavata.model.appcatalog.gatewayprofile.ComputeResourcePreference computeResourcePreference, org.apache.thrift.async.AsyncMethodCallback resultHandler) throws org.apache.thrift.TException;

    public void addGatewayDataStoragePreference(org.apache.airavata.model.security.AuthzToken authzToken, String gatewayID, String dataMoveId, org.apache.airavata.model.appcatalog.gatewayprofile.DataStoragePreference dataStoragePreference, org.apache.thrift.async.AsyncMethodCallback resultHandler) throws org.apache.thrift.TException;

    public void getGatewayComputeResourcePreference(org.apache.airavata.model.security.AuthzToken authzToken, String gatewayID, String computeResourceId, org.apache.thrift.async.AsyncMethodCallback resultHandler) throws org.apache.thrift.TException;

    public void getGatewayDataStoragePreference(org.apache.airavata.model.security.AuthzToken authzToken, String gatewayID, String dataMoveId, org.apache.thrift.async.AsyncMethodCallback resultHandler) throws org.apache.thrift.TException;

    public void getAllGatewayComputeResourcePreferences(org.apache.airavata.model.security.AuthzToken authzToken, String gatewayID, org.apache.thrift.async.AsyncMethodCallback resultHandler) throws org.apache.thrift.TException;

    public void getAllGatewayDataStoragePreferences(org.apache.airavata.model.security.AuthzToken authzToken, String gatewayID, org.apache.thrift.async.AsyncMethodCallback resultHandler) throws org.apache.thrift.TException;

    public void getAllGatewayResourceProfiles(org.apache.airavata.model.security.AuthzToken authzToken, org.apache.thrift.async.AsyncMethodCallback resultHandler) throws org.apache.thrift.TException;

    public void updateGatewayComputeResourcePreference(org.apache.airavata.model.security.AuthzToken authzToken, String gatewayID, String computeResourceId, org.apache.airavata.model.appcatalog.gatewayprofile.ComputeResourcePreference computeResourcePreference, org.apache.thrift.async.AsyncMethodCallback resultHandler) throws org.apache.thrift.TException;

    public void updateGatewayDataStoragePreference(org.apache.airavata.model.security.AuthzToken authzToken, String gatewayID, String dataMoveId, org.apache.airavata.model.appcatalog.gatewayprofile.DataStoragePreference dataStoragePreference, org.apache.thrift.async.AsyncMethodCallback resultHandler) throws org.apache.thrift.TException;

    public void deleteGatewayComputeResourcePreference(org.apache.airavata.model.security.AuthzToken authzToken, String gatewayID, String computeResourceId, org.apache.thrift.async.AsyncMethodCallback resultHandler) throws org.apache.thrift.TException;

    public void deleteGatewayDataStoragePreference(org.apache.airavata.model.security.AuthzToken authzToken, String gatewayID, String dataMoveId, org.apache.thrift.async.AsyncMethodCallback resultHandler) throws org.apache.thrift.TException;

    public void getAllWorkflows(org.apache.airavata.model.security.AuthzToken authzToken, String gatewayId, org.apache.thrift.async.AsyncMethodCallback resultHandler) throws org.apache.thrift.TException;

    public void getWorkflow(org.apache.airavata.model.security.AuthzToken authzToken, String workflowTemplateId, org.apache.thrift.async.AsyncMethodCallback resultHandler) throws org.apache.thrift.TException;

    public void deleteWorkflow(org.apache.airavata.model.security.AuthzToken authzToken, String workflowTemplateId, org.apache.thrift.async.AsyncMethodCallback resultHandler) throws org.apache.thrift.TException;

    public void registerWorkflow(org.apache.airavata.model.security.AuthzToken authzToken, String gatewayId, org.apache.airavata.model.Workflow workflow, org.apache.thrift.async.AsyncMethodCallback resultHandler) throws org.apache.thrift.TException;

    public void updateWorkflow(org.apache.airavata.model.security.AuthzToken authzToken, String workflowTemplateId, org.apache.airavata.model.Workflow workflow, org.apache.thrift.async.AsyncMethodCallback resultHandler) throws org.apache.thrift.TException;

    public void getWorkflowTemplateId(org.apache.airavata.model.security.AuthzToken authzToken, String workflowName, org.apache.thrift.async.AsyncMethodCallback resultHandler) throws org.apache.thrift.TException;

    public void isWorkflowExistWithName(org.apache.airavata.model.security.AuthzToken authzToken, String workflowName, org.apache.thrift.async.AsyncMethodCallback resultHandler) throws org.apache.thrift.TException;

  }

  public static class Client extends org.apache.thrift.TServiceClient 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 String getAPIVersion(org.apache.airavata.model.security.AuthzToken authzToken) throws org.apache.airavata.model.error.InvalidRequestException, org.apache.airavata.model.error.AiravataClientException, org.apache.airavata.model.error.AiravataSystemException, org.apache.airavata.model.error.AuthorizationException, org.apache.thrift.TException
    {
      send_getAPIVersion(authzToken);
      return recv_getAPIVersion();
    }

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

    public String recv_getAPIVersion() throws org.apache.airavata.model.error.InvalidRequestException, org.apache.airavata.model.error.AiravataClientException, org.apache.airavata.model.error.AiravataSystemException, org.apache.airavata.model.error.AuthorizationException, org.apache.thrift.TException
    {
      getAPIVersion_result result = new getAPIVersion_result();
      receiveBase(result, "getAPIVersion");
      if (result.isSetSuccess()) {
        return result.success;
      }
      if (result.ire != null) {
        throw result.ire;
      }
      if (result.ace != null) {
        throw result.ace;
      }
      if (result.ase != null) {
        throw result.ase;
      }
      if (result.ae != null) {
        throw result.ae;
      }
      throw new org.apache.thrift.TApplicationException(org.apache.thrift.TApplicationException.MISSING_RESULT, "getAPIVersion failed: unknown result");
    }

    public String addGateway(org.apache.airavata.model.security.AuthzToken authzToken, org.apache.airavata.model.workspace.Gateway gateway) throws org.apache.airavata.model.error.InvalidRequestException, org.apache.airavata.model.error.AiravataClientException, org.apache.airavata.model.error.AiravataSystemException, 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 String recv_addGateway() throws org.apache.airavata.model.error.InvalidRequestException, org.apache.airavata.model.error.AiravataClientException, org.apache.airavata.model.error.AiravataSystemException, 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.ire != null) {
        throw result.ire;
      }
      if (result.ace != null) {
        throw result.ace;
      }
      if (result.ase != null) {
        throw result.ase;
      }
      if (result.ae != null) {
        throw result.ae;
      }
      throw new org.apache.thrift.TApplicationException(org.apache.thrift.TApplicationException.MISSING_RESULT, "addGateway failed: unknown result");
    }

    public void updateGateway(org.apache.airavata.model.security.AuthzToken authzToken, String gatewayId, org.apache.airavata.model.workspace.Gateway updatedGateway) throws org.apache.airavata.model.error.InvalidRequestException, org.apache.airavata.model.error.AiravataClientException, org.apache.airavata.model.error.AiravataSystemException, org.apache.airavata.model.error.AuthorizationException, org.apache.thrift.TException
    {
      send_updateGateway(authzToken, gatewayId, updatedGateway);
      recv_updateGateway();
    }

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

    public void recv_updateGateway() throws org.apache.airavata.model.error.InvalidRequestException, org.apache.airavata.model.error.AiravataClientException, org.apache.airavata.model.error.AiravataSystemException, org.apache.airavata.model.error.AuthorizationException, org.apache.thrift.TException
    {
      updateGateway_result result = new updateGateway_result();
      receiveBase(result, "updateGateway");
      if (result.ire != null) {
        throw result.ire;
      }
      if (result.ace != null) {
        throw result.ace;
      }
      if (result.ase != null) {
        throw result.ase;
      }
      if (result.ae != null) {
        throw result.ae;
      }
      return;
    }

    public org.apache.airavata.model.workspace.Gateway getGateway(org.apache.airavata.model.security.AuthzToken authzToken, String gatewayId) throws org.apache.airavata.model.error.InvalidRequestException, org.apache.airavata.model.error.AiravataClientException, org.apache.airavata.model.error.AiravataSystemException, org.apache.airavata.model.error.AuthorizationException, org.apache.thrift.TException
    {
      send_getGateway(authzToken, gatewayId);
      return recv_getGateway();
    }

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

    public org.apache.airavata.model.workspace.Gateway recv_getGateway() throws org.apache.airavata.model.error.InvalidRequestException, org.apache.airavata.model.error.AiravataClientException, org.apache.airavata.model.error.AiravataSystemException, 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.ire != null) {
        throw result.ire;
      }
      if (result.ace != null) {
        throw result.ace;
      }
      if (result.ase != null) {
        throw result.ase;
      }
      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, String gatewayId) throws org.apache.airavata.model.error.InvalidRequestException, org.apache.airavata.model.error.AiravataClientException, org.apache.airavata.model.error.AiravataSystemException, org.apache.airavata.model.error.AuthorizationException, org.apache.thrift.TException
    {
      send_deleteGateway(authzToken, gatewayId);
      return recv_deleteGateway();
    }

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

    public boolean recv_deleteGateway() throws org.apache.airavata.model.error.InvalidRequestException, org.apache.airavata.model.error.AiravataClientException, org.apache.airavata.model.error.AiravataSystemException, 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.ire != null) {
        throw result.ire;
      }
      if (result.ace != null) {
        throw result.ace;
      }
      if (result.ase != null) {
        throw result.ase;
      }
      if (result.ae != null) {
        throw result.ae;
      }
      throw new org.apache.thrift.TApplicationException(org.apache.thrift.TApplicationException.MISSING_RESULT, "deleteGateway failed: unknown result");
    }

    public List<org.apache.airavata.model.workspace.Gateway> getAllGateways(org.apache.airavata.model.security.AuthzToken authzToken) throws org.apache.airavata.model.error.InvalidRequestException, org.apache.airavata.model.error.AiravataClientException, org.apache.airavata.model.error.AiravataSystemException, 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 List<org.apache.airavata.model.workspace.Gateway> recv_getAllGateways() throws org.apache.airavata.model.error.InvalidRequestException, org.apache.airavata.model.error.AiravataClientException, org.apache.airavata.model.error.AiravataSystemException, 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.ire != null) {
        throw result.ire;
      }
      if (result.ace != null) {
        throw result.ace;
      }
      if (result.ase != null) {
        throw result.ase;
      }
      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, String gatewayId) throws org.apache.airavata.model.error.InvalidRequestException, org.apache.airavata.model.error.AiravataClientException, org.apache.airavata.model.error.AiravataSystemException, 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, 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.model.error.InvalidRequestException, org.apache.airavata.model.error.AiravataClientException, org.apache.airavata.model.error.AiravataSystemException, 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.ire != null) {
        throw result.ire;
      }
      if (result.ace != null) {
        throw result.ace;
      }
      if (result.ase != null) {
        throw result.ase;
      }
      if (result.ae != null) {
        throw result.ae;
      }
      throw new org.apache.thrift.TApplicationException(org.apache.thrift.TApplicationException.MISSING_RESULT, "isGatewayExist failed: unknown result");
    }

    public String generateAndRegisterSSHKeys(org.apache.airavata.model.security.AuthzToken authzToken, String gatewayId, String userName) throws org.apache.airavata.model.error.InvalidRequestException, org.apache.airavata.model.error.AiravataClientException, org.apache.airavata.model.error.AiravataSystemException, org.apache.thrift.TException
    {
      send_generateAndRegisterSSHKeys(authzToken, gatewayId, userName);
      return recv_generateAndRegisterSSHKeys();
    }

    public void send_generateAndRegisterSSHKeys(org.apache.airavata.model.security.AuthzToken authzToken, String gatewayId, String userName) throws org.apache.thrift.TException
    {
      generateAndRegisterSSHKeys_args args = new generateAndRegisterSSHKeys_args();
      args.setAuthzToken(authzToken);
      args.setGatewayId(gatewayId);
      args.setUserName(userName);
      sendBase("generateAndRegisterSSHKeys", args);
    }

    public String recv_generateAndRegisterSSHKeys() throws org.apache.airavata.model.error.InvalidRequestException, org.apache.airavata.model.error.AiravataClientException, org.apache.airavata.model.error.AiravataSystemException, org.apache.thrift.TException
    {
      generateAndRegisterSSHKeys_result result = new generateAndRegisterSSHKeys_result();
      receiveBase(result, "generateAndRegisterSSHKeys");
      if (result.isSetSuccess()) {
        return result.success;
      }
      if (result.ire != null) {
        throw result.ire;
      }
      if (result.ace != null) {
        throw result.ace;
      }
      if (result.ase != null) {
        throw result.ase;
      }
      throw new org.apache.thrift.TApplicationException(org.apache.thrift.TApplicationException.MISSING_RESULT, "generateAndRegisterSSHKeys failed: unknown result");
    }

    public String getSSHPubKey(org.apache.airavata.model.security.AuthzToken authzToken, String airavataCredStoreToken, String gatewayId) throws org.apache.airavata.model.error.InvalidRequestException, org.apache.airavata.model.error.AiravataClientException, org.apache.airavata.model.error.AiravataSystemException, org.apache.thrift.TException
    {
      send_getSSHPubKey(authzToken, airavataCredStoreToken, gatewayId);
      return recv_getSSHPubKey();
    }

    public void send_getSSHPubKey(org.apache.airavata.model.security.AuthzToken authzToken, String airavataCredStoreToken, String gatewayId) throws org.apache.thrift.TException
    {
      getSSHPubKey_args args = new getSSHPubKey_args();
      args.setAuthzToken(authzToken);
      args.setAiravataCredStoreToken(airavataCredStoreToken);
      args.setGatewayId(gatewayId);
      sendBase("getSSHPubKey", args);
    }

    public String recv_getSSHPubKey() throws org.apache.airavata.model.error.InvalidRequestException, org.apache.airavata.model.error.AiravataClientException, org.apache.airavata.model.error.AiravataSystemException, org.apache.thrift.TException
    {
      getSSHPubKey_result result = new getSSHPubKey_result();
      receiveBase(result, "getSSHPubKey");
      if (result.isSetSuccess()) {
        return result.success;
      }
      if (result.ire != null) {
        throw result.ire;
      }
      if (result.ace != null) {
        throw result.ace;
      }
      if (result.ase != null) {
        throw result.ase;
      }
      throw new org.apache.thrift.TApplicationException(org.apache.thrift.TApplicationException.MISSING_RESULT, "getSSHPubKey failed: unknown result");
    }

    public Map<String,String> getAllUserSSHPubKeys(org.apache.airavata.model.security.AuthzToken authzToken, String userName) throws org.apache.airavata.model.error.InvalidRequestException, org.apache.airavata.model.error.AiravataClientException, org.apache.airavata.model.error.AiravataSystemException, org.apache.thrift.TException
    {
      send_getAllUserSSHPubKeys(authzToken, userName);
      return recv_getAllUserSSHPubKeys();
    }

    public void send_getAllUserSSHPubKeys(org.apache.airavata.model.security.AuthzToken authzToken, String userName) throws org.apache.thrift.TException
    {
      getAllUserSSHPubKeys_args args = new getAllUserSSHPubKeys_args();
      args.setAuthzToken(authzToken);
      args.setUserName(userName);
      sendBase("getAllUserSSHPubKeys", args);
    }

    public Map<String,String> recv_getAllUserSSHPubKeys() throws org.apache.airavata.model.error.InvalidRequestException, org.apache.airavata.model.error.AiravataClientException, org.apache.airavata.model.error.AiravataSystemException, org.apache.thrift.TException
    {
      getAllUserSSHPubKeys_result result = new getAllUserSSHPubKeys_result();
      receiveBase(result, "getAllUserSSHPubKeys");
      if (result.isSetSuccess()) {
        return result.success;
      }
      if (result.ire != null) {
        throw result.ire;
      }
      if (result.ace != null) {
        throw result.ace;
      }
      if (result.ase != null) {
        throw result.ase;
      }
      throw new org.apache.thrift.TApplicationException(org.apache.thrift.TApplicationException.MISSING_RESULT, "getAllUserSSHPubKeys failed: unknown result");
    }

    public String createProject(org.apache.airavata.model.security.AuthzToken authzToken, String gatewayId, org.apache.airavata.model.workspace.Project project) throws org.apache.airavata.model.error.InvalidRequestException, org.apache.airavata.model.error.AiravataClientException, org.apache.airavata.model.error.AiravataSystemException, org.apache.airavata.model.error.AuthorizationException, org.apache.thrift.TException
    {
      send_createProject(authzToken, gatewayId, project);
      return recv_createProject();
    }

    public void send_createProject(org.apache.airavata.model.security.AuthzToken authzToken, String gatewayId, org.apache.airavata.model.workspace.Project project) throws org.apache.thrift.TException
    {
      createProject_args args = new createProject_args();
      args.setAuthzToken(authzToken);
      args.setGatewayId(gatewayId);
      args.setProject(project);
      sendBase("createProject", args);
    }

    public String recv_createProject() throws org.apache.airavata.model.error.InvalidRequestException, org.apache.airavata.model.error.AiravataClientException, org.apache.airavata.model.error.AiravataSystemException, org.apache.airavata.model.error.AuthorizationException, org.apache.thrift.TException
    {
      createProject_result result = new createProject_result();
      receiveBase(result, "createProject");
      if (result.isSetSuccess()) {
        return result.success;
      }
      if (result.ire != null) {
        throw result.ire;
      }
      if (result.ace != null) {
        throw result.ace;
      }
      if (result.ase != null) {
        throw result.ase;
      }
      if (result.ae != null) {
        throw result.ae;
      }
      throw new org.apache.thrift.TApplicationException(org.apache.thrift.TApplicationException.MISSING_RESULT, "createProject failed: unknown result");
    }

    public void updateProject(org.apache.airavata.model.security.AuthzToken authzToken, String projectId, org.apache.airavata.model.workspace.Project updatedProject) throws org.apache.airavata.model.error.InvalidRequestException, org.apache.airavata.model.error.AiravataClientException, org.apache.airavata.model.error.AiravataSystemException, org.apache.airavata.model.error.ProjectNotFoundException, org.apache.airavata.model.error.AuthorizationException, org.apache.thrift.TException
    {
      send_updateProject(authzToken, projectId, updatedProject);
      recv_updateProject();
    }

    public void send_updateProject(org.apache.airavata.model.security.AuthzToken authzToken, String projectId, org.apache.airavata.model.workspace.Project updatedProject) throws org.apache.thrift.TException
    {
      updateProject_args args = new updateProject_args();
      args.setAuthzToken(authzToken);
      args.setProjectId(projectId);
      args.setUpdatedProject(updatedProject);
      sendBase("updateProject", args);
    }

    public void recv_updateProject() throws org.apache.airavata.model.error.InvalidRequestException, org.apache.airavata.model.error.AiravataClientException, org.apache.airavata.model.error.AiravataSystemException, org.apache.airavata.model.error.ProjectNotFoundException, org.apache.airavata.model.error.AuthorizationException, org.apache.thrift.TException
    {
      updateProject_result result = new updateProject_result();
      receiveBase(result, "updateProject");
      if (result.ire != null) {
        throw result.ire;
      }
      if (result.ace != null) {
        throw result.ace;
      }
      if (result.ase != null) {
        throw result.ase;
      }
      if (result.pnfe != null) {
        throw result.pnfe;
      }
      if (result.ae != null) {
        throw result.ae;
      }
      return;
    }

    public org.apache.airavata.model.workspace.Project getProject(org.apache.airavata.model.security.AuthzToken authzToken, String projectId) throws org.apache.airavata.model.error.InvalidRequestException, org.apache.airavata.model.error.AiravataClientException, org.apache.airavata.model.error.AiravataSystemException, org.apache.airavata.model.error.ProjectNotFoundException, org.apache.airavata.model.error.AuthorizationException, org.apache.thrift.TException
    {
      send_getProject(authzToken, projectId);
      return recv_getProject();
    }

    public void send_getProject(org.apache.airavata.model.security.AuthzToken authzToken, String projectId) throws org.apache.thrift.TException
    {
      getProject_args args = new getProject_args();
      args.setAuthzToken(authzToken);
      args.setProjectId(projectId);
      sendBase("getProject", args);
    }

    public org.apache.airavata.model.workspace.Project recv_getProject() throws org.apache.airavata.model.error.InvalidRequestException, org.apache.airavata.model.error.AiravataClientException, org.apache.airavata.model.error.AiravataSystemException, org.apache.airavata.model.error.ProjectNotFoundException, org.apache.airavata.model.error.AuthorizationException, org.apache.thrift.TException
    {
      getProject_result result = new getProject_result();
      receiveBase(result, "getProject");
      if (result.isSetSuccess()) {
        return result.success;
      }
      if (result.ire != null) {
        throw result.ire;
      }
      if (result.ace != null) {
        throw result.ace;
      }
      if (result.ase != null) {
        throw result.ase;
      }
      if (result.pnfe != null) {
        throw result.pnfe;
      }
      if (result.ae != null) {
        throw result.ae;
      }
      throw new org.apache.thrift.TApplicationException(org.apache.thrift.TApplicationException.MISSING_RESULT, "getProject failed: unknown result");
    }

    public boolean deleteProject(org.apache.airavata.model.security.AuthzToken authzToken, String projectId) throws org.apache.airavata.model.error.InvalidRequestException, org.apache.airavata.model.error.AiravataClientException, org.apache.airavata.model.error.AiravataSystemException, org.apache.airavata.model.error.ProjectNotFoundException, org.apache.airavata.model.error.AuthorizationException, org.apache.thrift.TException
    {
      send_deleteProject(authzToken, projectId);
      return recv_deleteProject();
    }

    public void send_deleteProject(org.apache.airavata.model.security.AuthzToken authzToken, String projectId) throws org.apache.thrift.TException
    {
      deleteProject_args args = new deleteProject_args();
      args.setAuthzToken(authzToken);
      args.setProjectId(projectId);
      sendBase("deleteProject", args);
    }

    public boolean recv_deleteProject() throws org.apache.airavata.model.error.InvalidRequestException, org.apache.airavata.model.error.AiravataClientException, org.apache.airavata.model.error.AiravataSystemException, org.apache.airavata.model.error.ProjectNotFoundException, org.apache.airavata.model.error.AuthorizationException, org.apache.thrift.TException
    {
      deleteProject_result result = new deleteProject_result();
      receiveBase(result, "deleteProject");
      if (result.isSetSuccess()) {
        return result.success;
      }
      if (result.ire != null) {
        throw result.ire;
      }
      if (result.ace != null) {
        throw result.ace;
      }
      if (result.ase != null) {
        throw result.ase;
      }
      if (result.pnfe != null) {
        throw result.pnfe;
      }
      if (result.ae != null) {
        throw result.ae;
      }
      throw new org.apache.thrift.TApplicationException(org.apache.thrift.TApplicationException.MISSING_RESULT, "deleteProject failed: unknown result");
    }

    public List<org.apache.airavata.model.workspace.Project> getUserProjects(org.apache.airavata.model.security.AuthzToken authzToken, String gatewayId, String userName, int limit, int offset) throws org.apache.airavata.model.error.InvalidRequestException, org.apache.airavata.model.error.AiravataClientException, org.apache.airavata.model.error.AiravataSystemException, org.apache.airavata.model.error.AuthorizationException, org.apache.thrift.TException
    {
      send_getUserProjects(authzToken, gatewayId, userName, limit, offset);
      return recv_getUserProjects();
    }

    public void send_getUserProjects(org.apache.airavata.model.security.AuthzToken authzToken, String gatewayId, String userName, int limit, int offset) throws org.apache.thrift.TException
    {
      getUserProjects_args args = new getUserProjects_args();
      args.setAuthzToken(authzToken);
      args.setGatewayId(gatewayId);
      args.setUserName(userName);
      args.setLimit(limit);
      args.setOffset(offset);
      sendBase("getUserProjects", args);
    }

    public List<org.apache.airavata.model.workspace.Project> recv_getUserProjects() throws org.apache.airavata.model.error.InvalidRequestException, org.apache.airavata.model.error.AiravataClientException, org.apache.airavata.model.error.AiravataSystemException, org.apache.airavata.model.error.AuthorizationException, org.apache.thrift.TException
    {
      getUserProjects_result result = new getUserProjects_result();
      receiveBase(result, "getUserProjects");
      if (result.isSetSuccess()) {
        return result.success;
      }
      if (result.ire != null) {
        throw result.ire;
      }
      if (result.ace != null) {
        throw result.ace;
      }
      if (result.ase != null) {
        throw result.ase;
      }
      if (result.ae != null) {
        throw result.ae;
      }
      throw new org.apache.thrift.TApplicationException(org.apache.thrift.TApplicationException.MISSING_RESULT, "getUserProjects failed: unknown result");
    }

    public List<org.apache.airavata.model.workspace.Project> searchProjectsByProjectName(org.apache.airavata.model.security.AuthzToken authzToken, String gatewayId, String userName, String projectName, int limit, int offset) throws org.apache.airavata.model.error.InvalidRequestException, org.apache.airavata.model.error.AiravataClientException, org.apache.airavata.model.error.AiravataSystemException, org.apache.airavata.model.error.AuthorizationException, org.apache.thrift.TException
    {
      send_searchProjectsByProjectName(authzToken, gatewayId, userName, projectName, limit, offset);
      return recv_searchProjectsByProjectName();
    }

    public void send_searchProjectsByProjectName(org.apache.airavata.model.security.AuthzToken authzToken, String gatewayId, String userName, String projectName, int limit, int offset) throws org.apache.thrift.TException
    {
      searchProjectsByProjectName_args args = new searchProjectsByProjectName_args();
      args.setAuthzToken(authzToken);
      args.setGatewayId(gatewayId);
      args.setUserName(userName);
      args.setProjectName(projectName);
      args.setLimit(limit);
      args.setOffset(offset);
      sendBase("searchProjectsByProjectName", args);
    }

    public List<org.apache.airavata.model.workspace.Project> recv_searchProjectsByProjectName() throws org.apache.airavata.model.error.InvalidRequestException, org.apache.airavata.model.error.AiravataClientException, org.apache.airavata.model.error.AiravataSystemException, org.apache.airavata.model.error.AuthorizationException, org.apache.thrift.TException
    {
      searchProjectsByProjectName_result result = new searchProjectsByProjectName_result();
      receiveBase(result, "searchProjectsByProjectName");
      if (result.isSetSuccess()) {
        return result.success;
      }
      if (result.ire != null) {
        throw result.ire;
      }
      if (result.ace != null) {
        throw result.ace;
      }
      if (result.ase != null) {
        throw result.ase;
      }
      if (result.ae != null) {
        throw result.ae;
      }
      throw new org.apache.thrift.TApplicationException(org.apache.thrift.TApplicationException.MISSING_RESULT, "searchProjectsByProjectName failed: unknown result");
    }

    public List<org.apache.airavata.model.workspace.Project> searchProjectsByProjectDesc(org.apache.airavata.model.security.AuthzToken authzToken, String gatewayId, String userName, String description, int limit, int offset) throws org.apache.airavata.model.error.InvalidRequestException, org.apache.airavata.model.error.AiravataClientException, org.apache.airavata.model.error.AiravataSystemException, org.apache.airavata.model.error.AuthorizationException, org.apache.thrift.TException
    {
      send_searchProjectsByProjectDesc(authzToken, gatewayId, userName, description, limit, offset);
      return recv_searchProjectsByProjectDesc();
    }

    public void send_searchProjectsByProjectDesc(org.apache.airavata.model.security.AuthzToken authzToken, String gatewayId, String userName, String description, int limit, int offset) throws org.apache.thrift.TException
    {
      searchProjectsByProjectDesc_args args = new searchProjectsByProjectDesc_args();
      args.setAuthzToken(authzToken);
      args.setGatewayId(gatewayId);
      args.setUserName(userName);
      args.setDescription(description);
      args.setLimit(limit);
      args.setOffset(offset);
      sendBase("searchProjectsByProjectDesc", args);
    }

    public List<org.apache.airavata.model.workspace.Project> recv_searchProjectsByProjectDesc() throws org.apache.airavata.model.error.InvalidRequestException, org.apache.airavata.model.error.AiravataClientException, org.apache.airavata.model.error.AiravataSystemException, org.apache.airavata.model.error.AuthorizationException, org.apache.thrift.TException
    {
      searchProjectsByProjectDesc_result result = new searchProjectsByProjectDesc_result();
      receiveBase(result, "searchProjectsByProjectDesc");
      if (result.isSetSuccess()) {
        return result.success;
      }
      if (result.ire != null) {
        throw result.ire;
      }
      if (result.ace != null) {
        throw result.ace;
      }
      if (result.ase != null) {
        throw result.ase;
      }
      if (result.ae != null) {
        throw result.ae;
      }
      throw new org.apache.thrift.TApplicationException(org.apache.thrift.TApplicationException.MISSING_RESULT, "searchProjectsByProjectDesc failed: unknown result");
    }

    public List<org.apache.airavata.model.experiment.ExperimentSummaryModel> searchExperimentsByName(org.apache.airavata.model.security.AuthzToken authzToken, String gatewayId, String userName, String expName, int limit, int offset) throws org.apache.airavata.model.error.InvalidRequestException, org.apache.airavata.model.error.AiravataClientException, org.apache.airavata.model.error.AiravataSystemException, org.apache.airavata.model.error.AuthorizationException, org.apache.thrift.TException
    {
      send_searchExperimentsByName(authzToken, gatewayId, userName, expName, limit, offset);
      return recv_searchExperimentsByName();
    }

    public void send_searchExperimentsByName(org.apache.airavata.model.security.AuthzToken authzToken, String gatewayId, String userName, String expName, int limit, int offset) throws org.apache.thrift.TException
    {
      searchExperimentsByName_args args = new searchExperimentsByName_args();
      args.setAuthzToken(authzToken);
      args.setGatewayId(gatewayId);
      args.setUserName(userName);
      args.setExpName(expName);
      args.setLimit(limit);
      args.setOffset(offset);
      sendBase("searchExperimentsByName", args);
    }

    public List<org.apache.airavata.model.experiment.ExperimentSummaryModel> recv_searchExperimentsByName() throws org.apache.airavata.model.error.InvalidRequestException, org.apache.airavata.model.error.AiravataClientException, org.apache.airavata.model.error.AiravataSystemException, org.apache.airavata.model.error.AuthorizationException, org.apache.thrift.TException
    {
      searchExperimentsByName_result result = new searchExperimentsByName_result();
      receiveBase(result, "searchExperimentsByName");
      if (result.isSetSuccess()) {
        return result.success;
      }
      if (result.ire != null) {
        throw result.ire;
      }
      if (result.ace != null) {
        throw result.ace;
      }
      if (result.ase != null) {
        throw result.ase;
      }
      if (result.ae != null) {
        throw result.ae;
      }
      throw new org.apache.thrift.TApplicationException(org.apache.thrift.TApplicationException.MISSING_RESULT, "searchExperimentsByName failed: unknown result");
    }

    public List<org.apache.airavata.model.experiment.ExperimentSummaryModel> searchExperimentsByDesc(org.apache.airavata.model.security.AuthzToken authzToken, String gatewayId, String userName, String description, int limit, int offset) throws org.apache.airavata.model.error.InvalidRequestException, org.apache.airavata.model.error.AiravataClientException, org.apache.airavata.model.error.AiravataSystemException, org.apache.airavata.model.error.AuthorizationException, org.apache.thrift.TException
    {
      send_searchExperimentsByDesc(authzToken, gatewayId, userName, description, limit, offset);
      return recv_searchExperimentsByDesc();
    }

    public void send_searchExperimentsByDesc(org.apache.airavata.model.security.AuthzToken authzToken, String gatewayId, String userName, String description, int limit, int offset) throws org.apache.thrift.TException
    {
      searchExperimentsByDesc_args args = new searchExperimentsByDesc_args();
      args.setAuthzToken(authzToken);
      args.setGatewayId(gatewayId);
      args.setUserName(userName);
      args.setDescription(description);
      args.setLimit(limit);
      args.setOffset(offset);
      sendBase("searchExperimentsByDesc", args);
    }

    public List<org.apache.airavata.model.experiment.ExperimentSummaryModel> recv_searchExperimentsByDesc() throws org.apache.airavata.model.error.InvalidRequestException, org.apache.airavata.model.error.AiravataClientException, org.apache.airavata.model.error.AiravataSystemException, org.apache.airavata.model.error.AuthorizationException, org.apache.thrift.TException
    {
      searchExperimentsByDesc_result result = new searchExperimentsByDesc_result();
      receiveBase(result, "searchExperimentsByDesc");
      if (result.isSetSuccess()) {
        return result.success;
      }
      if (result.ire != null) {
        throw result.ire;
      }
      if (result.ace != null) {
        throw result.ace;
      }
      if (result.ase != null) {
        throw result.ase;
      }
      if (result.ae != null) {
        throw result.ae;
      }
      throw new org.apache.thrift.TApplicationException(org.apache.thrift.TApplicationException.MISSING_RESULT, "searchExperimentsByDesc failed: unknown result");
    }

    public List<org.apache.airavata.model.experiment.ExperimentSummaryModel> searchExperimentsByApplication(org.apache.airavata.model.security.AuthzToken authzToken, String gatewayId, String userName, String applicationId, int limit, int offset) throws org.apache.airavata.model.error.InvalidRequestException, org.apache.airavata.model.error.AiravataClientException, org.apache.airavata.model.error.AiravataSystemException, org.apache.airavata.model.error.AuthorizationException, org.apache.thrift.TException
    {
      send_searchExperimentsByApplication(authzToken, gatewayId, userName, applicationId, limit, offset);
      return recv_searchExperimentsByApplication();
    }

    public void send_searchExperimentsByApplication(org.apache.airavata.model.security.AuthzToken authzToken, String gatewayId, String userName, String applicationId, int limit, int offset) throws org.apache.thrift.TException
    {
      searchExperimentsByApplication_args args = new searchExperimentsByApplication_args();
      args.setAuthzToken(authzToken);
      args.setGatewayId(gatewayId);
      args.setUserName(userName);
      args.setApplicationId(applicationId);
      args.setLimit(limit);
      args.setOffset(offset);
      sendBase("searchExperimentsByApplication", args);
    }

    public List<org.apache.airavata.model.experiment.ExperimentSummaryModel> recv_searchExperimentsByApplication() throws org.apache.airavata.model.error.InvalidRequestException, org.apache.airavata.model.error.AiravataClientException, org.apache.airavata.model.error.AiravataSystemException, org.apache.airavata.model.error.AuthorizationException, org.apache.thrift.TException
    {
      searchExperimentsByApplication_result result = new searchExperimentsByApplication_result();
      receiveBase(result, "searchExperimentsByApplication");
      if (result.isSetSuccess()) {
        return result.success;
      }
      if (result.ire != null) {
        throw result.ire;
      }
      if (result.ace != null) {
        throw result.ace;
      }
      if (result.ase != null) {
        throw result.ase;
      }
      if (result.ae != null) {
        throw result.ae;
      }
      throw new org.apache.thrift.TApplicationException(org.apache.thrift.TApplicationException.MISSING_RESULT, "searchExperimentsByApplication failed: unknown result");
    }

    public List<org.apache.airavata.model.experiment.ExperimentSummaryModel> searchExperimentsByStatus(org.apache.airavata.model.security.AuthzToken authzToken, String gatewayId, String userName, org.apache.airavata.model.status.ExperimentState experimentState, int limit, int offset) throws org.apache.airavata.model.error.InvalidRequestException, org.apache.airavata.model.error.AiravataClientException, org.apache.airavata.model.error.AiravataSystemException, org.apache.airavata.model.error.AuthorizationException, org.apache.thrift.TException
    {
      send_searchExperimentsByStatus(authzToken, gatewayId, userName, experimentState, limit, offset);
      return recv_searchExperimentsByStatus();
    }

    public void send_searchExperimentsByStatus(org.apache.airavata.model.security.AuthzToken authzToken, String gatewayId, String userName, org.apache.airavata.model.status.ExperimentState experimentState, int limit, int offset) throws org.apache.thrift.TException
    {
      searchExperimentsByStatus_args args = new searchExperimentsByStatus_args();
      args.setAuthzToken(authzToken);
      args.setGatewayId(gatewayId);
      args.setUserName(userName);
      args.setExperimentState(experimentState);
      args.setLimit(limit);
      args.setOffset(offset);
      sendBase("searchExperimentsByStatus", args);
    }

    public List<org.apache.airavata.model.experiment.ExperimentSummaryModel> recv_searchExperimentsByStatus() throws org.apache.airavata.model.error.InvalidRequestException, org.apache.airavata.model.error.AiravataClientException, org.apache.airavata.model.error.AiravataSystemException, org.apache.airavata.model.error.AuthorizationException, org.apache.thrift.TException
    {
      searchExperimentsByStatus_result result = new searchExperimentsByStatus_result();
      receiveBase(result, "searchExperimentsByStatus");
      if (result.isSetSuccess()) {
        return result.success;
      }
      if (result.ire != null) {
        throw result.ire;
      }
      if (result.ace != null) {
        throw result.ace;
      }
      if (result.ase != null) {
        throw result.ase;
      }
      if (result.ae != null) {
        throw result.ae;
      }
      throw new org.apache.thrift.TApplicationException(org.apache.thrift.TApplicationException.MISSING_RESULT, "searchExperimentsByStatus failed: unknown result");
    }

    public List<org.apache.airavata.model.experiment.ExperimentSummaryModel> searchExperimentsByCreationTime(org.apache.airavata.model.security.AuthzToken authzToken, String gatewayId, String userName, long fromTime, long toTime, int limit, int offset) throws org.apache.airavata.model.error.InvalidRequestException, org.apache.airavata.model.error.AiravataClientException, org.apache.airavata.model.error.AiravataSystemException, org.apache.airavata.model.error.AuthorizationException, org.apache.thrift.TException
    {
      send_searchExperimentsByCreationTime(authzToken, gatewayId, userName, fromTime, toTime, limit, offset);
      return recv_searchExperimentsByCreationTime();
    }

    public void send_searchExperimentsByCreationTime(org.apache.airavata.model.security.AuthzToken authzToken, String gatewayId, String userName, long fromTime, long toTime, int limit, int offset) throws org.apache.thrift.TException
    {
      searchExperimentsByCreationTime_args args = new searchExperimentsByCreationTime_args();
      args.setAuthzToken(authzToken);
      args.setGatewayId(gatewayId);
      args.setUserName(userName);
      args.setFromTime(fromTime);
      args.setToTime(toTime);
      args.setLimit(limit);
      args.setOffset(offset);
      sendBase("searchExperimentsByCreationTime", args);
    }

    public List<org.apache.airavata.model.experiment.ExperimentSummaryModel> recv_searchExperimentsByCreationTime() throws org.apache.airavata.model.error.InvalidRequestException, org.apache.airavata.model.error.AiravataClientException, org.apache.airavata.model.error.AiravataSystemException, org.apache.airavata.model.error.AuthorizationException, org.apache.thrift.TException
    {
      searchExperimentsByCreationTime_result result = new searchExperimentsByCreationTime_result();
      receiveBase(result, "searchExperimentsByCreationTime");
      if (result.isSetSuccess()) {
        return result.success;
      }
      if (result.ire != null) {
        throw result.ire;
      }
      if (result.ace != null) {
        throw result.ace;
      }
      if (result.ase != null) {
        throw result.ase;
      }
      if (result.ae != null) {
        throw result.ae;
      }
      throw new org.apache.thrift.TApplicationException(org.apache.thrift.TApplicationException.MISSING_RESULT, "searchExperimentsByCreationTime failed: unknown result");
    }

    public List<org.apache.airavata.model.experiment.ExperimentSummaryModel> searchExperiments(org.apache.airavata.model.security.AuthzToken authzToken, String gatewayId, String userName, Map<org.apache.airavata.model.experiment.ExperimentSearchFields,String> filters, int limit, int offset) throws org.apache.airavata.model.error.InvalidRequestException, org.apache.airavata.model.error.AiravataClientException, org.apache.airavata.model.error.AiravataSystemException, org.apache.airavata.model.error.AuthorizationException, org.apache.thrift.TException
    {
      send_searchExperiments(authzToken, gatewayId, userName, filters, limit, offset);
      return recv_searchExperiments();
    }

    public void send_searchExperiments(org.apache.airavata.model.security.AuthzToken authzToken, String gatewayId, String userName, Map<org.apache.airavata.model.experiment.ExperimentSearchFields,String> filters, int limit, int offset) throws org.apache.thrift.TException
    {
      searchExperiments_args args = new searchExperiments_args();
      args.setAuthzToken(authzToken);
      args.setGatewayId(gatewayId);
      args.setUserName(userName);
      args.setFilters(filters);
      args.setLimit(limit);
      args.setOffset(offset);
      sendBase("searchExperiments", args);
    }

    public List<org.apache.airavata.model.experiment.ExperimentSummaryModel> recv_searchExperiments() throws org.apache.airavata.model.error.InvalidRequestException, org.apache.airavata.model.error.AiravataClientException, org.apache.airavata.model.error.AiravataSystemException, org.apache.airavata.model.error.AuthorizationException, org.apache.thrift.TException
    {
      searchExperiments_result result = new searchExperiments_result();
      receiveBase(result, "searchExperiments");
      if (result.isSetSuccess()) {
        return result.success;
      }
      if (result.ire != null) {
        throw result.ire;
      }
      if (result.ace != null) {
        throw result.ace;
      }
      if (result.ase != null) {
        throw result.ase;
      }
      if (result.ae != null) {
        throw result.ae;
      }
      throw new org.apache.thrift.TApplicationException(org.apache.thrift.TApplicationException.MISSING_RESULT, "searchExperiments failed: unknown result");
    }

    public org.apache.airavata.model.experiment.ExperimentStatistics getExperimentStatistics(org.apache.airavata.model.security.AuthzToken authzToken, String gatewayId, long fromTime, long toTime) throws org.apache.airavata.model.error.InvalidRequestException, org.apache.airavata.model.error.AiravataClientException, org.apache.airavata.model.error.AiravataSystemException, org.apache.airavata.model.error.AuthorizationException, org.apache.thrift.TException
    {
      send_getExperimentStatistics(authzToken, gatewayId, fromTime, toTime);
      return recv_getExperimentStatistics();
    }

    public void send_getExperimentStatistics(org.apache.airavata.model.security.AuthzToken authzToken, String gatewayId, long fromTime, long toTime) throws org.apache.thrift.TException
    {
      getExperimentStatistics_args args = new getExperimentStatistics_args();
      args.setAuthzToken(authzToken);
      args.setGatewayId(gatewayId);
      args.setFromTime(fromTime);
      args.setToTime(toTime);
      sendBase("getExperimentStatistics", args);
    }

    public org.apache.airavata.model.experiment.ExperimentStatistics recv_getExperimentStatistics() throws org.apache.airavata.model.error.InvalidRequestException, org.apache.airavata.model.error.AiravataClientException, org.apache.airavata.model.error.AiravataSystemException, org.apache.airavata.model.error.AuthorizationException, org.apache.thrift.TException
    {
      getExperimentStatistics_result result = new getExperimentStatistics_result();
      receiveBase(result, "getExperimentStatistics");
      if (result.isSetSuccess()) {
        return result.success;
      }
      if (result.ire != null) {
        throw result.ire;
      }
      if (result.ace != null) {
        throw result.ace;
      }
      if (result.ase != null) {
        throw result.ase;
      }
      if (result.ae != null) {
        throw result.ae;
      }
      throw new org.apache.thrift.TApplicationException(org.apache.thrift.TApplicationException.MISSING_RESULT, "getExperimentStatistics failed: unknown result");
    }

    public List<org.apache.airavata.model.experiment.ExperimentModel> getExperimentsInProject(org.apache.airavata.model.security.AuthzToken authzToken, String projectId, int limit, int offset) throws org.apache.airavata.model.error.InvalidRequestException, org.apache.airavata.model.error.AiravataClientException, org.apache.airavata.model.error.AiravataSystemException, org.apache.airavata.model.error.ProjectNotFoundException, org.apache.airavata.model.error.AuthorizationException, org.apache.thrift.TException
    {
      send_getExperimentsInProject(authzToken, projectId, limit, offset);
      return recv_getExperimentsInProject();
    }

    public void send_getExperimentsInProject(org.apache.airavata.model.security.AuthzToken authzToken, String projectId, int limit, int offset) throws org.apache.thrift.TException
    {
      getExperimentsInProject_args args = new getExperimentsInProject_args();
      args.setAuthzToken(authzToken);
      args.setProjectId(projectId);
      args.setLimit(limit);
      args.setOffset(offset);
      sendBase("getExperimentsInProject", args);
    }

    public List<org.apache.airavata.model.experiment.ExperimentModel> recv_getExperimentsInProject() throws org.apache.airavata.model.error.InvalidRequestException, org.apache.airavata.model.error.AiravataClientException, org.apache.airavata.model.error.AiravataSystemException, org.apache.airavata.model.error.ProjectNotFoundException, org.apache.airavata.model.error.AuthorizationException, org.apache.thrift.TException
    {
      getExperimentsInProject_result result = new getExperimentsInProject_result();
      receiveBase(result, "getExperimentsInProject");
      if (result.isSetSuccess()) {
        return result.success;
      }
      if (result.ire != null) {
        throw result.ire;
      }
      if (result.ace != null) {
        throw result.ace;
      }
      if (result.ase != null) {
        throw result.ase;
      }
      if (result.pnfe != null) {
        throw result.pnfe;
      }
      if (result.ae != null) {
        throw result.ae;
      }
      throw new org.apache.thrift.TApplicationException(org.apache.thrift.TApplicationException.MISSING_RESULT, "getExperimentsInProject failed: unknown result");
    }

    public List<org.apache.airavata.model.experiment.ExperimentModel> getUserExperiments(org.apache.airavata.model.security.AuthzToken authzToken, String gatewayId, String userName, int limit, int offset) throws org.apache.airavata.model.error.InvalidRequestException, org.apache.airavata.model.error.AiravataClientException, org.apache.airavata.model.error.AiravataSystemException, org.apache.airavata.model.error.AuthorizationException, org.apache.thrift.TException
    {
      send_getUserExperiments(authzToken, gatewayId, userName, limit, offset);
      return recv_getUserExperiments();
    }

    public void send_getUserExperiments(org.apache.airavata.model.security.AuthzToken authzToken, String gatewayId, String userName, int limit, int offset) throws org.apache.thrift.TException
    {
      getUserExperiments_args args = new getUserExperiments_args();
      args.setAuthzToken(authzToken);
      args.setGatewayId(gatewayId);
      args.setUserName(userName);
      args.setLimit(limit);
      args.setOffset(offset);
      sendBase("getUserExperiments", args);
    }

    public List<org.apache.airavata.model.experiment.ExperimentModel> recv_getUserExperiments() throws org.apache.airavata.model.error.InvalidRequestException, org.apache.airavata.model.error.AiravataClientException, org.apache.airavata.model.error.AiravataSystemException, org.apache.airavata.model.error.AuthorizationException, org.apache.thrift.TException
    {
      getUserExperiments_result result = new getUserExperiments_result();
      receiveBase(result, "getUserExperiments");
      if (result.isSetSuccess()) {
        return result.success;
      }
      if (result.ire != null) {
        throw result.ire;
      }
      if (result.ace != null) {
        throw result.ace;
      }
      if (result.ase != null) {
        throw result.ase;
      }
      if (result.ae != null) {
        throw result.ae;
      }
      throw new org.apache.thrift.TApplicationException(org.apache.thrift.TApplicationException.MISSING_RESULT, "getUserExperiments failed: unknown result");
    }

    public String createExperiment(org.apache.airavata.model.security.AuthzToken authzToken, String gatewayId, org.apache.airavata.model.experiment.ExperimentModel experiment) throws org.apache.airavata.model.error.InvalidRequestException, org.apache.airavata.model.error.AiravataClientException, org.apache.airavata.model.error.AiravataSystemException, org.apache.airavata.model.error.AuthorizationException, org.apache.thrift.TException
    {
      send_createExperiment(authzToken, gatewayId, experiment);
      return recv_createExperiment();
    }

    public void send_createExperiment(org.apache.airavata.model.security.AuthzToken authzToken, String gatewayId, org.apache.airavata.model.experiment.ExperimentModel experiment) throws org.apache.thrift.TException
    {
      createExperiment_args args = new createExperiment_args();
      args.setAuthzToken(authzToken);
      args.setGatewayId(gatewayId);
      args.setExperiment(experiment);
      sendBase("createExperiment", args);
    }

    public String recv_createExperiment() throws org.apache.airavata.model.error.InvalidRequestException, org.apache.airavata.model.error.AiravataClientException, org.apache.airavata.model.error.AiravataSystemException, org.apache.airavata.model.error.AuthorizationException, org.apache.thrift.TException
    {
      createExperiment_result result = new createExperiment_result();
      receiveBase(result, "createExperiment");
      if (result.isSetSuccess()) {
        return result.success;
      }
      if (result.ire != null) {
        throw result.ire;
      }
      if (result.ace != null) {
        throw result.ace;
      }
      if (result.ase != null) {
        throw result.ase;
      }
      if (result.ae != null) {
        throw result.ae;
      }
      throw new org.apache.thrift.TApplicationException(org.apache.thrift.TApplicationException.MISSING_RESULT, "createExperiment failed: unknown result");
    }

    public boolean deleteExperiment(org.apache.airavata.model.security.AuthzToken authzToken, String experimentId) throws org.apache.airavata.model.error.InvalidRequestException, org.apache.airavata.model.error.AiravataClientException, org.apache.airavata.model.error.AiravataSystemException, org.apache.airavata.model.error.AuthorizationException, org.apache.thrift.TException
    {
      send_deleteExperiment(authzToken, experimentId);
      return recv_deleteExperiment();
    }

    public void send_deleteExperiment(org.apache.airavata.model.security.AuthzToken authzToken, String experimentId) throws org.apache.thrift.TException
    {
      deleteExperiment_args args = new deleteExperiment_args();
      args.setAuthzToken(authzToken);
      args.setExperimentId(experimentId);
      sendBase("deleteExperiment", args);
    }

    public boolean recv_deleteExperiment() throws org.apache.airavata.model.error.InvalidRequestException, org.apache.airavata.model.error.AiravataClientException, org.apache.airavata.model.error.AiravataSystemException, org.apache.airavata.model.error.AuthorizationException, org.apache.thrift.TException
    {
      deleteExperiment_result result = new deleteExperiment_result();
      receiveBase(result, "deleteExperiment");
      if (result.isSetSuccess()) {
        return result.success;
      }
      if (result.ire != null) {
        throw result.ire;
      }
      if (result.ace != null) {
        throw result.ace;
      }
      if (result.ase != null) {
        throw result.ase;
      }
      if (result.ae != null) {
        throw result.ae;
      }
      throw new org.apache.thrift.TApplicationException(org.apache.thrift.TApplicationException.MISSING_RESULT, "deleteExperiment failed: unknown result");
    }

    public org.apache.airavata.model.experiment.ExperimentModel getExperiment(org.apache.airavata.model.security.AuthzToken authzToken, String airavataExperimentId) throws org.apache.airavata.model.error.InvalidRequestException, org.apache.airavata.model.error.ExperimentNotFoundException, org.apache.airavata.model.error.AiravataClientException, org.apache.airavata.model.error.AiravataSystemException, org.apache.airavata.model.error.AuthorizationException, org.apache.thrift.TException
    {
      send_getExperiment(authzToken, airavataExperimentId);
      return recv_getExperiment();
    }

    public void send_getExperiment(org.apache.airavata.model.security.AuthzToken authzToken, String airavataExperimentId) throws org.apache.thrift.TException
    {
      getExperiment_args args = new getExperiment_args();
      args.setAuthzToken(authzToken);
      args.setAiravataExperimentId(airavataExperimentId);
      sendBase("getExperiment", args);
    }

    public org.apache.airavata.model.experiment.ExperimentModel recv_getExperiment() throws org.apache.airavata.model.error.InvalidRequestException, org.apache.airavata.model.error.ExperimentNotFoundException, org.apache.airavata.model.error.AiravataClientException, org.apache.airavata.model.error.AiravataSystemException, org.apache.airavata.model.error.AuthorizationException, org.apache.thrift.TException
    {
      getExperiment_result result = new getExperiment_result();
      receiveBase(result, "getExperiment");
      if (result.isSetSuccess()) {
        return result.success;
      }
      if (result.ire != null) {
        throw result.ire;
      }
      if (result.enf != null) {
        throw result.enf;
      }
      if (result.ace != null) {
        throw result.ace;
      }
      if (result.ase != null) {
        throw result.ase;
      }
      if (result.ae != null) {
        throw result.ae;
      }
      throw new org.apache.thrift.TApplicationException(org.apache.thrift.TApplicationException.MISSING_RESULT, "getExperiment failed: unknown result");
    }

    public org.apache.airavata.model.experiment.ExperimentModel getDetailedExperimentTree(org.apache.airavata.model.security.AuthzToken authzToken, String airavataExperimentId) throws org.apache.airavata.model.error.InvalidRequestException, org.apache.airavata.model.error.ExperimentNotFoundException, org.apache.airavata.model.error.AiravataClientException, org.apache.airavata.model.error.AiravataSystemException, org.apache.airavata.model.error.AuthorizationException, org.apache.thrift.TException
    {
      send_getDetailedExperimentTree(authzToken, airavataExperimentId);
      return recv_getDetailedExperimentTree();
    }

    public void send_getDetailedExperimentTree(org.apache.airavata.model.security.AuthzToken authzToken, String airavataExperimentId) throws org.apache.thrift.TException
    {
      getDetailedExperimentTree_args args = new getDetailedExperimentTree_args();
      args.setAuthzToken(authzToken);
      args.setAiravataExperimentId(airavataExperimentId);
      sendBase("getDetailedExperimentTree", args);
    }

    public org.apache.airavata.model.experiment.ExperimentModel recv_getDetailedExperimentTree() throws org.apache.airavata.model.error.InvalidRequestException, org.apache.airavata.model.error.ExperimentNotFoundException, org.apache.airavata.model.error.AiravataClientException, org.apache.airavata.model.error.AiravataSystemException, org.apache.airavata.model.error.AuthorizationException, org.apache.thrift.TException
    {
      getDetailedExperimentTree_result result = new getDetailedExperimentTree_result();
      receiveBase(result, "getDetailedExperimentTree");
      if (result.isSetSuccess()) {
        return result.success;
      }
      if (result.ire != null) {
        throw result.ire;
      }
      if (result.enf != null) {
        throw result.enf;
      }
      if (result.ace != null) {
        throw result.ace;
      }
      if (result.ase != null) {
        throw result.ase;
      }
      if (result.ae != null) {
        throw result.ae;
      }
      throw new org.apache.thrift.TApplicationException(org.apache.thrift.TApplicationException.MISSING_RESULT, "getDetailedExperimentTree failed: unknown result");
    }

    public void updateExperiment(org.apache.airavata.model.security.AuthzToken authzToken, String airavataExperimentId, org.apache.airavata.model.experiment.ExperimentModel experiment) throws org.apache.airavata.model.error.InvalidRequestException, org.apache.airavata.model.error.ExperimentNotFoundException, org.apache.airavata.model.error.AiravataClientException, org.apache.airavata.model.error.AiravataSystemException, org.apache.airavata.model.error.AuthorizationException, org.apache.thrift.TException
    {
      send_updateExperiment(authzToken, airavataExperimentId, experiment);
      recv_updateExperiment();
    }

    public void send_updateExperiment(org.apache.airavata.model.security.AuthzToken authzToken, String airavataExperimentId, org.apache.airavata.model.experiment.ExperimentModel experiment) throws org.apache.thrift.TException
    {
      updateExperiment_args args = new updateExperiment_args();
      args.setAuthzToken(authzToken);
      args.setAiravataExperimentId(airavataExperimentId);
      args.setExperiment(experiment);
      sendBase("updateExperiment", args);
    }

    public void recv_updateExperiment() throws org.apache.airavata.model.error.InvalidRequestException, org.apache.airavata.model.error.ExperimentNotFoundException, org.apache.airavata.model.error.AiravataClientException, org.apache.airavata.model.error.AiravataSystemException, org.apache.airavata.model.error.AuthorizationException, org.apache.thrift.TException
    {
      updateExperiment_result result = new updateExperiment_result();
      receiveBase(result, "updateExperiment");
      if (result.ire != null) {
        throw result.ire;
      }
      if (result.enf != null) {
        throw result.enf;
      }
      if (result.ace != null) {
        throw result.ace;
      }
      if (result.ase != null) {
        throw result.ase;
      }
      if (result.ae != null) {
        throw result.ae;
      }
      return;
    }

    public void updateExperimentConfiguration(org.apache.airavata.model.security.AuthzToken authzToken, String airavataExperimentId, org.apache.airavata.model.experiment.UserConfigurationDataModel userConfiguration) throws org.apache.airavata.model.error.AuthorizationException, org.apache.thrift.TException
    {
      send_updateExperimentConfiguration(authzToken, airavataExperimentId, userConfiguration);
      recv_updateExperimentConfiguration();
    }

    public void send_updateExperimentConfiguration(org.apache.airavata.model.security.AuthzToken authzToken, String airavataExperimentId, org.apache.airavata.model.experiment.UserConfigurationDataModel userConfiguration) throws org.apache.thrift.TException
    {
      updateExperimentConfiguration_args args = new updateExperimentConfiguration_args();
      args.setAuthzToken(authzToken);
      args.setAiravataExperimentId(airavataExperimentId);
      args.setUserConfiguration(userConfiguration);
      sendBase("updateExperimentConfiguration", args);
    }

    public void recv_updateExperimentConfiguration() throws org.apache.airavata.model.error.AuthorizationException, org.apache.thrift.TException
    {
      updateExperimentConfiguration_result result = new updateExperimentConfiguration_result();
      receiveBase(result, "updateExperimentConfiguration");
      if (result.ae != null) {
        throw result.ae;
      }
      return;
    }

    public void updateResourceScheduleing(org.apache.airavata.model.security.AuthzToken authzToken, String airavataExperimentId, org.apache.airavata.model.scheduling.ComputationalResourceSchedulingModel resourceScheduling) throws org.apache.airavata.model.error.AuthorizationException, org.apache.thrift.TException
    {
      send_updateResourceScheduleing(authzToken, airavataExperimentId, resourceScheduling);
      recv_updateResourceScheduleing();
    }

    public void send_updateResourceScheduleing(org.apache.airavata.model.security.AuthzToken authzToken, String airavataExperimentId, org.apache.airavata.model.scheduling.ComputationalResourceSchedulingModel resourceScheduling) throws org.apache.thrift.TException
    {
      updateResourceScheduleing_args args = new updateResourceScheduleing_args();
      args.setAuthzToken(authzToken);
      args.setAiravataExperimentId(airavataExperimentId);
      args.setResourceScheduling(resourceScheduling);
      sendBase("updateResourceScheduleing", args);
    }

    public void recv_updateResourceScheduleing() throws org.apache.airavata.model.error.AuthorizationException, org.apache.thrift.TException
    {
      updateResourceScheduleing_result result = new updateResourceScheduleing_result();
      receiveBase(result, "updateResourceScheduleing");
      if (result.ae != null) {
        throw result.ae;
      }
      return;
    }

    public boolean validateExperiment(org.apache.airavata.model.security.AuthzToken authzToken, String airavataExperimentId) throws org.apache.airavata.model.error.InvalidRequestException, org.apache.airavata.model.error.ExperimentNotFoundException, org.apache.airavata.model.error.AiravataClientException, org.apache.airavata.model.error.AiravataSystemException, org.apache.airavata.model.error.AuthorizationException, org.apache.thrift.TException
    {
      send_validateExperiment(authzToken, airavataExperimentId);
      return recv_validateExperiment();
    }

    public void send_validateExperiment(org.apache.airavata.model.security.AuthzToken authzToken, String airavataExperimentId) throws org.apache.thrift.TException
    {
      validateExperiment_args args = new validateExperiment_args();
      args.setAuthzToken(authzToken);
      args.setAiravataExperimentId(airavataExperimentId);
      sendBase("validateExperiment", args);
    }

    public boolean recv_validateExperiment() throws org.apache.airavata.model.error.InvalidRequestException, org.apache.airavata.model.error.ExperimentNotFoundException, org.apache.airavata.model.error.AiravataClientException, org.apache.airavata.model.error.AiravataSystemException, org.apache.airavata.model.error.AuthorizationException, org.apache.thrift.TException
    {
      validateExperiment_result result = new validateExperiment_result();
      receiveBase(result, "validateExperiment");
      if (result.isSetSuccess()) {
        return result.success;
      }
      if (result.ire != null) {
        throw result.ire;
      }
      if (result.enf != null) {
        throw result.enf;
      }
      if (result.ace != null) {
        throw result.ace;
      }
      if (result.ase != null) {
        throw result.ase;
      }
      if (result.ae != null) {
        throw result.ae;
      }
      throw new org.apache.thrift.TApplicationException(org.apache.thrift.TApplicationException.MISSING_RESULT, "validateExperiment failed: unknown result");
    }

    public void launchExperiment(org.apache.airavata.model.security.AuthzToken authzToken, String airavataExperimentId, String gatewayId) throws org.apache.airavata.model.error.InvalidRequestException, org.apache.airavata.model.error.ExperimentNotFoundException, org.apache.airavata.model.error.AiravataClientException, org.apache.airavata.model.error.AiravataSystemException, org.apache.airavata.model.error.AuthorizationException, org.apache.thrift.TException
    {
      send_launchExperiment(authzToken, airavataExperimentId, gatewayId);
      recv_launchExperiment();
    }

    public void send_launchExperiment(org.apache.airavata.model.security.AuthzToken authzToken, String airavataExperimentId, String gatewayId) throws org.apache.thrift.TException
    {
      launchExperiment_args args = new launchExperiment_args();
      args.setAuthzToken(authzToken);
      args.setAiravataExperimentId(airavataExperimentId);
      args.setGatewayId(gatewayId);
      sendBase("launchExperiment", args);
    }

    public void recv_launchExperiment() throws org.apache.airavata.model.error.InvalidRequestException, org.apache.airavata.model.error.ExperimentNotFoundException, org.apache.airavata.model.error.AiravataClientException, org.apache.airavata.model.error.AiravataSystemException, org.apache.airavata.model.error.AuthorizationException, org.apache.thrift.TException
    {
      launchExperiment_result result = new launchExperiment_result();
      receiveBase(result, "launchExperiment");
      if (result.ire != null) {
        throw result.ire;
      }
      if (result.enf != null) {
        throw result.enf;
      }
      if (result.ace != null) {
        throw result.ace;
      }
      if (result.ase != null) {
        throw result.ase;
      }
      if (result.ae != null) {
        throw result.ae;
      }
      return;
    }

    public org.apache.airavata.model.status.ExperimentStatus getExperimentStatus(org.apache.airavata.model.security.AuthzToken authzToken, String airavataExperimentId) throws org.apache.airavata.model.error.InvalidRequestException, org.apache.airavata.model.error.ExperimentNotFoundException, org.apache.airavata.model.error.AiravataClientException, org.apache.airavata.model.error.AiravataSystemException, org.apache.airavata.model.error.AuthorizationException, org.apache.thrift.TException
    {
      send_getExperimentStatus(authzToken, airavataExperimentId);
      return recv_getExperimentStatus();
    }

    public void send_getExperimentStatus(org.apache.airavata.model.security.AuthzToken authzToken, String airavataExperimentId) throws org.apache.thrift.TException
    {
      getExperimentStatus_args args = new getExperimentStatus_args();
      args.setAuthzToken(authzToken);
      args.setAiravataExperimentId(airavataExperimentId);
      sendBase("getExperimentStatus", args);
    }

    public org.apache.airavata.model.status.ExperimentStatus recv_getExperimentStatus() throws org.apache.airavata.model.error.InvalidRequestException, org.apache.airavata.model.error.ExperimentNotFoundException, org.apache.airavata.model.error.AiravataClientException, org.apache.airavata.model.error.AiravataSystemException, org.apache.airavata.model.error.AuthorizationException, org.apache.thrift.TException
    {
      getExperimentStatus_result result = new getExperimentStatus_result();
      receiveBase(result, "getExperimentStatus");
      if (result.isSetSuccess()) {
        return result.success;
      }
      if (result.ire != null) {
        throw result.ire;
      }
      if (result.enf != null) {
        throw result.enf;
      }
      if (result.ace != null) {
        throw result.ace;
      }
      if (result.ase != null) {
        throw result.ase;
      }
      if (result.ae != null) {
        throw result.ae;
      }
      throw new org.apache.thrift.TApplicationException(org.apache.thrift.TApplicationException.MISSING_RESULT, "getExperimentStatus failed: unknown result");
    }

    public List<org.apache.airavata.model.application.io.OutputDataObjectType> getExperimentOutputs(org.apache.airavata.model.security.AuthzToken authzToken, String airavataExperimentId) throws org.apache.airavata.model.error.InvalidRequestException, org.apache.airavata.model.error.ExperimentNotFoundException, org.apache.airavata.model.error.AiravataClientException, org.apache.airavata.model.error.AiravataSystemException, org.apache.airavata.model.error.AuthorizationException, org.apache.thrift.TException
    {
      send_getExperimentOutputs(authzToken, airavataExperimentId);
      return recv_getExperimentOutputs();
    }

    public void send_getExperimentOutputs(org.apache.airavata.model.security.AuthzToken authzToken, String airavataExperimentId) throws org.apache.thrift.TException
    {
      getExperimentOutputs_args args = new getExperimentOutputs_args();
      args.setAuthzToken(authzToken);
      args.setAiravataExperimentId(airavataExperimentId);
      sendBase("getExperimentOutputs", args);
    }

    public List<org.apache.airavata.model.application.io.OutputDataObjectType> recv_getExperimentOutputs() throws org.apache.airavata.model.error.InvalidRequestException, org.apache.airavata.model.error.ExperimentNotFoundException, org.apache.airavata.model.error.AiravataClientException, org.apache.airavata.model.error.AiravataSystemException, org.apache.airavata.model.error.AuthorizationException, org.apache.thrift.TException
    {
      getExperimentOutputs_result result = new getExperimentOutputs_result();
      receiveBase(result, "getExperimentOutputs");
      if (result.isSetSuccess()) {
        return result.success;
      }
      if (result.ire != null) {
        throw result.ire;
      }
      if (result.enf != null) {
        throw result.enf;
      }
      if (result.ace != null) {
        throw result.ace;
      }
      if (result.ase != null) {
        throw result.ase;
      }
      if (result.ae != null) {
        throw result.ae;
      }
      throw new org.apache.thrift.TApplicationException(org.apache.thrift.TApplicationException.MISSING_RESULT, "getExperimentOutputs failed: unknown result");
    }

    public List<org.apache.airavata.model.application.io.OutputDataObjectType> getIntermediateOutputs(org.apache.airavata.model.security.AuthzToken authzToken, String airavataExperimentId) throws org.apache.airavata.model.error.InvalidRequestException, org.apache.airavata.model.error.ExperimentNotFoundException, org.apache.airavata.model.error.AiravataClientException, org.apache.airavata.model.error.AiravataSystemException, org.apache.airavata.model.error.AuthorizationException, org.apache.thrift.TException
    {
      send_getIntermediateOutputs(authzToken, airavataExperimentId);
      return recv_getIntermediateOutputs();
    }

    public void send_getIntermediateOutputs(org.apache.airavata.model.security.AuthzToken authzToken, String airavataExperimentId) throws org.apache.thrift.TException
    {
      getIntermediateOutputs_args args = new getIntermediateOutputs_args();
      args.setAuthzToken(authzToken);
      args.setAiravataExperimentId(airavataExperimentId);
      sendBase("getIntermediateOutputs", args);
    }

    public List<org.apache.airavata.model.application.io.OutputDataObjectType> recv_getIntermediateOutputs() throws org.apache.airavata.model.error.InvalidRequestException, org.apache.airavata.model.error.ExperimentNotFoundException, org.apache.airavata.model.error.AiravataClientException, org.apache.airavata.model.error.AiravataSystemException, org.apache.airavata.model.error.AuthorizationException, org.apache.thrift.TException
    {
      getIntermediateOutputs_result result = new getIntermediateOutputs_result();
      receiveBase(result, "getIntermediateOutputs");
      if (result.isSetSuccess()) {
        return result.success;
      }
      if (result.ire != null) {
        throw result.ire;
      }
      if (result.enf != null) {
        throw result.enf;
      }
      if (result.ace != null) {
        throw result.ace;
      }
      if (result.ase != null) {
        throw result.ase;
      }
      if (result.ae != null) {
        throw result.ae;
      }
      throw new org.apache.thrift.TApplicationException(org.apache.thrift.TApplicationException.MISSING_RESULT, "getIntermediateOutputs failed: unknown result");
    }

    public Map<String,org.apache.airavata.model.status.JobStatus> getJobStatuses(org.apache.airavata.model.security.AuthzToken authzToken, String airavataExperimentId) throws org.apache.airavata.model.error.InvalidRequestException, org.apache.airavata.model.error.ExperimentNotFoundException, org.apache.airavata.model.error.AiravataClientException, org.apache.airavata.model.error.AiravataSystemException, org.apache.airavata.model.error.AuthorizationException, org.apache.thrift.TException
    {
      send_getJobStatuses(authzToken, airavataExperimentId);
      return recv_getJobStatuses();
    }

    public void send_getJobStatuses(org.apache.airavata.model.security.AuthzToken authzToken, String airavataExperimentId) throws org.apache.thrift.TException
    {
      getJobStatuses_args args = new getJobStatuses_args();
      args.setAuthzToken(authzToken);
      args.setAiravataExperimentId(airavataExperimentId);
      sendBase("getJobStatuses", args);
    }

    public Map<String,org.apache.airavata.model.status.JobStatus> recv_getJobStatuses() throws org.apache.airavata.model.error.InvalidRequestException, org.apache.airavata.model.error.ExperimentNotFoundException, org.apache.airavata.model.error.AiravataClientException, org.apache.airavata.model.error.AiravataSystemException, org.apache.airavata.model.error.AuthorizationException, org.apache.thrift.TException
    {
      getJobStatuses_result result = new getJobStatuses_result();
      receiveBase(result, "getJobStatuses");
      if (result.isSetSuccess()) {
        return result.success;
      }
      if (result.ire != null) {
        throw result.ire;
      }
      if (result.enf != null) {
        throw result.enf;
      }
      if (result.ace != null) {
        throw result.ace;
      }
      if (result.ase != null) {
        throw result.ase;
      }
      if (result.ae != null) {
        throw result.ae;
      }
      throw new org.apache.thrift.TApplicationException(org.apache.thrift.TApplicationException.MISSING_RESULT, "getJobStatuses failed: unknown result");
    }

    public List<org.apache.airavata.model.job.JobModel> getJobDetails(org.apache.airavata.model.security.AuthzToken authzToken, String airavataExperimentId) throws org.apache.airavata.model.error.InvalidRequestException, org.apache.airavata.model.error.ExperimentNotFoundException, org.apache.airavata.model.error.AiravataClientException, org.apache.airavata.model.error.AiravataSystemException, org.apache.airavata.model.error.AuthorizationException, org.apache.thrift.TException
    {
      send_getJobDetails(authzToken, airavataExperimentId);
      return recv_getJobDetails();
    }

    public void send_getJobDetails(org.apache.airavata.model.security.AuthzToken authzToken, String airavataExperimentId) throws org.apache.thrift.TException
    {
      getJobDetails_args args = new getJobDetails_args();
      args.setAuthzToken(authzToken);
      args.setAiravataExperimentId(airavataExperimentId);
      sendBase("getJobDetails", args);
    }

    public List<org.apache.airavata.model.job.JobModel> recv_getJobDetails() throws org.apache.airavata.model.error.InvalidRequestException, org.apache.airavata.model.error.ExperimentNotFoundException, org.apache.airavata.model.error.AiravataClientException, org.apache.airavata.model.error.AiravataSystemException, org.apache.airavata.model.error.AuthorizationException, org.apache.thrift.TException
    {
      getJobDetails_result result = new getJobDetails_result();
      receiveBase(result, "getJobDetails");
      if (result.isSetSuccess()) {
        return result.success;
      }
      if (result.ire != null) {
        throw result.ire;
      }
      if (result.enf != null) {
        throw result.enf;
      }
      if (result.ace != null) {
        throw result.ace;
      }
      if (result.ase != null) {
        throw result.ase;
      }
      if (result.ae != null) {
        throw result.ae;
      }
      throw new org.apache.thrift.TApplicationException(org.apache.thrift.TApplicationException.MISSING_RESULT, "getJobDetails failed: unknown result");
    }

    public String cloneExperiment(org.apache.airavata.model.security.AuthzToken authzToken, String existingExperimentID, String newExperimentName) throws org.apache.airavata.model.error.InvalidRequestException, org.apache.airavata.model.error.ExperimentNotFoundException, org.apache.airavata.model.error.AiravataClientException, org.apache.airavata.model.error.AiravataSystemException, org.apache.airavata.model.error.AuthorizationException, org.apache.thrift.TException
    {
      send_cloneExperiment(authzToken, existingExperimentID, newExperimentName);
      return recv_cloneExperiment();
    }

    public void send_cloneExperiment(org.apache.airavata.model.security.AuthzToken authzToken, String existingExperimentID, String newExperimentName) throws org.apache.thrift.TException
    {
      cloneExperiment_args args = new cloneExperiment_args();
      args.setAuthzToken(authzToken);
      args.setExistingExperimentID(existingExperimentID);
      args.setNewExperimentName(newExperimentName);
      sendBase("cloneExperiment", args);
    }

    public String recv_cloneExperiment() throws org.apache.airavata.model.error.InvalidRequestException, org.apache.airavata.model.error.ExperimentNotFoundException, org.apache.airavata.model.error.AiravataClientException, org.apache.airavata.model.error.AiravataSystemException, org.apache.airavata.model.error.AuthorizationException, org.apache.thrift.TException
    {
      cloneExperiment_result result = new cloneExperiment_result();
      receiveBase(result, "cloneExperiment");
      if (result.isSetSuccess()) {
        return result.success;
      }
      if (result.ire != null) {
        throw result.ire;
      }
      if (result.enf != null) {
        throw result.enf;
      }
      if (result.ace != null) {
        throw result.ace;
      }
      if (result.ase != null) {
        throw result.ase;
      }
      if (result.ae != null) {
        throw result.ae;
      }
      throw new org.apache.thrift.TApplicationException(org.apache.thrift.TApplicationException.MISSING_RESULT, "cloneExperiment failed: unknown result");
    }

    public void terminateExperiment(org.apache.airavata.model.security.AuthzToken authzToken, String airavataExperimentId, String gatewayId) throws org.apache.airavata.model.error.InvalidRequestException, org.apache.airavata.model.error.ExperimentNotFoundException, org.apache.airavata.model.error.AiravataClientException, org.apache.airavata.model.error.AiravataSystemException, org.apache.airavata.model.error.AuthorizationException, org.apache.thrift.TException
    {
      send_terminateExperiment(authzToken, airavataExperimentId, gatewayId);
      recv_terminateExperiment();
    }

    public void send_terminateExperiment(org.apache.airavata.model.security.AuthzToken authzToken, String airavataExperimentId, String gatewayId) throws org.apache.thrift.TException
    {
      terminateExperiment_args args = new terminateExperiment_args();
      args.setAuthzToken(authzToken);
      args.setAiravataExperimentId(airavataExperimentId);
      args.setGatewayId(gatewayId);
      sendBase("terminateExperiment", args);
    }

    public void recv_terminateExperiment() throws org.apache.airavata.model.error.InvalidRequestException, org.apache.airavata.model.error.ExperimentNotFoundException, org.apache.airavata.model.error.AiravataClientException, org.apache.airavata.model.error.AiravataSystemException, org.apache.airavata.model.error.AuthorizationException, org.apache.thrift.TException
    {
      terminateExperiment_result result = new terminateExperiment_result();
      receiveBase(result, "terminateExperiment");
      if (result.ire != null) {
        throw result.ire;
      }
      if (result.enf != null) {
        throw result.enf;
      }
      if (result.ace != null) {
        throw result.ace;
      }
      if (result.ase != null) {
        throw result.ase;
      }
      if (result.ae != null) {
        throw result.ae;
      }
      return;
    }

    public String registerApplicationModule(org.apache.airavata.model.security.AuthzToken authzToken, String gatewayId, org.apache.airavata.model.appcatalog.appdeployment.ApplicationModule applicationModule) throws org.apache.airavata.model.error.InvalidRequestException, org.apache.airavata.model.error.AiravataClientException, org.apache.airavata.model.error.AiravataSystemException, org.apache.airavata.model.error.AuthorizationException, org.apache.thrift.TException
    {
      send_registerApplicationModule(authzToken, gatewayId, applicationModule);
      return recv_registerApplicationModule();
    }

    public void send_registerApplicationModule(org.apache.airavata.model.security.AuthzToken authzToken, String gatewayId, org.apache.airavata.model.appcatalog.appdeployment.ApplicationModule applicationModule) throws org.apache.thrift.TException
    {
      registerApplicationModule_args args = new registerApplicationModule_args();
      args.setAuthzToken(authzToken);
      args.setGatewayId(gatewayId);
      args.setApplicationModule(applicationModule);
      sendBase("registerApplicationModule", args);
    }

    public String recv_registerApplicationModule() throws org.apache.airavata.model.error.InvalidRequestException, org.apache.airavata.model.error.AiravataClientException, org.apache.airavata.model.error.AiravataSystemException, org.apache.airavata.model.error.AuthorizationException, org.apache.thrift.TException
    {
      registerApplicationModule_result result = new registerApplicationModule_result();
      receiveBase(result, "registerApplicationModule");
      if (result.isSetSuccess()) {
        return result.success;
      }
      if (result.ire != null) {
        throw result.ire;
      }
      if (result.ace != null) {
        throw result.ace;
      }
      if (result.ase != null) {
        throw result.ase;
      }
      if (result.ae != null) {
        throw result.ae;
      }
      throw new org.apache.thrift.TApplicationException(org.apache.thrift.TApplicationException.MISSING_RESULT, "registerApplicationModule failed: unknown result");
    }

    public org.apache.airavata.model.appcatalog.appdeployment.ApplicationModule getApplicationModule(org.apache.airavata.model.security.AuthzToken authzToken, String appModuleId) throws org.apache.airavata.model.error.InvalidRequestException, org.apache.airavata.model.error.AiravataClientException, org.apache.airavata.model.error.AiravataSystemException, org.apache.airavata.model.error.AuthorizationException, org.apache.thrift.TException
    {
      send_getApplicationModule(authzToken, appModuleId);
      return recv_getApplicationModule();
    }

    public void send_getApplicationModule(org.apache.airavata.model.security.AuthzToken authzToken, String appModuleId) throws org.apache.thrift.TException
    {
      getApplicationModule_args args = new getApplicationModule_args();
      args.setAuthzToken(authzToken);
      args.setAppModuleId(appModuleId);
      sendBase("getApplicationModule", args);
    }

    public org.apache.airavata.model.appcatalog.appdeployment.ApplicationModule recv_getApplicationModule() throws org.apache.airavata.model.error.InvalidRequestException, org.apache.airavata.model.error.AiravataClientException, org.apache.airavata.model.error.AiravataSystemException, org.apache.airavata.model.error.AuthorizationException, org.apache.thrift.TException
    {
      getApplicationModule_result result = new getApplicationModule_result();
      receiveBase(result, "getApplicationModule");
      if (result.isSetSuccess()) {
        return result.success;
      }
      if (result.ire != null) {
        throw result.ire;
      }
      if (result.ace != null) {
        throw result.ace;
      }
      if (result.ase != null) {
        throw result.ase;
      }
      if (result.ae != null) {
        throw result.ae;
      }
      throw new org.apache.thrift.TApplicationException(org.apache.thrift.TApplicationException.MISSING_RESULT, "getApplicationModule failed: unknown result");
    }

    public boolean updateApplicationModule(org.apache.airavata.model.security.AuthzToken authzToken, String appModuleId, org.apache.airavata.model.appcatalog.appdeployment.ApplicationModule applicationModule) throws org.apache.airavata.model.error.InvalidRequestException, org.apache.airavata.model.error.AiravataClientException, org.apache.airavata.model.error.AiravataSystemException, org.apache.airavata.model.error.AuthorizationException, org.apache.thrift.TException
    {
      send_updateApplicationModule(authzToken, appModuleId, applicationModule);
      return recv_updateApplicationModule();
    }

    public void send_updateApplicationModule(org.apache.airavata.model.security.AuthzToken authzToken, String appModuleId, org.apache.airavata.model.appcatalog.appdeployment.ApplicationModule applicationModule) throws org.apache.thrift.TException
    {
      updateApplicationModule_args args = new updateApplicationModule_args();
      args.setAuthzToken(authzToken);
      args.setAppModuleId(appModuleId);
      args.setApplicationModule(applicationModule);
      sendBase("updateApplicationModule", args);
    }

    public boolean recv_updateApplicationModule() throws org.apache.airavata.model.error.InvalidRequestException, org.apache.airavata.model.error.AiravataClientException, org.apache.airavata.model.error.AiravataSystemException, org.apache.airavata.model.error.AuthorizationException, org.apache.thrift.TException
    {
      updateApplicationModule_result result = new updateApplicationModule_result();
      receiveBase(result, "updateApplicationModule");
      if (result.isSetSuccess()) {
        return result.success;
      }
      if (result.ire != null) {
        throw result.ire;
      }
      if (result.ace != null) {
        throw result.ace;
      }
      if (result.ase != null) {
        throw result.ase;
      }
      if (result.ae != null) {
        throw result.ae;
      }
      throw new org.apache.thrift.TApplicationException(org.apache.thrift.TApplicationException.MISSING_RESULT, "updateApplicationModule failed: unknown result");
    }

    public List<org.apache.airavata.model.appcatalog.appdeployment.ApplicationModule> getAllAppModules(org.apache.airavata.model.security.AuthzToken authzToken, String gatewayId) throws org.apache.airavata.model.error.InvalidRequestException, org.apache.airavata.model.error.AiravataClientException, org.apache.airavata.model.error.AiravataSystemException, org.apache.airavata.model.error.AuthorizationException, org.apache.thrift.TException
    {
      send_getAllAppModules(authzToken, gatewayId);
      return recv_getAllAppModules();
    }

    public void send_getAllAppModules(org.apache.airavata.model.security.AuthzToken authzToken, String gatewayId) throws org.apache.thrift.TException
    {
      getAllAppModules_args args = new getAllAppModules_args();
      args.setAuthzToken(authzToken);
      args.setGatewayId(gatewayId);
      sendBase("getAllAppModules", args);
    }

    public List<org.apache.airavata.model.appcatalog.appdeployment.ApplicationModule> recv_getAllAppModules() throws org.apache.airavata.model.error.InvalidRequestException, org.apache.airavata.model.error.AiravataClientException, org.apache.airavata.model.error.AiravataSystemException, org.apache.airavata.model.error.AuthorizationException, org.apache.thrift.TException
    {
      getAllAppModules_result result = new getAllAppModules_result();
      receiveBase(result, "getAllAppModules");
      if (result.isSetSuccess()) {
        return result.success;
      }
      if (result.ire != null) {
        throw result.ire;
      }
      if (result.ace != null) {
        throw result.ace;
      }
      if (result.ase != null) {
        throw result.ase;
      }
      if (result.ae != null) {
        throw result.ae;
      }
      throw new org.apache.thrift.TApplicationException(org.apache.thrift.TApplicationException.MISSING_RESULT, "getAllAppModules failed: unknown result");
    }

    public boolean deleteApplicationModule(org.apache.airavata.model.security.AuthzToken authzToken, String appModuleId) throws org.apache.airavata.model.error.InvalidRequestException, org.apache.airavata.model.error.AiravataClientException, org.apache.airavata.model.error.AiravataSystemException, org.apache.airavata.model.error.AuthorizationException, org.apache.thrift.TException
    {
      send_deleteApplicationModule(authzToken, appModuleId);
      return recv_deleteApplicationModule();
    }

    public void send_deleteApplicationModule(org.apache.airavata.model.security.AuthzToken authzToken, String appModuleId) throws org.apache.thrift.TException
    {
      deleteApplicationModule_args args = new deleteApplicationModule_args();
      args.setAuthzToken(authzToken);
      args.setAppModuleId(appModuleId);
      sendBase("deleteApplicationModule", args);
    }

    public boolean recv_deleteApplicationModule() throws org.apache.airavata.model.error.InvalidRequestException, org.apache.airavata.model.error.AiravataClientException, org.apache.airavata.model.error.AiravataSystemException, org.apache.airavata.model.error.AuthorizationException, org.apache.thrift.TException
    {
      deleteApplicationModule_result result = new deleteApplicationModule_result();
      receiveBase(result, "deleteApplicationModule");
      if (result.isSetSuccess()) {
        return result.success;
      }
      if (result.ire != null) {
        throw result.ire;
      }
      if (result.ace != null) {
        throw result.ace;
      }
      if (result.ase != null) {
        throw result.ase;
      }
      if (result.ae != null) {
        throw result.ae;
      }
      throw new org.apache.thrift.TApplicationException(org.apache.thrift.TApplicationException.MISSING_RESULT, "deleteApplicationModule failed: unknown result");
    }

    public String registerApplicationDeployment(org.apache.airavata.model.security.AuthzToken authzToken, String gatewayId, org.apache.airavata.model.appcatalog.appdeployment.ApplicationDeploymentDescription applicationDeployment) throws org.apache.airavata.model.error.InvalidRequestException, org.apache.airavata.model.error.AiravataClientException, org.apache.airavata.model.error.AiravataSystemException, org.apache.airavata.model.error.AuthorizationException, org.apache.thrift.TException
    {
      send_registerApplicationDeployment(authzToken, gatewayId, applicationDeployment);
      return recv_registerApplicationDeployment();
    }

    public void send_registerApplicationDeployment(org.apache.airavata.model.security.AuthzToken authzToken, String gatewayId, org.apache.airavata.model.appcatalog.appdeployment.ApplicationDeploymentDescription applicationDeployment) throws org.apache.thrift.TException
    {
      registerApplicationDeployment_args args = new registerApplicationDeployment_args();
      args.setAuthzToken(authzToken);
      args.setGatewayId(gatewayId);
      args.setApplicationDeployment(applicationDeployment);
      sendBase("registerApplicationDeployment", args);
    }

    public String recv_registerApplicationDeployment() throws org.apache.airavata.model.error.InvalidRequestException, org.apache.airavata.model.error.AiravataClientException, org.apache.airavata.model.error.AiravataSystemException, org.apache.airavata.model.error.AuthorizationException, org.apache.thrift.TException
    {
      registerApplicationDeployment_result result = new registerApplicationDeployment_result();
      receiveBase(result, "registerApplicationDeployment");
      if (result.isSetSuccess()) {
        return result.success;
      }
      if (result.ire != null) {
        throw result.ire;
      }
      if (result.ace != null) {
        throw result.ace;
      }
      if (result.ase != null) {
        throw result.ase;
      }
      if (result.ae != null) {
        throw result.ae;
      }
      throw new org.apache.thrift.TApplicationException(org.apache.thrift.TApplicationException.MISSING_RESULT, "registerApplicationDeployment failed: unknown result");
    }

    public org.apache.airavata.model.appcatalog.appdeployment.ApplicationDeploymentDescription getApplicationDeployment(org.apache.airavata.model.security.AuthzToken authzToken, String appDeploymentId) throws org.apache.airavata.model.error.InvalidRequestException, org.apache.airavata.model.error.AiravataClientException, org.apache.airavata.model.error.AiravataSystemException, org.apache.airavata.model.error.AuthorizationException, org.apache.thrift.TException
    {
      send_getApplicationDeployment(authzToken, appDeploymentId);
      return recv_getApplicationDeployment();
    }

    public void send_getApplicationDeployment(org.apache.airavata.model.security.AuthzToken authzToken, String appDeploymentId) throws org.apache.thrift.TException
    {
      getApplicationDeployment_args args = new getApplicationDeployment_args();
      args.setAuthzToken(authzToken);
      args.setAppDeploymentId(appDeploymentId);
      sendBase("getApplicationDeployment", args);
    }

    public org.apache.airavata.model.appcatalog.appdeployment.ApplicationDeploymentDescription recv_getApplicationDeployment() throws org.apache.airavata.model.error.InvalidRequestException, org.apache.airavata.model.error.AiravataClientException, org.apache.airavata.model.error.AiravataSystemException, org.apache.airavata.model.error.AuthorizationException, org.apache.thrift.TException
    {
      getApplicationDeployment_result result = new getApplicationDeployment_result();
      receiveBase(result, "getApplicationDeployment");
      if (result.isSetSuccess()) {
        return result.success;
      }
      if (result.ire != null) {
        throw result.ire;
      }
      if (result.ace != null) {
        throw result.ace;
      }
      if (result.ase != null) {
        throw result.ase;
      }
      if (result.ae != null) {
        throw result.ae;
      }
      throw new org.apache.thrift.TApplicationException(org.apache.thrift.TApplicationException.MISSING_RESULT, "getApplicationDeployment failed: unknown result");
    }

    public boolean updateApplicationDeployment(org.apache.airavata.model.security.AuthzToken authzToken, String appDeploymentId, org.apache.airavata.model.appcatalog.appdeployment.ApplicationDeploymentDescription applicationDeployment) throws org.apache.airavata.model.error.InvalidRequestException, org.apache.airavata.model.error.AiravataClientException, org.apache.airavata.model.error.AiravataSystemException, org.apache.airavata.model.error.AuthorizationException, org.apache.thrift.TException
    {
      send_updateApplicationDeployment(authzToken, appDeploymentId, applicationDeployment);
      return recv_updateApplicationDeployment();
    }

    public void send_updateApplicationDeployment(org.apache.airavata.model.security.AuthzToken authzToken, String appDeploymentId, org.apache.airavata.model.appcatalog.appdeployment.ApplicationDeploymentDescription applicationDeployment) throws org.apache.thrift.TException
    {
      updateApplicationDeployment_args args = new updateApplicationDeployment_args();
      args.setAuthzToken(authzToken);
      args.setAppDeploymentId(appDeploymentId);
      args.setApplicationDeployment(applicationDeployment);
      sendBase("updateApplicationDeployment", args);
    }

    public boolean recv_updateApplicationDeployment() throws org.apache.airavata.model.error.InvalidRequestException, org.apache.airavata.model.error.AiravataClientException, org.apache.airavata.model.error.AiravataSystemException, org.apache.airavata.model.error.AuthorizationException, org.apache.thrift.TException
    {
      updateApplicationDeployment_result result = new updateApplicationDeployment_result();
      receiveBase(result, "updateApplicationDeployment");
      if (result.isSetSuccess()) {
        return result.success;
      }
      if (result.ire != null) {
        throw result.ire;
      }
      if (result.ace != null) {
        throw result.ace;
      }
      if (result.ase != null) {
        throw result.ase;
      }
      if (result.ae != null) {
        throw result.ae;
      }
      throw new org.apache.thrift.TApplicationException(org.apache.thrift.TApplicationException.MISSING_RESULT, "updateApplicationDeployment failed: unknown result");
    }

    public boolean deleteApplicationDeployment(org.apache.airavata.model.security.AuthzToken authzToken, String appDeploymentId) throws org.apache.airavata.model.error.InvalidRequestException, org.apache.airavata.model.error.AiravataClientException, org.apache.airavata.model.error.AiravataSystemException, org.apache.airavata.model.error.AuthorizationException, org.apache.thrift.TException
    {
      send_deleteApplicationDeployment(authzToken, appDeploymentId);
      return recv_deleteApplicationDeployment();
    }

    public void send_deleteApplicationDeployment(org.apache.airavata.model.security.AuthzToken authzToken, String appDeploymentId) throws org.apache.thrift.TException
    {
      deleteApplicationDeployment_args args = new deleteApplicationDeployment_args();
      args.setAuthzToken(authzToken);
      args.setAppDeploymentId(appDeploymentId);
      sendBase("deleteApplicationDeployment", args);
    }

    public boolean recv_deleteApplicationDeployment() throws org.apache.airavata.model.error.InvalidRequestException, org.apache.airavata.model.error.AiravataClientException, org.apache.airavata.model.error.AiravataSystemException, org.apache.airavata.model.error.AuthorizationException, org.apache.thrift.TException
    {
      deleteApplicationDeployment_result result = new deleteApplicationDeployment_result();
      receiveBase(result, "deleteApplicationDeployment");
      if (result.isSetSuccess()) {
        return result.success;
      }
      if (result.ire != null) {
        throw result.ire;
      }
      if (result.ace != null) {
        throw result.ace;
      }
      if (result.ase != null) {
        throw result.ase;
      }
      if (result.ae != null) {
        throw result.ae;
      }
      throw new org.apache.thrift.TApplicationException(org.apache.thrift.TApplicationException.MISSING_RESULT, "deleteApplicationDeployment failed: unknown result");
    }

    public List<org.apache.airavata.model.appcatalog.appdeployment.ApplicationDeploymentDescription> getAllApplicationDeployments(org.apache.airavata.model.security.AuthzToken authzToken, String gatewayId) throws org.apache.airavata.model.error.InvalidRequestException, org.apache.airavata.model.error.AiravataClientException, org.apache.airavata.model.error.AiravataSystemException, org.apache.airavata.model.error.AuthorizationException, org.apache.thrift.TException
    {
      send_getAllApplicationDeployments(authzToken, gatewayId);
      return recv_getAllApplicationDeployments();
    }

    public void send_getAllApplicationDeployments(org.apache.airavata.model.security.AuthzToken authzToken, String gatewayId) throws org.apache.thrift.TException
    {
      getAllApplicationDeployments_args args = new getAllApplicationDeployments_args();
      args.setAuthzToken(authzToken);
      args.setGatewayId(gatewayId);
      sendBase("getAllApplicationDeployments", args);
    }

    public List<org.apache.airavata.model.appcatalog.appdeployment.ApplicationDeploymentDescription> recv_getAllApplicationDeployments() throws org.apache.airavata.model.error.InvalidRequestException, org.apache.airavata.model.error.AiravataClientException, org.apache.airavata.model.error.AiravataSystemException, org.apache.airavata.model.error.AuthorizationException, org.apache.thrift.TException
    {
      getAllApplicationDeployments_result result = new getAllApplicationDeployments_result();
      receiveBase(result, "getAllApplicationDeployments");
      if (result.isSetSuccess()) {
        return result.success;
      }
      if (result.ire != null) {
        throw result.ire;
      }
      if (result.ace != null) {
        throw result.ace;
      }
      if (result.ase != null) {
        throw result.ase;
      }
      if (result.ae != null) {
        throw result.ae;
      }
      throw new org.apache.thrift.TApplicationException(org.apache.thrift.TApplicationException.MISSING_RESULT, "getAllApplicationDeployments failed: unknown result");
    }

    public List<String> getAppModuleDeployedResources(org.apache.airavata.model.security.AuthzToken authzToken, String appModuleId) throws org.apache.airavata.model.error.InvalidRequestException, org.apache.airavata.model.error.AiravataClientException, org.apache.airavata.model.error.AiravataSystemException, org.apache.airavata.model.error.AuthorizationException, org.apache.thrift.TException
    {
      send_getAppModuleDeployedResources(authzToken, appModuleId);
      return recv_getAppModuleDeployedResources();
    }

    public void send_getAppModuleDeployedResources(org.apache.airavata.model.security.AuthzToken authzToken, String appModuleId) throws org.apache.thrift.TException
    {
      getAppModuleDeployedResources_args args = new getAppModuleDeployedResources_args();
      args.setAuthzToken(authzToken);
      args.setAppModuleId(appModuleId);
      sendBase("getAppModuleDeployedResources", args);
    }

    public List<String> recv_getAppModuleDeployedResources() throws org.apache.airavata.model.error.InvalidRequestException, org.apache.airavata.model.error.AiravataClientException, org.apache.airavata.model.error.AiravataSystemException, org.apache.airavata.model.error.AuthorizationException, org.apache.thrift.TException
    {
      getAppModuleDeployedResources_result result = new getAppModuleDeployedResources_result();
      receiveBase(result, "getAppModuleDeployedResources");
      if (result.isSetSuccess()) {
        return result.success;
      }
      if (result.ire != null) {
        throw result.ire;
      }
      if (result.ace != null) {
        throw result.ace;
      }
      if (result.ase != null) {
        throw result.ase;
      }
      if (result.ae != null) {
        throw result.ae;
      }
      throw new org.apache.thrift.TApplicationException(org.apache.thrift.TApplicationException.MISSING_RESULT, "getAppModuleDeployedResources failed: unknown result");
    }

    public String registerApplicationInterface(org.apache.airavata.model.security.AuthzToken authzToken, String gatewayId, org.apache.airavata.model.appcatalog.appinterface.ApplicationInterfaceDescription applicationInterface) throws org.apache.airavata.model.error.InvalidRequestException, org.apache.airavata.model.error.AiravataClientException, org.apache.airavata.model.error.AiravataSystemException, org.apache.airavata.model.error.AuthorizationException, org.apache.thrift.TException
    {
      send_registerApplicationInterface(authzToken, gatewayId, applicationInterface);
      return recv_registerApplicationInterface();
    }

    public void send_registerApplicationInterface(org.apache.airavata.model.security.AuthzToken authzToken, String gatewayId, org.apache.airavata.model.appcatalog.appinterface.ApplicationInterfaceDescription applicationInterface) throws org.apache.thrift.TException
    {
      registerApplicationInterface_args args = new registerApplicationInterface_args();
      args.setAuthzToken(authzToken);
      args.setGatewayId(gatewayId);
      args.setApplicationInterface(applicationInterface);
      sendBase("registerApplicationInterface", args);
    }

    public String recv_registerApplicationInterface() throws org.apache.airavata.model.error.InvalidRequestException, org.apache.airavata.model.error.AiravataClientException, org.apache.airavata.model.error.AiravataSystemException, org.apache.airavata.model.error.AuthorizationException, org.apache.thrift.TException
    {
      registerApplicationInterface_result result = new registerApplicationInterface_result();
      receiveBase(result, "registerApplicationInterface");
      if (result.isSetSuccess()) {
        return result.success;
      }
      if (result.ire != null) {
        throw result.ire;
      }
      if (result.ace != null) {
        throw result.ace;
      }
      if (result.ase != null) {
        throw result.ase;
      }
      if (result.ae != null) {
        throw result.ae;
      }
      throw new org.apache.thrift.TApplicationException(org.apache.thrift.TApplicationException.MISSING_RESULT, "registerApplicationInterface failed: unknown result");
    }

    public org.apache.airavata.model.appcatalog.appinterface.ApplicationInterfaceDescription getApplicationInterface(org.apache.airavata.model.security.AuthzToken authzToken, String appInterfaceId) throws org.apache.airavata.model.error.InvalidRequestException, org.apache.airavata.model.error.AiravataClientException, org.apache.airavata.model.error.AiravataSystemException, org.apache.airavata.model.error.AuthorizationException, org.apache.thrift.TException
    {
      send_getApplicationInterface(authzToken, appInterfaceId);
      return recv_getApplicationInterface();
    }

    public void send_getApplicationInterface(org.apache.airavata.model.security.AuthzToken authzToken, String appInterfaceId) throws org.apache.thrift.TException
    {
      getApplicationInterface_args args = new getApplicationInterface_args();
      args.setAuthzToken(authzToken);
      args.setAppInterfaceId(appInterfaceId);
      sendBase("getApplicationInterface", args);
    }

    public org.apache.airavata.model.appcatalog.appinterface.ApplicationInterfaceDescription recv_getApplicationInterface() throws org.apache.airavata.model.error.InvalidRequestException, org.apache.airavata.model.error.AiravataClientException, org.apache.airavata.model.error.AiravataSystemException, org.apache.airavata.model.error.AuthorizationException, org.apache.thrift.TException
    {
      getApplicationInterface_result result = new getApplicationInterface_result();
      receiveBase(result, "getApplicationInterface");
      if (result.isSetSuccess()) {
        return result.success;
      }
      if (result.ire != null) {
        throw result.ire;
      }
      if (result.ace != null) {
        throw result.ace;
      }
      if (result.ase != null) {
        throw result.ase;
      }
      if (result.ae != null) {
        throw result.ae;
      }
      throw new org.apache.thrift.TApplicationException(org.apache.thrift.TApplicationException.MISSING_RESULT, "getApplicationInterface failed: unknown result");
    }

    public boolean updateApplicationInterface(org.apache.airavata.model.security.AuthzToken authzToken, String appInterfaceId, org.apache.airavata.model.appcatalog.appinterface.ApplicationInterfaceDescription applicationInterface) throws org.apache.airavata.model.error.InvalidRequestException, org.apache.airavata.model.error.AiravataClientException, org.apache.airavata.model.error.AiravataSystemException, org.apache.airavata.model.error.AuthorizationException, org.apache.thrift.TException
    {
      send_updateApplicationInterface(authzToken, appInterfaceId, applicationInterface);
      return recv_updateApplicationInterface();
    }

    public void send_updateApplicationInterface(org.apache.airavata.model.security.AuthzToken authzToken, String appInterfaceId, org.apache.airavata.model.appcatalog.appinterface.ApplicationInterfaceDescription applicationInterface) throws org.apache.thrift.TException
    {
      updateApplicationInterface_args args = new updateApplicationInterface_args();
      args.setAuthzToken(authzToken);
      args.setAppInterfaceId(appInterfaceId);
      args.setApplicationInterface(applicationInterface);
      sendBase("updateApplicationInterface", args);
    }

    public boolean recv_updateApplicationInterface() throws org.apache.airavata.model.error.InvalidRequestException, org.apache.airavata.model.error.AiravataClientException, org.apache.airavata.model.error.AiravataSystemException, org.apache.airavata.model.error.AuthorizationException, org.apache.thrift.TException
    {
      updateApplicationInterface_result result = new updateApplicationInterface_result();
      receiveBase(result, "updateApplicationInterface");
      if (result.isSetSuccess()) {
        return result.success;
      }
      if (result.ire != null) {
        throw result.ire;
      }
      if (result.ace != null) {
        throw result.ace;
      }
      if (result.ase != null) {
        throw result.ase;
      }
      if (result.ae != null) {
        throw result.ae;
      }
      throw new org.apache.thrift.TApplicationException(org.apache.thrift.TApplicationException.MISSING_RESULT, "updateApplicationInterface failed: unknown result");
    }

    public boolean deleteApplicationInterface(org.apache.airavata.model.security.AuthzToken authzToken, String appInterfaceId) throws org.apache.airavata.model.error.InvalidRequestException, org.apache.airavata.model.error.AiravataClientException, org.apache.airavata.model.error.AiravataSystemException, org.apache.airavata.model.error.AuthorizationException, org.apache.thrift.TException
    {
      send_deleteApplicationInterface(authzToken, appInterfaceId);
      return recv_deleteApplicationInterface();
    }

    public void send_deleteApplicationInterface(org.apache.airavata.model.security.AuthzToken authzToken, String appInterfaceId) throws org.apache.thrift.TException
    {
      deleteApplicationInterface_args args = new deleteApplicationInterface_args();
      args.setAuthzToken(authzToken);
      args.setAppInterfaceId(appInterfaceId);
      sendBase("deleteApplicationInterface", args);
    }

    public boolean recv_deleteApplicationInterface() throws org.apache.airavata.model.error.InvalidRequestException, org.apache.airavata.model.error.AiravataClientException, org.apache.airavata.model.error.AiravataSystemException, org.apache.airavata.model.error.AuthorizationException, org.apache.thrift.TException
    {
      deleteApplicationInterface_result result = new deleteApplicationInterface_result();
      receiveBase(result, "deleteApplicationInterface");
      if (result.isSetSuccess()) {
        return result.success;
      }
      if (result.ire != null) {
        throw result.ire;
      }
      if (result.ace != null) {
        throw result.ace;
      }
      if (result.ase != null) {
        throw result.ase;
      }
      if (result.ae != null) {
        throw result.ae;
      }
      throw new org.apache.thrift.TApplicationException(org.apache.thrift.TApplicationException.MISSING_RESULT, "deleteApplicationInterface failed: unknown result");
    }

    public Map<String,String> getAllApplicationInterfaceNames(org.apache.airavata.model.security.AuthzToken authzToken, String gatewayId) throws org.apache.airavata.model.error.InvalidRequestException, org.apache.airavata.model.error.AiravataClientException, org.apache.airavata.model.error.AiravataSystemException, org.apache.airavata.model.error.AuthorizationException, org.apache.thrift.TException
    {
      send_getAllApplicationInterfaceNames(authzToken, gatewayId);
      return recv_getAllApplicationInterfaceNames();
    }

    public void send_getAllApplicationInterfaceNames(org.apache.airavata.model.security.AuthzToken authzToken, String gatewayId) throws org.apache.thrift.TException
    {
      getAllApplicationInterfaceNames_args args = new getAllApplicationInterfaceNames_args();
      args.setAuthzToken(authzToken);
      args.setGatewayId(gatewayId);
      sendBase("getAllApplicationInterfaceNames", args);
    }

    public Map<String,String> recv_getAllApplicationInterfaceNames() throws org.apache.airavata.model.error.InvalidRequestException, org.apache.airavata.model.error.AiravataClientException, org.apache.airavata.model.error.AiravataSystemException, org.apache.airavata.model.error.AuthorizationException, org.apache.thrift.TException
    {
      getAllApplicationInterfaceNames_result result = new getAllApplicationInterfaceNames_result();
      receiveBase(result, "getAllApplicationInterfaceNames");
      if (result.isSetSuccess()) {
        return result.success;
      }
      if (result.ire != null) {
        throw result.ire;
      }
      if (result.ace != null) {
        throw result.ace;
      }
      if (result.ase != null) {
        throw result.ase;
      }
      if (result.ae != null) {
        throw result.ae;
      }
      throw new org.apache.thrift.TApplicationException(org.apache.thrift.TApplicationException.MISSING_RESULT, "getAllApplicationInterfaceNames failed: unknown result");
    }

    public List<org.apache.airavata.model.appcatalog.appinterface.ApplicationInterfaceDescription> getAllApplicationInterfaces(org.apache.airavata.model.security.AuthzToken authzToken, String gatewayId) throws org.apache.airavata.model.error.InvalidRequestException, org.apache.airavata.model.error.AiravataClientException, org.apache.airavata.model.error.AiravataSystemException, org.apache.airavata.model.error.AuthorizationException, org.apache.thrift.TException
    {
      send_getAllApplicationInterfaces(authzToken, gatewayId);
      return recv_getAllApplicationInterfaces();
    }

    public void send_getAllApplicationInterfaces(org.apache.airavata.model.security.AuthzToken authzToken, String gatewayId) throws org.apache.thrift.TException
    {
      getAllApplicationInterfaces_args args = new getAllApplicationInterfaces_args();
      args.setAuthzToken(authzToken);
      args.setGatewayId(gatewayId);
      sendBase("getAllApplicationInterfaces", args);
    }

    public List<org.apache.airavata.model.appcatalog.appinterface.ApplicationInterfaceDescription> recv_getAllApplicationInterfaces() throws org.apache.airavata.model.error.InvalidRequestException, org.apache.airavata.model.error.AiravataClientException, org.apache.airavata.model.error.AiravataSystemException, org.apache.airavata.model.error.AuthorizationException, org.apache.thrift.TException
    {
      getAllApplicationInterfaces_result result = new getAllApplicationInterfaces_result();
      receiveBase(result, "getAllApplicationInterfaces");
      if (result.isSetSuccess()) {
        return result.success;
      }
      if (result.ire != null) {
        throw result.ire;
      }
      if (result.ace != null) {
        throw result.ace;
      }
      if (result.ase != null) {
        throw result.ase;
      }
      if (result.ae != null) {
        throw result.ae;
      }
      throw new org.apache.thrift.TApplicationException(org.apache.thrift.TApplicationException.MISSING_RESULT, "getAllApplicationInterfaces failed: unknown result");
    }

    public List<org.apache.airavata.model.application.io.InputDataObjectType> getApplicationInputs(org.apache.airavata.model.security.AuthzToken authzToken, String appInterfaceId) throws org.apache.airavata.model.error.InvalidRequestException, org.apache.airavata.model.error.AiravataClientException, org.apache.airavata.model.error.AiravataSystemException, org.apache.airavata.model.error.AuthorizationException, org.apache.thrift.TException
    {
      send_getApplicationInputs(authzToken, appInterfaceId);
      return recv_getApplicationInputs();
    }

    public void send_getApplicationInputs(org.apache.airavata.model.security.AuthzToken authzToken, String appInterfaceId) throws org.apache.thrift.TException
    {
      getApplicationInputs_args args = new getApplicationInputs_args();
      args.setAuthzToken(authzToken);
      args.setAppInterfaceId(appInterfaceId);
      sendBase("getApplicationInputs", args);
    }

    public List<org.apache.airavata.model.application.io.InputDataObjectType> recv_getApplicationInputs() throws org.apache.airavata.model.error.InvalidRequestException, org.apache.airavata.model.error.AiravataClientException, org.apache.airavata.model.error.AiravataSystemException, org.apache.airavata.model.error.AuthorizationException, org.apache.thrift.TException
    {
      getApplicationInputs_result result = new getApplicationInputs_result();
      receiveBase(result, "getApplicationInputs");
      if (result.isSetSuccess()) {
        return result.success;
      }
      if (result.ire != null) {
        throw result.ire;
      }
      if (result.ace != null) {
        throw result.ace;
      }
      if (result.ase != null) {
        throw result.ase;
      }
      if (result.ae != null) {
        throw result.ae;
      }
      throw new org.apache.thrift.TApplicationException(org.apache.thrift.TApplicationException.MISSING_RESULT, "getApplicationInputs failed: unknown result");
    }

    public List<org.apache.airavata.model.application.io.OutputDataObjectType> getApplicationOutputs(org.apache.airavata.model.security.AuthzToken authzToken, String appInterfaceId) throws org.apache.airavata.model.error.InvalidRequestException, org.apache.airavata.model.error.AiravataClientException, org.apache.airavata.model.error.AiravataSystemException, org.apache.airavata.model.error.AuthorizationException, org.apache.thrift.TException
    {
      send_getApplicationOutputs(authzToken, appInterfaceId);
      return recv_getApplicationOutputs();
    }

    public void send_getApplicationOutputs(org.apache.airavata.model.security.AuthzToken authzToken, String appInterfaceId) throws org.apache.thrift.TException
    {
      getApplicationOutputs_args args = new getApplicationOutputs_args();
      args.setAuthzToken(authzToken);
      args.setAppInterfaceId(appInterfaceId);
      sendBase("getApplicationOutputs", args);
    }

    public List<org.apache.airavata.model.application.io.OutputDataObjectType> recv_getApplicationOutputs() throws org.apache.airavata.model.error.InvalidRequestException, org.apache.airavata.model.error.AiravataClientException, org.apache.airavata.model.error.AiravataSystemException, org.apache.airavata.model.error.AuthorizationException, org.apache.thrift.TException
    {
      getApplicationOutputs_result result = new getApplicationOutputs_result();
      receiveBase(result, "getApplicationOutputs");
      if (result.isSetSuccess()) {
        return result.success;
      }
      if (result.ire != null) {
        throw result.ire;
      }
      if (result.ace != null) {
        throw result.ace;
      }
      if (result.ase != null) {
        throw result.ase;
      }
      if (result.ae != null) {
        throw result.ae;
      }
      throw new org.apache.thrift.TApplicationException(org.apache.thrift.TApplicationException.MISSING_RESULT, "getApplicationOutputs failed: unknown result");
    }

    public Map<String,String> getAvailableAppInterfaceComputeResources(org.apache.airavata.model.security.AuthzToken authzToken, String appInterfaceId) throws org.apache.airavata.model.error.InvalidRequestException, org.apache.airavata.model.error.AiravataClientException, org.apache.airavata.model.error.AiravataSystemException, org.apache.airavata.model.error.AuthorizationException, org.apache.thrift.TException
    {
      send_getAvailableAppInterfaceComputeResources(authzToken, appInterfaceId);
      return recv_getAvailableAppInterfaceComputeResources();
    }

    public void send_getAvailableAppInterfaceComputeResources(org.apache.airavata.model.security.AuthzToken authzToken, String appInterfaceId) throws org.apache.thrift.TException
    {
      getAvailableAppInterfaceComputeResources_args args = new getAvailableAppInterfaceComputeResources_args();
      args.setAuthzToken(authzToken);
      args.setAppInterfaceId(appInterfaceId);
      sendBase("getAvailableAppInterfaceComputeResources", args);
    }

    public Map<String,String> recv_getAvailableAppInterfaceComputeResources() throws org.apache.airavata.model.error.InvalidRequestException, org.apache.airavata.model.error.AiravataClientException, org.apache.airavata.model.error.AiravataSystemException, org.apache.airavata.model.error.AuthorizationException, org.apache.thrift.TException
    {
      getAvailableAppInterfaceComputeResources_result result = new getAvailableAppInterfaceComputeResources_result();
      receiveBase(result, "getAvailableAppInterfaceComputeResources");
      if (result.isSetSuccess()) {
        return result.success;
      }
      if (result.ire != null) {
        throw result.ire;
      }
      if (result.ace != null) {
        throw result.ace;
      }
      if (result.ase != null) {
        throw result.ase;
      }
      if (result.ae != null) {
        throw result.ae;
      }
      throw new org.apache.thrift.TApplicationException(org.apache.thrift.TApplicationException.MISSING_RESULT, "getAvailableAppInterfaceComputeResources failed: unknown result");
    }

    public String registerComputeResource(org.apache.airavata.model.security.AuthzToken authzToken, org.apache.airavata.model.appcatalog.computeresource.ComputeResourceDescription computeResourceDescription) throws org.apache.airavata.model.error.InvalidRequestException, org.apache.airavata.model.error.AiravataClientException, org.apache.airavata.model.error.AiravataSystemException, org.apache.airavata.model.error.AuthorizationException, org.apache.thrift.TException
    {
      send_registerComputeResource(authzToken, computeResourceDescription);
      return recv_registerComputeResource();
    }

    public void send_registerComputeResource(org.apache.airavata.model.security.AuthzToken authzToken, org.apache.airavata.model.appcatalog.computeresource.ComputeResourceDescription computeResourceDescription) throws org.apache.thrift.TException
    {
      registerComputeResource_args args = new registerComputeResource_args();
      args.setAuthzToken(authzToken);
      args.setComputeResourceDescription(computeResourceDescription);
      sendBase("registerComputeResource", args);
    }

    public String recv_registerComputeResource() throws org.apache.airavata.model.error.InvalidRequestException, org.apache.airavata.model.error.AiravataClientException, org.apache.airavata.model.error.AiravataSystemException, org.apache.airavata.model.error.AuthorizationException, org.apache.thrift.TException
    {
      registerComputeResource_result result = new registerComputeResource_result();
      receiveBase(result, "registerComputeResource");
      if (result.isSetSuccess()) {
        return result.success;
      }
      if (result.ire != null) {
        throw result.ire;
      }
      if (result.ace != null) {
        throw result.ace;
      }
      if (result.ase != null) {
        throw result.ase;
      }
      if (result.ae != null) {
        throw result.ae;
      }
      throw new org.apache.thrift.TApplicationException(org.apache.thrift.TApplicationException.MISSING_RESULT, "registerComputeResource failed: unknown result");
    }

    public org.apache.airavata.model.appcatalog.computeresource.ComputeResourceDescription getComputeResource(org.apache.airavata.model.security.AuthzToken authzToken, String computeResourceId) throws org.apache.airavata.model.error.InvalidRequestException, org.apache.airavata.model.error.AiravataClientException, org.apache.airavata.model.error.AiravataSystemException, org.apache.airavata.model.error.AuthorizationException, org.apache.thrift.TException
    {
      send_getComputeResource(authzToken, computeResourceId);
      return recv_getComputeResource();
    }

    public void send_getComputeResource(org.apache.airavata.model.security.AuthzToken authzToken, String computeResourceId) throws org.apache.thrift.TException
    {
      getComputeResource_args args = new getComputeResource_args();
      args.setAuthzToken(authzToken);
      args.setComputeResourceId(computeResourceId);
      sendBase("getComputeResource", args);
    }

    public org.apache.airavata.model.appcatalog.computeresource.ComputeResourceDescription recv_getComputeResource() throws org.apache.airavata.model.error.InvalidRequestException, org.apache.airavata.model.error.AiravataClientException, org.apache.airavata.model.error.AiravataSystemException, org.apache.airavata.model.error.AuthorizationException, org.apache.thrift.TException
    {
      getComputeResource_result result = new getComputeResource_result();
      receiveBase(result, "getComputeResource");
      if (result.isSetSuccess()) {
        return result.success;
      }
      if (result.ire != null) {
        throw result.ire;
      }
      if (result.ace != null) {
        throw result.ace;
      }
      if (result.ase != null) {
        throw result.ase;
      }
      if (result.ae != null) {
        throw result.ae;
      }
      throw new org.apache.thrift.TApplicationException(org.apache.thrift.TApplicationException.MISSING_RESULT, "getComputeResource failed: unknown result");
    }

    public Map<String,String> getAllComputeResourceNames(org.apache.airavata.model.security.AuthzToken authzToken) throws org.apache.airavata.model.error.InvalidRequestException, org.apache.airavata.model.error.AiravataClientException, org.apache.airavata.model.error.AiravataSystemException, org.apache.airavata.model.error.AuthorizationException, org.apache.thrift.TException
    {
      send_getAllComputeResourceNames(authzToken);
      return recv_getAllComputeResourceNames();
    }

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

    public Map<String,String> recv_getAllComputeResourceNames() throws org.apache.airavata.model.error.InvalidRequestException, org.apache.airavata.model.error.AiravataClientException, org.apache.airavata.model.error.AiravataSystemException, org.apache.airavata.model.error.AuthorizationException, org.apache.thrift.TException
    {
      getAllComputeResourceNames_result result = new getAllComputeResourceNames_result();
      receiveBase(result, "getAllComputeResourceNames");
      if (result.isSetSuccess()) {
        return result.success;
      }
      if (result.ire != null) {
        throw result.ire;
      }
      if (result.ace != null) {
        throw result.ace;
      }
      if (result.ase != null) {
        throw result.ase;
      }
      if (result.ae != null) {
        throw result.ae;
      }
      throw new org.apache.thrift.TApplicationException(org.apache.thrift.TApplicationException.MISSING_RESULT, "getAllComputeResourceNames failed: unknown result");
    }

    public boolean updateComputeResource(org.apache.airavata.model.security.AuthzToken authzToken, String computeResourceId, org.apache.airavata.model.appcatalog.computeresource.ComputeResourceDescription computeResourceDescription) throws org.apache.airavata.model.error.InvalidRequestException, org.apache.airavata.model.error.AiravataClientException, org.apache.airavata.model.error.AiravataSystemException, org.apache.airavata.model.error.AuthorizationException, org.apache.thrift.TException
    {
      send_updateComputeResource(authzToken, computeResourceId, computeResourceDescription);
      return recv_updateComputeResource();
    }

    public void send_updateComputeResource(org.apache.airavata.model.security.AuthzToken authzToken, String computeResourceId, org.apache.airavata.model.appcatalog.computeresource.ComputeResourceDescription computeResourceDescription) throws org.apache.thrift.TException
    {
      updateComputeResource_args args = new updateComputeResource_args();
      args.setAuthzToken(authzToken);
      args.setComputeResourceId(computeResourceId);
      args.setComputeResourceDescription(computeResourceDescription);
      sendBase("updateComputeResource", args);
    }

    public boolean recv_updateComputeResource() throws org.apache.airavata.model.error.InvalidRequestException, org.apache.airavata.model.error.AiravataClientException, org.apache.airavata.model.error.AiravataSystemException, org.apache.airavata.model.error.AuthorizationException, org.apache.thrift.TException
    {
      updateComputeResource_result result = new updateComputeResource_result();
      receiveBase(result, "updateComputeResource");
      if (result.isSetSuccess()) {
        return result.success;
      }
      if (result.ire != null) {
        throw result.ire;
      }
      if (result.ace != null) {
        throw result.ace;
      }
      if (result.ase != null) {
        throw result.ase;
      }
      if (result.ae != null) {
        throw result.ae;
      }
      throw new org.apache.thrift.TApplicationException(org.apache.thrift.TApplicationException.MISSING_RESULT, "updateComputeResource failed: unknown result");
    }

    public boolean deleteComputeResource(org.apache.airavata.model.security.AuthzToken authzToken, String computeResourceId) throws org.apache.airavata.model.error.InvalidRequestException, org.apache.airavata.model.error.AiravataClientException, org.apache.airavata.model.error.AiravataSystemException, org.apache.airavata.model.error.AuthorizationException, org.apache.thrift.TException
    {
      send_deleteComputeResource(authzToken, computeResourceId);
      return recv_deleteComputeResource();
    }

    public void send_deleteComputeResource(org.apache.airavata.model.security.AuthzToken authzToken, String computeResourceId) throws org.apache.thrift.TException
    {
      deleteComputeResource_args args = new deleteComputeResource_args();
      args.setAuthzToken(authzToken);
      args.setComputeResourceId(computeResourceId);
      sendBase("deleteComputeResource", args);
    }

    public boolean recv_deleteComputeResource() throws org.apache.airavata.model.error.InvalidRequestException, org.apache.airavata.model.error.AiravataClientException, org.apache.airavata.model.error.AiravataSystemException, org.apache.airavata.model.error.AuthorizationException, org.apache.thrift.TException
    {
      deleteComputeResource_result result = new deleteComputeResource_result();
      receiveBase(result, "deleteComputeResource");
      if (result.isSetSuccess()) {
        return result.success;
      }
      if (result.ire != null) {
        throw result.ire;
      }
      if (result.ace != null) {
        throw result.ace;
      }
      if (result.ase != null) {
        throw result.ase;
      }
      if (result.ae != null) {
        throw result.ae;
      }
      throw new org.apache.thrift.TApplicationException(org.apache.thrift.TApplicationException.MISSING_RESULT, "deleteComputeResource failed: unknown result");
    }

    public String addLocalSubmissionDetails(org.apache.airavata.model.security.AuthzToken authzToken, String computeResourceId, int priorityOrder, org.apache.airavata.model.appcatalog.computeresource.LOCALSubmission localSubmission) throws org.apache.airavata.model.error.InvalidRequestException, org.apache.airavata.model.error.AiravataClientException, org.apache.airavata.model.error.AiravataSystemException, org.apache.airavata.model.error.AuthorizationException, org.apache.thrift.TException
    {
      send_addLocalSubmissionDetails(authzToken, computeResourceId, priorityOrder, localSubmission);
      return recv_addLocalSubmissionDetails();
    }

    public void send_addLocalSubmissionDetails(org.apache.airavata.model.security.AuthzToken authzToken, String computeResourceId, int priorityOrder, org.apache.airavata.model.appcatalog.computeresource.LOCALSubmission localSubmission) throws org.apache.thrift.TException
    {
      addLocalSubmissionDetails_args args = new addLocalSubmissionDetails_args();
      args.setAuthzToken(authzToken);
      args.setComputeResourceId(computeResourceId);
      args.setPriorityOrder(priorityOrder);
      args.setLocalSubmission(localSubmission);
      sendBase("addLocalSubmissionDetails", args);
    }

    public String recv_addLocalSubmissionDetails() throws org.apache.airavata.model.error.InvalidRequestException, org.apache.airavata.model.error.AiravataClientException, org.apache.airavata.model.error.AiravataSystemException, org.apache.airavata.model.error.AuthorizationException, org.apache.thrift.TException
    {
      addLocalSubmissionDetails_result result = new addLocalSubmissionDetails_result();
      receiveBase(result, "addLocalSubmissionDetails");
      if (result.isSetSuccess()) {
        return result.success;
      }
      if (result.ire != null) {
        throw result.ire;
      }
      if (result.ace != null) {
        throw result.ace;
      }
      if (result.ase != null) {
        throw result.ase;
      }
      if (result.ae != null) {
        throw result.ae;
      }
      throw new org.apache.thrift.TApplicationException(org.apache.thrift.TApplicationException.MISSING_RESULT, "addLocalSubmissionDetails failed: unknown result");
    }

    public boolean updateLocalSubmissionDetails(org.apache.airavata.model.security.AuthzToken authzToken, String jobSubmissionInterfaceId, org.apache.airavata.model.appcatalog.computeresource.LOCALSubmission localSubmission) throws org.apache.airavata.model.error.InvalidRequestException, org.apache.airavata.model.error.AiravataClientException, org.apache.airavata.model.error.AiravataSystemException, org.apache.airavata.model.error.AuthorizationException, org.apache.thrift.TException
    {
      send_updateLocalSubmissionDetails(authzToken, jobSubmissionInterfaceId, localSubmission);
      return recv_updateLocalSubmissionDetails();
    }

    public void send_updateLocalSubmissionDetails(org.apache.airavata.model.security.AuthzToken authzToken, String jobSubmissionInterfaceId, org.apache.airavata.model.appcatalog.computeresource.LOCALSubmission localSubmission) throws org.apache.thrift.TException
    {
      updateLocalSubmissionDetails_args args = new updateLocalSubmissionDetails_args();
      args.setAuthzToken(authzToken);
      args.setJobSubmissionInterfaceId(jobSubmissionInterfaceId);
      args.setLocalSubmission(localSubmission);
      sendBase("updateLocalSubmissionDetails", args);
    }

    public boolean recv_updateLocalSubmissionDetails() throws org.apache.airavata.model.error.InvalidRequestException, org.apache.airavata.model.error.AiravataClientException, org.apache.airavata.model.error.AiravataSystemException, org.apache.airavata.model.error.AuthorizationException, org.apache.thrift.TException
    {
      updateLocalSubmissionDetails_result result = new updateLocalSubmissionDetails_result();
      receiveBase(result, "updateLocalSubmissionDetails");
      if (result.isSetSuccess()) {
        return result.success;
      }
      if (result.ire != null) {
        throw result.ire;
      }
      if (result.ace != null) {
        throw result.ace;
      }
      if (result.ase != null) {
        throw result.ase;
      }
      if (result.ae != null) {
        throw result.ae;
      }
      throw new org.apache.thrift.TApplicationException(org.apache.thrift.TApplicationException.MISSING_RESULT, "updateLocalSubmissionDetails failed: unknown result");
    }

    public org.apache.airavata.model.appcatalog.computeresource.LOCALSubmission getLocalJobSubmission(org.apache.airavata.model.security.AuthzToken authzToken, String jobSubmissionId) throws org.apache.airavata.model.error.InvalidRequestException, org.apache.airavata.model.error.AiravataClientException, org.apache.airavata.model.error.AiravataSystemException, org.apache.airavata.model.error.AuthorizationException, org.apache.thrift.TException
    {
      send_getLocalJobSubmission(authzToken, jobSubmissionId);
      return recv_getLocalJobSubmission();
    }

    public void send_getLocalJobSubmission(org.apache.airavata.model.security.AuthzToken authzToken, String jobSubmissionId) throws org.apache.thrift.TException
    {
      getLocalJobSubmission_args args = new getLocalJobSubmission_args();
      args.setAuthzToken(authzToken);
      args.setJobSubmissionId(jobSubmissionId);
      sendBase("getLocalJobSubmission", args);
    }

    public org.apache.airavata.model.appcatalog.computeresource.LOCALSubmission recv_getLocalJobSubmission() throws org.apache.airavata.model.error.InvalidRequestException, org.apache.airavata.model.error.AiravataClientException, org.apache.airavata.model.error.AiravataSystemException, org.apache.airavata.model.error.AuthorizationException, org.apache.thrift.TException
    {
      getLocalJobSubmission_result result = new getLocalJobSubmission_result();
      receiveBase(result, "getLocalJobSubmission");
      if (result.isSetSuccess()) {
        return result.success;
      }
      if (result.ire != null) {
        throw result.ire;
      }
      if (result.ace != null) {
        throw result.ace;
      }
      if (result.ase != null) {
        throw result.ase;
      }
      if (result.ae != null) {
        throw result.ae;
      }
      throw new org.apache.thrift.TApplicationException(org.apache.thrift.TApplicationException.MISSING_RESULT, "getLocalJobSubmission failed: unknown result");
    }

    public String addSSHJobSubmissionDetails(org.apache.airavata.model.security.AuthzToken authzToken, String computeResourceId, int priorityOrder, org.apache.airavata.model.appcatalog.computeresource.SSHJobSubmission sshJobSubmission) throws org.apache.airavata.model.error.InvalidRequestException, org.apache.airavata.model.error.AiravataClientException, org.apache.airavata.model.error.AiravataSystemException, org.apache.airavata.model.error.AuthorizationException, org.apache.thrift.TException
    {
      send_addSSHJobSubmissionDetails(authzToken, computeResourceId, priorityOrder, sshJobSubmission);
      return recv_addSSHJobSubmissionDetails();
    }

    public void send_addSSHJobSubmissionDetails(org.apache.airavata.model.security.AuthzToken authzToken, String computeResourceId, int priorityOrder, org.apache.airavata.model.appcatalog.computeresource.SSHJobSubmission sshJobSubmission) throws org.apache.thrift.TException
    {
      addSSHJobSubmissionDetails_args args = new addSSHJobSubmissionDetails_args();
      args.setAuthzToken(authzToken);
      args.setComputeResourceId(computeResourceId);
      args.setPriorityOrder(priorityOrder);
      args.setSshJobSubmission(sshJobSubmission);
      sendBase("addSSHJobSubmissionDetails", args);
    }

    public String recv_addSSHJobSubmissionDetails() throws org.apache.airavata.model.error.InvalidRequestException, org.apache.airavata.model.error.AiravataClientException, org.apache.airavata.model.error.AiravataSystemException, org.apache.airavata.model.error.AuthorizationException, org.apache.thrift.TException
    {
      addSSHJobSubmissionDetails_result result = new addSSHJobSubmissionDetails_result();
      receiveBase(result, "addSSHJobSubmissionDetails");
      if (result.isSetSuccess()) {
        return result.success;
      }
      if (result.ire != null) {
        throw result.ire;
      }
      if (result.ace != null) {
        throw result.ace;
      }
      if (result.ase != null) {
        throw result.ase;
      }
      if (result.ae != null) {
        throw result.ae;
      }
      throw new org.apache.thrift.TApplicationException(org.apache.thrift.TApplicationException.MISSING_RESULT, "addSSHJobSubmissionDetails failed: unknown result");
    }

    public String addSSHForkJobSubmissionDetails(org.apache.airavata.model.security.AuthzToken authzToken, String computeResourceId, int priorityOrder, org.apache.airavata.model.appcatalog.computeresource.SSHJobSubmission sshJobSubmission) throws org.apache.airavata.model.error.InvalidRequestException, org.apache.airavata.model.error.AiravataClientException, org.apache.airavata.model.error.AiravataSystemException, org.apache.airavata.model.error.AuthorizationException, org.apache.thrift.TException
    {
      send_addSSHForkJobSubmissionDetails(authzToken, computeResourceId, priorityOrder, sshJobSubmission);
      return recv_addSSHForkJobSubmissionDetails();
    }

    public void send_addSSHForkJobSubmissionDetails(org.apache.airavata.model.security.AuthzToken authzToken, String computeResourceId, int priorityOrder, org.apache.airavata.model.appcatalog.computeresource.SSHJobSubmission sshJobSubmission) throws org.apache.thrift.TException
    {
      addSSHForkJobSubmissionDetails_args args = new addSSHForkJobSubmissionDetails_args();
      args.setAuthzToken(authzToken);
      args.setComputeResourceId(computeResourceId);
      args.setPriorityOrder(priorityOrder);
      args.setSshJobSubmission(sshJobSubmission);
      sendBase("addSSHForkJobSubmissionDetails", args);
    }

    public String recv_addSSHForkJobSubmissionDetails() throws org.apache.airavata.model.error.InvalidRequestException, org.apache.airavata.model.error.AiravataClientException, org.apache.airavata.model.error.AiravataSystemException, org.apache.airavata.model.error.AuthorizationException, org.apache.thrift.TException
    {
      addSSHForkJobSubmissionDetails_result result = new addSSHForkJobSubmissionDetails_result();
      receiveBase(result, "addSSHForkJobSubmissionDetails");
      if (result.isSetSuccess()) {
        return result.success;
      }
      if (result.ire != null) {
        throw result.ire;
      }
      if (result.ace != null) {
        throw result.ace;
      }
      if (result.ase != null) {
        throw result.ase;
      }
      if (result.ae != null) {
        throw result.ae;
      }
      throw new org.apache.thrift.TApplicationException(org.apache.thrift.TApplicationException.MISSING_RESULT, "addSSHForkJobSubmissionDetails failed: unknown result");
    }

    public org.apache.airavata.model.appcatalog.computeresource.SSHJobSubmission getSSHJobSubmission(org.apache.airavata.model.security.AuthzToken authzToken, String jobSubmissionId) throws org.apache.airavata.model.error.InvalidRequestException, org.apache.airavata.model.error.AiravataClientException, org.apache.airavata.model.error.AiravataSystemException, org.apache.airavata.model.error.AuthorizationException, org.apache.thrift.TException
    {
      send_getSSHJobSubmission(authzToken, jobSubmissionId);
      return recv_getSSHJobSubmission();
    }

    public void send_getSSHJobSubmission(org.apache.airavata.model.security.AuthzToken authzToken, String jobSubmissionId) throws org.apache.thrift.TException
    {
      getSSHJobSubmission_args args = new getSSHJobSubmission_args();
      args.setAuthzToken(authzToken);
      args.setJobSubmissionId(jobSubmissionId);
      sendBase("getSSHJobSubmission", args);
    }

    public org.apache.airavata.model.appcatalog.computeresource.SSHJobSubmission recv_getSSHJobSubmission() throws org.apache.airavata.model.error.InvalidRequestException, org.apache.airavata.model.error.AiravataClientException, org.apache.airavata.model.error.AiravataSystemException, org.apache.airavata.model.error.AuthorizationException, org.apache.thrift.TException
    {
      getSSHJobSubmission_result result = new getSSHJobSubmission_result();
      receiveBase(result, "getSSHJobSubmission");
      if (result.isSetSuccess()) {
        return result.success;
      }
      if (result.ire != null) {
        throw result.ire;
      }
      if (result.ace != null) {
        throw result.ace;
      }
      if (result.ase != null) {
        throw result.ase;
      }
      if (result.ae != null) {
        throw result.ae;
      }
      throw new org.apache.thrift.TApplicationException(org.apache.thrift.TApplicationException.MISSING_RESULT, "getSSHJobSubmission failed: unknown result");
    }

    public String addUNICOREJobSubmissionDetails(org.apache.airavata.model.security.AuthzToken authzToken, String computeResourceId, int priorityOrder, org.apache.airavata.model.appcatalog.computeresource.UnicoreJobSubmission unicoreJobSubmission) throws org.apache.airavata.model.error.InvalidRequestException, org.apache.airavata.model.error.AiravataClientException, org.apache.airavata.model.error.AiravataSystemException, org.apache.airavata.model.error.AuthorizationException, org.apache.thrift.TException
    {
      send_addUNICOREJobSubmissionDetails(authzToken, computeResourceId, priorityOrder, unicoreJobSubmission);
      return recv_addUNICOREJobSubmissionDetails();
    }

    public void send_addUNICOREJobSubmissionDetails(org.apache.airavata.model.security.AuthzToken authzToken, String computeResourceId, int priorityOrder, org.apache.airavata.model.appcatalog.computeresource.UnicoreJobSubmission unicoreJobSubmission) throws org.apache.thrift.TException
    {
      addUNICOREJobSubmissionDetails_args args = new addUNICOREJobSubmissionDetails_args();
      args.setAuthzToken(authzToken);
      args.setComputeResourceId(computeResourceId);
      args.setPriorityOrder(priorityOrder);
      args.setUnicoreJobSubmission(unicoreJobSubmission);
      sendBase("addUNICOREJobSubmissionDetails", args);
    }

    public String recv_addUNICOREJobSubmissionDetails() throws org.apache.airavata.model.error.InvalidRequestException, org.apache.airavata.model.error.AiravataClientException, org.apache.airavata.model.error.AiravataSystemException, org.apache.airavata.model.error.AuthorizationException, org.apache.thrift.TException
    {
      addUNICOREJobSubmissionDetails_result result = new addUNICOREJobSubmissionDetails_result();
      receiveBase(result, "addUNICOREJobSubmissionDetails");
      if (result.isSetSuccess()) {
        return result.success;
      }
      if (result.ire != null) {
        throw result.ire;
      }
      if (result.ace != null) {
        throw result.ace;
      }
      if (result.ase != null) {
        throw result.ase;
      }
      if (result.ae != null) {
        throw result.ae;
      }
      throw new org.apache.thrift.TApplicationException(org.apache.thrift.TApplicationException.MISSING_RESULT, "addUNICOREJobSubmissionDetails failed: unknown result");
    }

    public org.apache.airavata.model.appcatalog.computeresource.UnicoreJobSubmission getUnicoreJobSubmission(org.apache.airavata.model.security.AuthzToken authzToken, String jobSubmissionId) throws org.apache.airavata.model.error.InvalidRequestException, org.apache.airavata.model.error.AiravataClientException, org.apache.airavata.model.error.AiravataSystemException, org.apache.airavata.model.error.AuthorizationException, org.apache.thrift.TException
    {
      send_getUnicoreJobSubmission(authzToken, jobSubmissionId);
      return recv_getUnicoreJobSubmission();
    }

    public void send_getUnicoreJobSubmission(org.apache.airavata.model.security.AuthzToken authzToken, String jobSubmissionId) throws org.apache.thrift.TException
    {
      getUnicoreJobSubmission_args args = new getUnicoreJobSubmission_args();
      args.setAuthzToken(authzToken);
      args.setJobSubmissionId(jobSubmissionId);
      sendBase("getUnicoreJobSubmission", args);
    }

    public org.apache.airavata.model.appcatalog.computeresource.UnicoreJobSubmission recv_getUnicoreJobSubmission() throws org.apache.airavata.model.error.InvalidRequestException, org.apache.airavata.model.error.AiravataClientException, org.apache.airavata.model.error.AiravataSystemException, org.apache.airavata.model.error.AuthorizationException, org.apache.thrift.TException
    {
      getUnicoreJobSubmission_result result = new getUnicoreJobSubmission_result();
      receiveBase(result, "getUnicoreJobSubmission");
      if (result.isSetSuccess()) {
        return result.success;
      }
      if (result.ire != null) {
        throw result.ire;
      }
      if (result.ace != null) {
        throw result.ace;
      }
      if (result.ase != null) {
        throw result.ase;
      }
      if (result.ae != null) {
        throw result.ae;
      }
      throw new org.apache.thrift.TApplicationException(org.apache.thrift.TApplicationException.MISSING_RESULT, "getUnicoreJobSubmission failed: unknown result");
    }

    public String addCloudJobSubmissionDetails(org.apache.airavata.model.security.AuthzToken authzToken, String computeResourceId, int priorityOrder, org.apache.airavata.model.appcatalog.computeresource.CloudJobSubmission cloudSubmission) throws org.apache.airavata.model.error.InvalidRequestException, org.apache.airavata.model.error.AiravataClientException, org.apache.airavata.model.error.AiravataSystemException, org.apache.airavata.model.error.AuthorizationException, org.apache.thrift.TException
    {
      send_addCloudJobSubmissionDetails(authzToken, computeResourceId, priorityOrder, cloudSubmission);
      return recv_addCloudJobSubmissionDetails();
    }

    public void send_addCloudJobSubmissionDetails(org.apache.airavata.model.security.AuthzToken authzToken, String computeResourceId, int priorityOrder, org.apache.airavata.model.appcatalog.computeresource.CloudJobSubmission cloudSubmission) throws org.apache.thrift.TException
    {
      addCloudJobSubmissionDetails_args args = new addCloudJobSubmissionDetails_args();
      args.setAuthzToken(authzToken);
      args.setComputeResourceId(computeResourceId);
      args.setPriorityOrder(priorityOrder);
      args.setCloudSubmission(cloudSubmission);
      sendBase("addCloudJobSubmissionDetails", args);
    }

    public String recv_addCloudJobSubmissionDetails() throws org.apache.airavata.model.error.InvalidRequestException, org.apache.airavata.model.error.AiravataClientException, org.apache.airavata.model.error.AiravataSystemException, org.apache.airavata.model.error.AuthorizationException, org.apache.thrift.TException
    {
      addCloudJobSubmissionDetails_result result = new addCloudJobSubmissionDetails_result();
      receiveBase(result, "addCloudJobSubmissionDetails");
      if (result.isSetSuccess()) {
        return result.success;
      }
      if (result.ire != null) {
        throw result.ire;
      }
      if (result.ace != null) {
        throw result.ace;
      }
      if (result.ase != null) {
        throw result.ase;
      }
      if (result.ae != null) {
        throw result.ae;
      }
      throw new org.apache.thrift.TApplicationException(org.apache.thrift.TApplicationException.MISSING_RESULT, "addCloudJobSubmissionDetails failed: unknown result");
    }

    public org.apache.airavata.model.appcatalog.computeresource.CloudJobSubmission getCloudJobSubmission(org.apache.airavata.model.security.AuthzToken authzToken, String jobSubmissionId) throws org.apache.airavata.model.error.InvalidRequestException, org.apache.airavata.model.error.AiravataClientException, org.apache.airavata.model.error.AiravataSystemException, org.apache.airavata.model.error.AuthorizationException, org.apache.thrift.TException
    {
      send_getCloudJobSubmission(authzToken, jobSubmissionId);
      return recv_getCloudJobSubmission();
    }

    public void send_getCloudJobSubmission(org.apache.airavata.model.security.AuthzToken authzToken, String jobSubmissionId) throws org.apache.thrift.TException
    {
      getCloudJobSubmission_args args = new getCloudJobSubmission_args();
      args.setAuthzToken(authzToken);
      args.setJobSubmissionId(jobSubmissionId);
      sendBase("getCloudJobSubmission", args);
    }

    public org.apache.airavata.model.appcatalog.computeresource.CloudJobSubmission recv_getCloudJobSubmission() throws org.apache.airavata.model.error.InvalidRequestException, org.apache.airavata.model.error.AiravataClientException, org.apache.airavata.model.error.AiravataSystemException, org.apache.airavata.model.error.AuthorizationException, org.apache.thrift.TException
    {
      getCloudJobSubmission_result result = new getCloudJobSubmission_result();
      receiveBase(result, "getCloudJobSubmission");
      if (result.isSetSuccess()) {
        return result.success;
      }
      if (result.ire != null) {
        throw result.ire;
      }
      if (result.ace != null) {
        throw result.ace;
      }
      if (result.ase != null) {
        throw result.ase;
      }
      if (result.ae != null) {
        throw result.ae;
      }
      throw new org.apache.thrift.TApplicationException(org.apache.thrift.TApplicationException.MISSING_RESULT, "getCloudJobSubmission failed: unknown result");
    }

    public boolean updateSSHJobSubmissionDetails(org.apache.airavata.model.security.AuthzToken authzToken, String jobSubmissionInterfaceId, org.apache.airavata.model.appcatalog.computeresource.SSHJobSubmission sshJobSubmission) throws org.apache.airavata.model.error.InvalidRequestException, org.apache.airavata.model.error.AiravataClientException, org.apache.airavata.model.error.AiravataSystemException, org.apache.airavata.model.error.AuthorizationException, org.apache.thrift.TException
    {
      send_updateSSHJobSubmissionDetails(authzToken, jobSubmissionInterfaceId, sshJobSubmission);
      return recv_updateSSHJobSubmissionDetails();
    }

    public void send_updateSSHJobSubmissionDetails(org.apache.airavata.model.security.AuthzToken authzToken, String jobSubmissionInterfaceId, org.apache.airavata.model.appcatalog.computeresource.SSHJobSubmission sshJobSubmission) throws org.apache.thrift.TException
    {
      updateSSHJobSubmissionDetails_args args = new updateSSHJobSubmissionDetails_args();
      args.setAuthzToken(authzToken);
      args.setJobSubmissionInterfaceId(jobSubmissionInterfaceId);
      args.setSshJobSubmission(sshJobSubmission);
      sendBase("updateSSHJobSubmissionDetails", args);
    }

    public boolean recv_updateSSHJobSubmissionDetails() throws org.apache.airavata.model.error.InvalidRequestException, org.apache.airavata.model.error.AiravataClientException, org.apache.airavata.model.error.AiravataSystemException, org.apache.airavata.model.error.AuthorizationException, org.apache.thrift.TException
    {
      updateSSHJobSubmissionDetails_result result = new updateSSHJobSubmissionDetails_result();
      receiveBase(result, "updateSSHJobSubmissionDetails");
      if (result.isSetSuccess()) {
        return result.success;
      }
      if (result.ire != null) {
        throw result.ire;
      }
      if (result.ace != null) {
        throw result.ace;
      }
      if (result.ase != null) {
        throw result.ase;
      }
      if (result.ae != null) {
        throw result.ae;
      }
      throw new org.apache.thrift.TApplicationException(org.apache.thrift.TApplicationException.MISSING_RESULT, "updateSSHJobSubmissionDetails failed: unknown result");
    }

    public boolean updateCloudJobSubmissionDetails(org.apache.airavata.model.security.AuthzToken authzToken, String jobSubmissionInterfaceId, org.apache.airavata.model.appcatalog.computeresource.CloudJobSubmission sshJobSubmission) throws org.apache.airavata.model.error.InvalidRequestException, org.apache.airavata.model.error.AiravataClientException, org.apache.airavata.model.error.AiravataSystemException, org.apache.airavata.model.error.AuthorizationException, org.apache.thrift.TException
    {
      send_updateCloudJobSubmissionDetails(authzToken, jobSubmissionInterfaceId, sshJobSubmission);
      return recv_updateCloudJobSubmissionDetails();
    }

    public void send_updateCloudJobSubmissionDetails(org.apache.airavata.model.security.AuthzToken authzToken, String jobSubmissionInterfaceId, org.apache.airavata.model.appcatalog.computeresource.CloudJobSubmission sshJobSubmission) throws org.apache.thrift.TException
    {
      updateCloudJobSubmissionDetails_args args = new updateCloudJobSubmissionDetails_args();
      args.setAuthzToken(authzToken);
      args.setJobSubmissionInterfaceId(jobSubmissionInterfaceId);
      args.setSshJobSubmission(sshJobSubmission);
      sendBase("updateCloudJobSubmissionDetails", args);
    }

    public boolean recv_updateCloudJobSubmissionDetails() throws org.apache.airavata.model.error.InvalidRequestException, org.apache.airavata.model.error.AiravataClientException, org.apache.airavata.model.error.AiravataSystemException, org.apache.airavata.model.error.AuthorizationException, org.apache.thrift.TException
    {
      updateCloudJobSubmissionDetails_result result = new updateCloudJobSubmissionDetails_result();
      receiveBase(result, "updateCloudJobSubmissionDetails");
      if (result.isSetSuccess()) {
        return result.success;
      }
      if (result.ire != null) {
        throw result.ire;
      }
      if (result.ace != null) {
        throw result.ace;
      }
      if (result.ase != null) {
        throw result.ase;
      }
      if (result.ae != null) {
        throw result.ae;
      }
      throw new org.apache.thrift.TApplicationException(org.apache.thrift.TApplicationException.MISSING_RESULT, "updateCloudJobSubmissionDetails failed: unknown result");
    }

    public boolean updateUnicoreJobSubmissionDetails(org.apache.airavata.model.security.AuthzToken authzToken, String jobSubmissionInterfaceId, org.apache.airavata.model.appcatalog.computeresource.UnicoreJobSubmission unicoreJobSubmission) throws org.apache.airavata.model.error.InvalidRequestException, org.apache.airavata.model.error.AiravataClientException, org.apache.airavata.model.error.AiravataSystemException, org.apache.airavata.model.error.AuthorizationException, org.apache.thrift.TException
    {
      send_updateUnicoreJobSubmissionDetails(authzToken, jobSubmissionInterfaceId, unicoreJobSubmission);
      return recv_updateUnicoreJobSubmissionDetails();
    }

    public void send_updateUnicoreJobSubmissionDetails(org.apache.airavata.model.security.AuthzToken authzToken, String jobSubmissionInterfaceId, org.apache.airavata.model.appcatalog.computeresource.UnicoreJobSubmission unicoreJobSubmission) throws org.apache.thrift.TException
    {
      updateUnicoreJobSubmissionDetails_args args = new updateUnicoreJobSubmissionDetails_args();
      args.setAuthzToken(authzToken);
      args.setJobSubmissionInterfaceId(jobSubmissionInterfaceId);
      args.setUnicoreJobSubmission(unicoreJobSubmission);
      sendBase("updateUnicoreJobSubmissionDetails", args);
    }

    public boolean recv_updateUnicoreJobSubmissionDetails() throws org.apache.airavata.model.error.InvalidRequestException, org.apache.airavata.model.error.AiravataClientException, org.apache.airavata.model.error.AiravataSystemException, org.apache.airavata.model.error.AuthorizationException, org.apache.thrift.TException
    {
      updateUnicoreJobSubmissionDetails_result result = new updateUnicoreJobSubmissionDetails_result();
      receiveBase(result, "updateUnicoreJobSubmissionDetails");
      if (result.isSetSuccess()) {
        return result.success;
      }
      if (result.ire != null) {
        throw result.ire;
      }
      if (result.ace != null) {
        throw result.ace;
      }
      if (result.ase != null) {
        throw result.ase;
      }
      if (result.ae != null) {
        throw result.ae;
      }
      throw new org.apache.thrift.TApplicationException(org.apache.thrift.TApplicationException.MISSING_RESULT, "updateUnicoreJobSubmissionDetails failed: unknown result");
    }

    public String addLocalDataMovementDetails(org.apache.airavata.model.security.AuthzToken authzToken, String computeResourceId, int priorityOrder, org.apache.airavata.model.appcatalog.computeresource.LOCALDataMovement localDataMovement) throws org.apache.airavata.model.error.InvalidRequestException, org.apache.airavata.model.error.AiravataClientException, org.apache.airavata.model.error.AiravataSystemException, org.apache.airavata.model.error.AuthorizationException, org.apache.thrift.TException
    {
      send_addLocalDataMovementDetails(authzToken, computeResourceId, priorityOrder, localDataMovement);
      return recv_addLocalDataMovementDetails();
    }

    public void send_addLocalDataMovementDetails(org.apache.airavata.model.security.AuthzToken authzToken, String computeResourceId, int priorityOrder, org.apache.airavata.model.appcatalog.computeresource.LOCALDataMovement localDataMovement) throws org.apache.thrift.TException
    {
      addLocalDataMovementDetails_args args = new addLocalDataMovementDetails_args();
      args.setAuthzToken(authzToken);
      args.setComputeResourceId(computeResourceId);
      args.setPriorityOrder(priorityOrder);
      args.setLocalDataMovement(localDataMovement);
      sendBase("addLocalDataMovementDetails", args);
    }

    public String recv_addLocalDataMovementDetails() throws org.apache.airavata.model.error.InvalidRequestException, org.apache.airavata.model.error.AiravataClientException, org.apache.airavata.model.error.AiravataSystemException, org.apache.airavata.model.error.AuthorizationException, org.apache.thrift.TException
    {
      addLocalDataMovementDetails_result result = new addLocalDataMovementDetails_result();
      receiveBase(result, "addLocalDataMovementDetails");
      if (result.isSetSuccess()) {
        return result.success;
      }
      if (result.ire != null) {
        throw result.ire;
      }
      if (result.ace != null) {
        throw result.ace;
      }
      if (result.ase != null) {
        throw result.ase;
      }
      if (result.ae != null) {
        throw result.ae;
      }
      throw new org.apache.thrift.TApplicationException(org.apache.thrift.TApplicationException.MISSING_RESULT, "addLocalDataMovementDetails failed: unknown result");
    }

    public boolean updateLocalDataMovementDetails(org.apache.airavata.model.security.AuthzToken authzToken, String dataMovementInterfaceId, org.apache.airavata.model.appcatalog.computeresource.LOCALDataMovement localDataMovement) throws org.apache.airavata.model.error.InvalidRequestException, org.apache.airavata.model.error.AiravataClientException, org.apache.airavata.model.error.AiravataSystemException, org.apache.airavata.model.error.AuthorizationException, org.apache.thrift.TException
    {
      send_updateLocalDataMovementDetails(authzToken, dataMovementInterfaceId, localDataMovement);
      return recv_updateLocalDataMovementDetails();
    }

    public void send_updateLocalDataMovementDetails(org.apache.airavata.model.security.AuthzToken authzToken, String dataMovementInterfaceId, org.apache.airavata.model.appcatalog.computeresource.LOCALDataMovement localDataMovement) throws org.apache.thrift.TException
    {
      updateLocalDataMovementDetails_args args = new updateLocalDataMovementDetails_args();
      args.setAuthzToken(authzToken);
      args.setDataMovementInterfaceId(dataMovementInterfaceId);
      args.setLocalDataMovement(localDataMovement);
      sendBase("updateLocalDataMovementDetails", args);
    }

    public boolean recv_updateLocalDataMovementDetails() throws org.apache.airavata.model.error.InvalidRequestException, org.apache.airavata.model.error.AiravataClientException, org.apache.airavata.model.error.AiravataSystemException, org.apache.airavata.model.error.AuthorizationException, org.apache.thrift.TException
    {
      updateLocalDataMovementDetails_result result = new updateLocalDataMovementDetails_result();
      receiveBase(result, "updateLocalDataMovementDetails");
      if (result.isSetSuccess()) {
        return result.success;
      }
      if (result.ire != null) {
        throw result.ire;
      }
      if (result.ace != null) {
        throw result.ace;
      }
      if (result.ase != null) {
        throw result.ase;
      }
      if (result.ae != null) {
        throw result.ae;
      }
      throw new org.apache.thrift.TApplicationException(org.apache.thrift.TApplicationException.MISSING_RESULT, "updateLocalDataMovementDetails failed: unknown result");
    }

    public org.apache.airavata.model.appcatalog.computeresource.LOCALDataMovement getLocalDataMovement(org.apache.airavata.model.security.AuthzToken authzToken, String dataMovementId) throws org.apache.airavata.model.error.InvalidRequestException, org.apache.airavata.model.error.AiravataClientException, org.apache.airavata.model.error.AiravataSystemException, org.apache.airavata.model.error.AuthorizationException, org.apache.thrift.TException
    {
      send_getLocalDataMovement(authzToken, dataMovementId);
      return recv_getLocalDataMovement();
    }

    public void send_getLocalDataMovement(org.apache.airavata.model.security.AuthzToken authzToken, String dataMovementId) throws org.apache.thrift.TException
    {
      getLocalDataMovement_args args = new getLocalDataMovement_args();
      args.setAuthzToken(authzToken);
      args.setDataMovementId(dataMovementId);
      sendBase("getLocalDataMovement", args);
    }

    public org.apache.airavata.model.appcatalog.computeresource.LOCALDataMovement recv_getLocalDataMovement() throws org.apache.airavata.model.error.InvalidRequestException, org.apache.airavata.model.error.AiravataClientException, org.apache.airavata.model.error.AiravataSystemException, org.apache.airavata.model.error.AuthorizationException, org.apache.thrift.TException
    {
      getLocalDataMovement_result result = new getLocalDataMovement_result();
      receiveBase(result, "getLocalDataMovement");
      if (result.isSetSuccess()) {
        return result.success;
      }
      if (result.ire != null) {
        throw result.ire;
      }
      if (result.ace != null) {
        throw result.ace;
      }
      if (result.ase != null) {
        throw result.ase;
      }
      if (result.ae != null) {
        throw result.ae;
      }
      throw new org.apache.thrift.TApplicationException(org.apache.thrift.TApplicationException.MISSING_RESULT, "getLocalDataMovement failed: unknown result");
    }

    public String addSCPDataMovementDetails(org.apache.airavata.model.security.AuthzToken authzToken, String computeResourceId, int priorityOrder, org.apache.airavata.model.appcatalog.computeresource.SCPDataMovement scpDataMovement) throws org.apache.airavata.model.error.InvalidRequestException, org.apache.airavata.model.error.AiravataClientException, org.apache.airavata.model.error.AiravataSystemException, org.apache.airavata.model.error.AuthorizationException, org.apache.thrift.TException
    {
      send_addSCPDataMovementDetails(authzToken, computeResourceId, priorityOrder, scpDataMovement);
      return recv_addSCPDataMovementDetails();
    }

    public void send_addSCPDataMovementDetails(org.apache.airavata.model.security.AuthzToken authzToken, String computeResourceId, int priorityOrder, org.apache.airavata.model.appcatalog.computeresource.SCPDataMovement scpDataMovement) throws org.apache.thrift.TException
    {
      addSCPDataMovementDetails_args args = new addSCPDataMovementDetails_args();
      args.setAuthzToken(authzToken);
      args.setComputeResourceId(computeResourceId);
      args.setPriorityOrder(priorityOrder);
      args.setScpDataMovement(scpDataMovement);
      sendBase("addSCPDataMovementDetails", args);
    }

    public String recv_addSCPDataMovementDetails() throws org.apache.airavata.model.error.InvalidRequestException, org.apache.airavata.model.error.AiravataClientException, org.apache.airavata.model.error.AiravataSystemException, org.apache.airavata.model.error.AuthorizationException, org.apache.thrift.TException
    {
      addSCPDataMovementDetails_result result = new addSCPDataMovementDetails_result();
      receiveBase(result, "addSCPDataMovementDetails");
      if (result.isSetSuccess()) {
        return result.success;
      }
      if (result.ire != null) {
        throw result.ire;
      }
      if (result.ace != null) {
        throw result.ace;
      }
      if (result.ase != null) {
        throw result.ase;
      }
      if (result.ae != null) {
        throw result.ae;
      }
      throw new org.apache.thrift.TApplicationException(org.apache.thrift.TApplicationException.MISSING_RESULT, "addSCPDataMovementDetails failed: unknown result");
    }

    public boolean updateSCPDataMovementDetails(org.apache.airavata.model.security.AuthzToken authzToken, String dataMovementInterfaceId, org.apache.airavata.model.appcatalog.computeresource.SCPDataMovement scpDataMovement) throws org.apache.airavata.model.error.InvalidRequestException, org.apache.airavata.model.error.AiravataClientException, org.apache.airavata.model.error.AiravataSystemException, org.apache.airavata.model.error.AuthorizationException, org.apache.thrift.TException
    {
      send_updateSCPDataMovementDetails(authzToken, dataMovementInterfaceId, scpDataMovement);
      return recv_updateSCPDataMovementDetails();
    }

    public void send_updateSCPDataMovementDetails(org.apache.airavata.model.security.AuthzToken authzToken, String dataMovementInterfaceId, org.apache.airavata.model.appcatalog.computeresource.SCPDataMovement scpDataMovement) throws org.apache.thrift.TException
    {
      updateSCPDataMovementDetails_args args = new updateSCPDataMovementDetails_args();
      args.setAuthzToken(authzToken);
      args.setDataMovementInterfaceId(dataMovementInterfaceId);
      args.setScpDataMovement(scpDataMovement);
      sendBase("updateSCPDataMovementDetails", args);
    }

    public boolean recv_updateSCPDataMovementDetails() throws org.apache.airavata.model.error.InvalidRequestException, org.apache.airavata.model.error.AiravataClientException, org.apache.airavata.model.error.AiravataSystemException, org.apache.airavata.model.error.AuthorizationException, org.apache.thrift.TException
    {
      updateSCPDataMovementDetails_result result = new updateSCPDataMovementDetails_result();
      receiveBase(result, "updateSCPDataMovementDetails");
      if (result.isSetSuccess()) {
        return result.success;
      }
      if (result.ire != null) {
        throw result.ire;
      }
      if (result.ace != null) {
        throw result.ace;
      }
      if (result.ase != null) {
        throw result.ase;
      }
      if (result.ae != null) {
        throw result.ae;
      }
      throw new org.apache.thrift.TApplicationException(org.apache.thrift.TApplicationException.MISSING_RESULT, "updateSCPDataMovementDetails failed: unknown result");
    }

    public org.apache.airavata.model.appcatalog.computeresource.SCPDataMovement getSCPDataMovement(org.apache.airavata.model.security.AuthzToken authzToken, String dataMovementId) throws org.apache.airavata.model.error.InvalidRequestException, org.apache.airavata.model.error.AiravataClientException, org.apache.airavata.model.error.AiravataSystemException, org.apache.airavata.model.error.AuthorizationException, org.apache.thrift.TException
    {
      send_getSCPDataMovement(authzToken, dataMovementId);
      return recv_getSCPDataMovement();
    }

    public void send_getSCPDataMovement(org.apache.airavata.model.security.AuthzToken authzToken, String dataMovementId) throws org.apache.thrift.TException
    {
      getSCPDataMovement_args args = new getSCPDataMovement_args();
      args.setAuthzToken(authzToken);
      args.setDataMovementId(dataMovementId);
      sendBase("getSCPDataMovement", args);
    }

    public org.apache.airavata.model.appcatalog.computeresource.SCPDataMovement recv_getSCPDataMovement() throws org.apache.airavata.model.error.InvalidRequestException, org.apache.airavata.model.error.AiravataClientException, org.apache.airavata.model.error.AiravataSystemException, org.apache.airavata.model.error.AuthorizationException, org.apache.thrift.TException
    {
      getSCPDataMovement_result result = new getSCPDataMovement_result();
      receiveBase(result, "getSCPDataMovement");
      if (result.isSetSuccess()) {
        return result.success;
      }
      if (result.ire != null) {
        throw result.ire;
      }
      if (result.ace != null) {
        throw result.ace;
      }
      if (result.ase != null) {
        throw result.ase;
      }
      if (result.ae != null) {
        throw result.ae;
      }
      throw new org.apache.thrift.TApplicationException(org.apache.thrift.TApplicationException.MISSING_RESULT, "getSCPDataMovement failed: unknown result");
    }

    public String addUnicoreDataMovementDetails(org.apache.airavata.model.security.AuthzToken authzToken, String computeResourceId, int priorityOrder, org.apache.airavata.model.appcatalog.computeresource.UnicoreDataMovement unicoreDataMovement) throws org.apache.airavata.model.error.InvalidRequestException, org.apache.airavata.model.error.AiravataClientException, org.apache.airavata.model.error.AiravataSystemException, org.apache.airavata.model.error.AuthorizationException, org.apache.thrift.TException
    {
      send_addUnicoreDataMovementDetails(authzToken, computeResourceId, priorityOrder, unicoreDataMovement);
      return recv_addUnicoreDataMovementDetails();
    }

    public void send_addUnicoreDataMovementDetails(org.apache.airavata.model.security.AuthzToken authzToken, String computeResourceId, int priorityOrder, org.apache.airavata.model.appcatalog.computeresource.UnicoreDataMovement unicoreDataMovement) throws org.apache.thrift.TException
    {
      addUnicoreDataMovementDetails_args args = new addUnicoreDataMovementDetails_args();
      args.setAuthzToken(authzToken);
      args.setComputeResourceId(computeResourceId);
      args.setPriorityOrder(priorityOrder);
      args.setUnicoreDataMovement(unicoreDataMovement);
      sendBase("addUnicoreDataMovementDetails", args);
    }

    public String recv_addUnicoreDataMovementDetails() throws org.apache.airavata.model.error.InvalidRequestException, org.apache.airavata.model.error.AiravataClientException, org.apache.airavata.model.error.AiravataSystemException, org.apache.airavata.model.error.AuthorizationException, org.apache.thrift.TException
    {
      addUnicoreDataMovementDetails_result result = new addUnicoreDataMovementDetails_result();
      receiveBase(result, "addUnicoreDataMovementDetails");
      if (result.isSetSuccess()) {
        return result.success;
      }
      if (result.ire != null) {
        throw result.ire;
      }
      if (result.ace != null) {
        throw result.ace;
      }
      if (result.ase != null) {
        throw result.ase;
      }
      if (result.ae != null) {
        throw result.ae;
      }
      throw new org.apache.thrift.TApplicationException(org.apache.thrift.TApplicationException.MISSING_RESULT, "addUnicoreDataMovementDetails failed: unknown result");
    }

    public boolean updateUnicoreDataMovementDetails(org.apache.airavata.model.security.AuthzToken authzToken, String dataMovementInterfaceId, org.apache.airavata.model.appcatalog.computeresource.UnicoreDataMovement unicoreDataMovement) throws org.apache.airavata.model.error.InvalidRequestException, org.apache.airavata.model.error.AiravataClientException, org.apache.airavata.model.error.AiravataSystemException, org.apache.airavata.model.error.AuthorizationException, org.apache.thrift.TException
    {
      send_updateUnicoreDataMovementDetails(authzToken, dataMovementInterfaceId, unicoreDataMovement);
      return recv_updateUnicoreDataMovementDetails();
    }

    public void send_updateUnicoreDataMovementDetails(org.apache.airavata.model.security.AuthzToken authzToken, String dataMovementInterfaceId, org.apache.airavata.model.appcatalog.computeresource.UnicoreDataMovement unicoreDataMovement) throws org.apache.thrift.TException
    {
      updateUnicoreDataMovementDetails_args args = new updateUnicoreDataMovementDetails_args();
      args.setAuthzToken(authzToken);
      args.setDataMovementInterfaceId(dataMovementInterfaceId);
      args.setUnicoreDataMovement(unicoreDataMovement);
      sendBase("updateUnicoreDataMovementDetails", args);
    }

    public boolean recv_updateUnicoreDataMovementDetails() throws org.apache.airavata.model.error.InvalidRequestException, org.apache.airavata.model.error.AiravataClientException, org.apache.airavata.model.error.AiravataSystemException, org.apache.airavata.model.error.AuthorizationException, org.apache.thrift.TException
    {
      updateUnicoreDataMovementDetails_result result = new updateUnicoreDataMovementDetails_result();
      receiveBase(result, "updateUnicoreDataMovementDetails");
      if (result.isSetSuccess()) {
        return result.success;
      }
      if (result.ire != null) {
        throw result.ire;
      }
      if (result.ace != null) {
        throw result.ace;
      }
      if (result.ase != null) {
        throw result.ase;
      }
      if (result.ae != null) {
        throw result.ae;
      }
      throw new org.apache.thrift.TApplicationException(org.apache.thrift.TApplicationException.MISSING_RESULT, "updateUnicoreDataMovementDetails failed: unknown result");
    }

    public org.apache.airavata.model.appcatalog.computeresource.UnicoreDataMovement getUnicoreDataMovement(org.apache.airavata.model.security.AuthzToken authzToken, String dataMovementId) throws org.apache.airavata.model.error.InvalidRequestException, org.apache.airavata.model.error.AiravataClientException, org.apache.airavata.model.error.AiravataSystemException, org.apache.airavata.model.error.AuthorizationException, org.apache.thrift.TException
    {
      send_getUnicoreDataMovement(authzToken, dataMovementId);
      return recv_getUnicoreDataMovement();
    }

    public void send_getUnicoreDataMovement(org.apache.airavata.model.security.AuthzToken authzToken, String dataMovementId) throws org.apache.thrift.TException
    {
      getUnicoreDataMovement_args args = new getUnicoreDataMovement_args();
      args.setAuthzToken(authzToken);
      args.setDataMovementId(dataMovementId);
      sendBase("getUnicoreDataMovement", args);
    }

    public org.apache.airavata.model.appcatalog.computeresource.UnicoreDataMovement recv_getUnicoreDataMovement() throws org.apache.airavata.model.error.InvalidRequestException, org.apache.airavata.model.error.AiravataClientException, org.apache.airavata.model.error.AiravataSystemException, org.apache.airavata.model.error.AuthorizationException, org.apache.thrift.TException
    {
      getUnicoreDataMovement_result result = new getUnicoreDataMovement_result();
      receiveBase(result, "getUnicoreDataMovement");
      if (result.isSetSuccess()) {
        return result.success;
      }
      if (result.ire != null) {
        throw result.ire;
      }
      if (result.ace != null) {
        throw result.ace;
      }
      if (result.ase != null) {
        throw result.ase;
      }
      if (result.ae != null) {
        throw result.ae;
      }
      throw new org.apache.thrift.TApplicationException(org.apache.thrift.TApplicationException.MISSING_RESULT, "getUnicoreDataMovement failed: unknown result");
    }

    public String addGridFTPDataMovementDetails(org.apache.airavata.model.security.AuthzToken authzToken, String computeResourceId, int priorityOrder, org.apache.airavata.model.appcatalog.computeresource.GridFTPDataMovement gridFTPDataMovement) throws org.apache.airavata.model.error.InvalidRequestException, org.apache.airavata.model.error.AiravataClientException, org.apache.airavata.model.error.AiravataSystemException, org.apache.airavata.model.error.AuthorizationException, org.apache.thrift.TException
    {
      send_addGridFTPDataMovementDetails(authzToken, computeResourceId, priorityOrder, gridFTPDataMovement);
      return recv_addGridFTPDataMovementDetails();
    }

    public void send_addGridFTPDataMovementDetails(org.apache.airavata.model.security.AuthzToken authzToken, String computeResourceId, int priorityOrder, org.apache.airavata.model.appcatalog.computeresource.GridFTPDataMovement gridFTPDataMovement) throws org.apache.thrift.TException
    {
      addGridFTPDataMovementDetails_args args = new addGridFTPDataMovementDetails_args();
      args.setAuthzToken(authzToken);
      args.setComputeResourceId(computeResourceId);
      args.setPriorityOrder(priorityOrder);
      args.setGridFTPDataMovement(gridFTPDataMovement);
      sendBase("addGridFTPDataMovementDetails", args);
    }

    public String recv_addGridFTPDataMovementDetails() throws org.apache.airavata.model.error.InvalidRequestException, org.apache.airavata.model.error.AiravataClientException, org.apache.airavata.model.error.AiravataSystemException, org.apache.airavata.model.error.AuthorizationException, org.apache.thrift.TException
    {
      addGridFTPDataMovementDetails_result result = new addGridFTPDataMovementDetails_result();
      receiveBase(result, "addGridFTPDataMovementDetails");
      if (result.isSetSuccess()) {
        return result.success;
      }
      if (result.ire != null) {
        throw result.ire;
      }
      if (result.ace != null) {
        throw result.ace;
      }
      if (result.ase != null) {
        throw result.ase;
      }
      if (result.ae != null) {
        throw result.ae;
      }
      throw new org.apache.thrift.TApplicationException(org.apache.thrift.TApplicationException.MISSING_RESULT, "addGridFTPDataMovementDetails failed: unknown result");
    }

    public boolean updateGridFTPDataMovementDetails(org.apache.airavata.model.security.AuthzToken authzToken, String dataMovementInterfaceId, org.apache.airavata.model.appcatalog.computeresource.GridFTPDataMovement gridFTPDataMovement) throws org.apache.airavata.model.error.InvalidRequestException, org.apache.airavata.model.error.AiravataClientException, org.apache.airavata.model.error.AiravataSystemException, org.apache.airavata.model.error.AuthorizationException, org.apache.thrift.TException
    {
      send_updateGridFTPDataMovementDetails(authzToken, dataMovementInterfaceId, gridFTPDataMovement);
      return recv_updateGridFTPDataMovementDetails();
    }

    public void send_updateGridFTPDataMovementDetails(org.apache.airavata.model.security.AuthzToken authzToken, String dataMovementInterfaceId, org.apache.airavata.model.appcatalog.computeresource.GridFTPDataMovement gridFTPDataMovement) throws org.apache.thrift.TException
    {
      updateGridFTPDataMovementDetails_args args = new updateGridFTPDataMovementDetails_args();
      args.setAuthzToken(authzToken);
      args.setDataMovementInterfaceId(dataMovementInterfaceId);
      args.setGridFTPDataMovement(gridFTPDataMovement);
      sendBase("updateGridFTPDataMovementDetails", args);
    }

    public boolean recv_updateGridFTPDataMovementDetails() throws org.apache.airavata.model.error.InvalidRequestException, org.apache.airavata.model.error.AiravataClientException, org.apache.airavata.model.error.AiravataSystemException, org.apache.airavata.model.error.AuthorizationException, org.apache.thrift.TException
    {
      updateGridFTPDataMovementDetails_result result = new updateGridFTPDataMovementDetails_result();
      receiveBase(result, "updateGridFTPDataMovementDetails");
      if (result.isSetSuccess()) {
        return result.success;
      }
      if (result.ire != null) {
        throw result.ire;
      }
      if (result.ace != null) {
        throw result.ace;
      }
      if (result.ase != null) {
        throw result.ase;
      }
      if (result.ae != null) {
        throw result.ae;
      }
      throw new org.apache.thrift.TApplicationException(org.apache.thrift.TApplicationException.MISSING_RESULT, "updateGridFTPDataMovementDetails failed: unknown result");
    }

    public org.apache.airavata.model.appcatalog.computeresource.GridFTPDataMovement getGridFTPDataMovement(org.apache.airavata.model.security.AuthzToken authzToken, String dataMovementId) throws org.apache.airavata.model.error.InvalidRequestException, org.apache.airavata.model.error.AiravataClientException, org.apache.airavata.model.error.AiravataSystemException, org.apache.airavata.model.error.AuthorizationException, org.apache.thrift.TException
    {
      send_getGridFTPDataMovement(authzToken, dataMovementId);
      return recv_getGridFTPDataMovement();
    }

    public void send_getGridFTPDataMovement(org.apache.airavata.model.security.AuthzToken authzToken, String dataMovementId) throws org.apache.thrift.TException
    {
      getGridFTPDataMovement_args args = new getGridFTPDataMovement_args();
      args.setAuthzToken(authzToken);
      args.setDataMovementId(dataMovementId);
      sendBase("getGridFTPDataMovement", args);
    }

    public org.apache.airavata.model.appcatalog.computeresource.GridFTPDataMovement recv_getGridFTPDataMovement() throws org.apache.airavata.model.error.InvalidRequestException, org.apache.airavata.model.error.AiravataClientException, org.apache.airavata.model.error.AiravataSystemException, org.apache.airavata.model.error.AuthorizationException, org.apache.thrift.TException
    {
      getGridFTPDataMovement_result result = new getGridFTPDataMovement_result();
      receiveBase(result, "getGridFTPDataMovement");
      if (result.isSetSuccess()) {
        return result.success;
      }
      if (result.ire != null) {
        throw result.ire;
      }
      if (result.ace != null) {
        throw result.ace;
      }
      if (result.ase != null) {
        throw result.ase;
      }
      if (result.ae != null) {
        throw result.ae;
      }
      throw new org.apache.thrift.TApplicationException(org.apache.thrift.TApplicationException.MISSING_RESULT, "getGridFTPDataMovement failed: unknown result");
    }

    public boolean changeJobSubmissionPriority(org.apache.airavata.model.security.AuthzToken authzToken, String jobSubmissionInterfaceId, int newPriorityOrder) throws org.apache.airavata.model.error.InvalidRequestException, org.apache.airavata.model.error.AiravataClientException, org.apache.airavata.model.error.AiravataSystemException, org.apache.airavata.model.error.AuthorizationException, org.apache.thrift.TException
    {
      send_changeJobSubmissionPriority(authzToken, jobSubmissionInterfaceId, newPriorityOrder);
      return recv_changeJobSubmissionPriority();
    }

    public void send_changeJobSubmissionPriority(org.apache.airavata.model.security.AuthzToken authzToken, String jobSubmissionInterfaceId, int newPriorityOrder) throws org.apache.thrift.TException
    {
      changeJobSubmissionPriority_args args = new changeJobSubmissionPriority_args();
      args.setAuthzToken(authzToken);
      args.setJobSubmissionInterfaceId(jobSubmissionInterfaceId);
      args.setNewPriorityOrder(newPriorityOrder);
      sendBase("changeJobSubmissionPriority", args);
    }

    public boolean recv_changeJobSubmissionPriority() throws org.apache.airavata.model.error.InvalidRequestException, org.apache.airavata.model.error.AiravataClientException, org.apache.airavata.model.error.AiravataSystemException, org.apache.airavata.model.error.AuthorizationException, org.apache.thrift.TException
    {
      changeJobSubmissionPriority_result result = new changeJobSubmissionPriority_result();
      receiveBase(result, "changeJobSubmissionPriority");
      if (result.isSetSuccess()) {
        return result.success;
      }
      if (result.ire != null) {
        throw result.ire;
      }
      if (result.ace != null) {
        throw result.ace;
      }
      if (result.ase != null) {
        throw result.ase;
      }
      if (result.ae != null) {
        throw result.ae;
      }
      throw new org.apache.thrift.TApplicationException(org.apache.thrift.TApplicationException.MISSING_RESULT, "changeJobSubmissionPriority failed: unknown result");
    }

    public boolean changeDataMovementPriority(org.apache.airavata.model.security.AuthzToken authzToken, String dataMovementInterfaceId, int newPriorityOrder) throws org.apache.airavata.model.error.InvalidRequestException, org.apache.airavata.model.error.AiravataClientException, org.apache.airavata.model.error.AiravataSystemException, org.apache.airavata.model.error.AuthorizationException, org.apache.thrift.TException
    {
      send_changeDataMovementPriority(authzToken, dataMovementInterfaceId, newPriorityOrder);
      return recv_changeDataMovementPriority();
    }

    public void send_changeDataMovementPriority(org.apache.airavata.model.security.AuthzToken authzToken, String dataMovementInterfaceId, int newPriorityOrder) throws org.apache.thrift.TException
    {
      changeDataMovementPriority_args args = new changeDataMovementPriority_args();
      args.setAuthzToken(authzToken);
      args.setDataMovementInterfaceId(dataMovementInterfaceId);
      args.setNewPriorityOrder(newPriorityOrder);
      sendBase("changeDataMovementPriority", args);
    }

    public boolean recv_changeDataMovementPriority() throws org.apache.airavata.model.error.InvalidRequestException, org.apache.airavata.model.error.AiravataClientException, org.apache.airavata.model.error.AiravataSystemException, org.apache.airavata.model.error.AuthorizationException, org.apache.thrift.TException
    {
      changeDataMovementPriority_result result = new changeDataMovementPriority_result();
      receiveBase(result, "changeDataMovementPriority");
      if (result.isSetSuccess()) {
        return result.success;
      }
      if (result.ire != null) {
        throw result.ire;
      }
      if (result.ace != null) {
        throw result.ace;
      }
      if (result.ase != null) {
        throw result.ase;
      }
      if (result.ae != null) {
        throw result.ae;
      }
      throw new org.apache.thrift.TApplicationException(org.apache.thrift.TApplicationException.MISSING_RESULT, "changeDataMovementPriority failed: unknown result");
    }

    public boolean changeJobSubmissionPriorities(org.apache.airavata.model.security.AuthzToken authzToken, Map<String,Integer> jobSubmissionPriorityMap) throws org.apache.airavata.model.error.InvalidRequestException, org.apache.airavata.model.error.AiravataClientException, org.apache.airavata.model.error.AiravataSystemException, org.apache.airavata.model.error.AuthorizationException, org.apache.thrift.TException
    {
      send_changeJobSubmissionPriorities(authzToken, jobSubmissionPriorityMap);
      return recv_changeJobSubmissionPriorities();
    }

    public void send_changeJobSubmissionPriorities(org.apache.airavata.model.security.AuthzToken authzToken, Map<String,Integer> jobSubmissionPriorityMap) throws org.apache.thrift.TException
    {
      changeJobSubmissionPriorities_args args = new changeJobSubmissionPriorities_args();
      args.setAuthzToken(authzToken);
      args.setJobSubmissionPriorityMap(jobSubmissionPriorityMap);
      sendBase("changeJobSubmissionPriorities", args);
    }

    public boolean recv_changeJobSubmissionPriorities() throws org.apache.airavata.model.error.InvalidRequestException, org.apache.airavata.model.error.AiravataClientException, org.apache.airavata.model.error.AiravataSystemException, org.apache.airavata.model.error.AuthorizationException, org.apache.thrift.TException
    {
      changeJobSubmissionPriorities_result result = new changeJobSubmissionPriorities_result();
      receiveBase(result, "changeJobSubmissionPriorities");
      if (result.isSetSuccess()) {
        return result.success;
      }
      if (result.ire != null) {
        throw result.ire;
      }
      if (result.ace != null) {
        throw result.ace;
      }
      if (result.ase != null) {
        throw result.ase;
      }
      if (result.ae != null) {
        throw result.ae;
      }
      throw new org.apache.thrift.TApplicationException(org.apache.thrift.TApplicationException.MISSING_RESULT, "changeJobSubmissionPriorities failed: unknown result");
    }

    public boolean changeDataMovementPriorities(org.apache.airavata.model.security.AuthzToken authzToken, Map<String,Integer> dataMovementPriorityMap) throws org.apache.airavata.model.error.InvalidRequestException, org.apache.airavata.model.error.AiravataClientException, org.apache.airavata.model.error.AiravataSystemException, org.apache.airavata.model.error.AuthorizationException, org.apache.thrift.TException
    {
      send_changeDataMovementPriorities(authzToken, dataMovementPriorityMap);
      return recv_changeDataMovementPriorities();
    }

    public void send_changeDataMovementPriorities(org.apache.airavata.model.security.AuthzToken authzToken, Map<String,Integer> dataMovementPriorityMap) throws org.apache.thrift.TException
    {
      changeDataMovementPriorities_args args = new changeDataMovementPriorities_args();
      args.setAuthzToken(authzToken);
      args.setDataMovementPriorityMap(dataMovementPriorityMap);
      sendBase("changeDataMovementPriorities", args);
    }

    public boolean recv_changeDataMovementPriorities() throws org.apache.airavata.model.error.InvalidRequestException, org.apache.airavata.model.error.AiravataClientException, org.apache.airavata.model.error.AiravataSystemException, org.apache.airavata.model.error.AuthorizationException, org.apache.thrift.TException
    {
      changeDataMovementPriorities_result result = new changeDataMovementPriorities_result();
      receiveBase(result, "changeDataMovementPriorities");
      if (result.isSetSuccess()) {
        return result.success;
      }
      if (result.ire != null) {
        throw result.ire;
      }
      if (result.ace != null) {
        throw result.ace;
      }
      if (result.ase != null) {
        throw result.ase;
      }
      if (result.ae != null) {
        throw result.ae;
      }
      throw new org.apache.thrift.TApplicationException(org.apache.thrift.TApplicationException.MISSING_RESULT, "changeDataMovementPriorities failed: unknown result");
    }

    public boolean deleteJobSubmissionInterface(org.apache.airavata.model.security.AuthzToken authzToken, String computeResourceId, String jobSubmissionInterfaceId) throws org.apache.airavata.model.error.InvalidRequestException, org.apache.airavata.model.error.AiravataClientException, org.apache.airavata.model.error.AiravataSystemException, org.apache.airavata.model.error.AuthorizationException, org.apache.thrift.TException
    {
      send_deleteJobSubmissionInterface(authzToken, computeResourceId, jobSubmissionInterfaceId);
      return recv_deleteJobSubmissionInterface();
    }

    public void send_deleteJobSubmissionInterface(org.apache.airavata.model.security.AuthzToken authzToken, String computeResourceId, String jobSubmissionInterfaceId) throws org.apache.thrift.TException
    {
      deleteJobSubmissionInterface_args args = new deleteJobSubmissionInterface_args();
      args.setAuthzToken(authzToken);
      args.setComputeResourceId(computeResourceId);
      args.setJobSubmissionInterfaceId(jobSubmissionInterfaceId);
      sendBase("deleteJobSubmissionInterface", args);
    }

    public boolean recv_deleteJobSubmissionInterface() throws org.apache.airavata.model.error.InvalidRequestException, org.apache.airavata.model.error.AiravataClientException, org.apache.airavata.model.error.AiravataSystemException, org.apache.airavata.model.error.AuthorizationException, org.apache.thrift.TException
    {
      deleteJobSubmissionInterface_result result = new deleteJobSubmissionInterface_result();
      receiveBase(result, "deleteJobSubmissionInterface");
      if (result.isSetSuccess()) {
        return result.success;
      }
      if (result.ire != null) {
        throw result.ire;
      }
      if (result.ace != null) {
        throw result.ace;
      }
      if (result.ase != null) {
        throw result.ase;
      }
      if (result.ae != null) {
        throw result.ae;
      }
      throw new org.apache.thrift.TApplicationException(org.apache.thrift.TApplicationException.MISSING_RESULT, "deleteJobSubmissionInterface failed: unknown result");
    }

    public boolean deleteDataMovementInterface(org.apache.airavata.model.security.AuthzToken authzToken, String computeResourceId, String dataMovementInterfaceId) throws org.apache.airavata.model.error.InvalidRequestException, org.apache.airavata.model.error.AiravataClientException, org.apache.airavata.model.error.AiravataSystemException, org.apache.airavata.model.error.AuthorizationException, org.apache.thrift.TException
    {
      send_deleteDataMovementInterface(authzToken, computeResourceId, dataMovementInterfaceId);
      return recv_deleteDataMovementInterface();
    }

    public void send_deleteDataMovementInterface(org.apache.airavata.model.security.AuthzToken authzToken, String computeResourceId, String dataMovementInterfaceId) throws org.apache.thrift.TException
    {
      deleteDataMovementInterface_args args = new deleteDataMovementInterface_args();
      args.setAuthzToken(authzToken);
      args.setComputeResourceId(computeResourceId);
      args.setDataMovementInterfaceId(dataMovementInterfaceId);
      sendBase("deleteDataMovementInterface", args);
    }

    public boolean recv_deleteDataMovementInterface() throws org.apache.airavata.model.error.InvalidRequestException, org.apache.airavata.model.error.AiravataClientException, org.apache.airavata.model.error.AiravataSystemException, org.apache.airavata.model.error.AuthorizationException, org.apache.thrift.TException
    {
      deleteDataMovementInterface_result result = new deleteDataMovementInterface_result();
      receiveBase(result, "deleteDataMovementInterface");
      if (result.isSetSuccess()) {
        return result.success;
      }
      if (result.ire != null) {
        throw result.ire;
      }
      if (result.ace != null) {
        throw result.ace;
      }
      if (result.ase != null) {
        throw result.ase;
      }
      if (result.ae != null) {
        throw result.ae;
      }
      throw new org.apache.thrift.TApplicationException(org.apache.thrift.TApplicationException.MISSING_RESULT, "deleteDataMovementInterface failed: unknown result");
    }

    public String registerResourceJobManager(org.apache.airavata.model.security.AuthzToken authzToken, org.apache.airavata.model.appcatalog.computeresource.ResourceJobManager resourceJobManager) throws org.apache.airavata.model.error.InvalidRequestException, org.apache.airavata.model.error.AiravataClientException, org.apache.airavata.model.error.AiravataSystemException, org.apache.airavata.model.error.AuthorizationException, org.apache.thrift.TException
    {
      send_registerResourceJobManager(authzToken, resourceJobManager);
      return recv_registerResourceJobManager();
    }

    public void send_registerResourceJobManager(org.apache.airavata.model.security.AuthzToken authzToken, org.apache.airavata.model.appcatalog.computeresource.ResourceJobManager resourceJobManager) throws org.apache.thrift.TException
    {
      registerResourceJobManager_args args = new registerResourceJobManager_args();
      args.setAuthzToken(authzToken);
      args.setResourceJobManager(resourceJobManager);
      sendBase("registerResourceJobManager", args);
    }

    public String recv_registerResourceJobManager() throws org.apache.airavata.model.error.InvalidRequestException, org.apache.airavata.model.error.AiravataClientException, org.apache.airavata.model.error.AiravataSystemException, org.apache.airavata.model.error.AuthorizationException, org.apache.thrift.TException
    {
      registerResourceJobManager_result result = new registerResourceJobManager_result();
      receiveBase(result, "registerResourceJobManager");
      if (result.isSetSuccess()) {
        return result.success;
      }
      if (result.ire != null) {
        throw result.ire;
      }
      if (result.ace != null) {
        throw result.ace;
      }
      if (result.ase != null) {
        throw result.ase;
      }
      if (result.ae != null) {
        throw result.ae;
      }
      throw new org.apache.thrift.TApplicationException(org.apache.thrift.TApplicationException.MISSING_RESULT, "registerResourceJobManager failed: unknown result");
    }

    public boolean updateResourceJobManager(org.apache.airavata.model.security.AuthzToken authzToken, String resourceJobManagerId, org.apache.airavata.model.appcatalog.computeresource.ResourceJobManager updatedResourceJobManager) throws org.apache.airavata.model.error.InvalidRequestException, org.apache.airavata.model.error.AiravataClientException, org.apache.airavata.model.error.AiravataSystemException, org.apache.airavata.model.error.AuthorizationException, org.apache.thrift.TException
    {
      send_updateResourceJobManager(authzToken, resourceJobManagerId, updatedResourceJobManager);
      return recv_updateResourceJobManager();
    }

    public void send_updateResourceJobManager(org.apache.airavata.model.security.AuthzToken authzToken, String resourceJobManagerId, org.apache.airavata.model.appcatalog.computeresource.ResourceJobManager updatedResourceJobManager) throws org.apache.thrift.TException
    {
      updateResourceJobManager_args args = new updateResourceJobManager_args();
      args.setAuthzToken(authzToken);
      args.setResourceJobManagerId(resourceJobManagerId);
      args.setUpdatedResourceJobManager(updatedResourceJobManager);
      sendBase("updateResourceJobManager", args);
    }

    public boolean recv_updateResourceJobManager() throws org.apache.airavata.model.error.InvalidRequestException, org.apache.airavata.model.error.AiravataClientException, org.apache.airavata.model.error.AiravataSystemException, org.apache.airavata.model.error.AuthorizationException, org.apache.thrift.TException
    {
      updateResourceJobManager_result result = new updateResourceJobManager_result();
      receiveBase(result, "updateResourceJobManager");
      if (result.isSetSuccess()) {
        return result.success;
      }
      if (result.ire != null) {
        throw result.ire;
      }
      if (result.ace != null) {
        throw result.ace;
      }
      if (result.ase != null) {
        throw result.ase;
      }
      if (result.ae != null) {
        throw result.ae;
      }
      throw new org.apache.thrift.TApplicationException(org.apache.thrift.TApplicationException.MISSING_RESULT, "updateResourceJobManager failed: unknown result");
    }

    public org.apache.airavata.model.appcatalog.computeresource.ResourceJobManager getResourceJobManager(org.apache.airavata.model.security.AuthzToken authzToken, String resourceJobManagerId) throws org.apache.airavata.model.error.InvalidRequestException, org.apache.airavata.model.error.AiravataClientException, org.apache.airavata.model.error.AiravataSystemException, org.apache.airavata.model.error.AuthorizationException, org.apache.thrift.TException
    {
      send_getResourceJobManager(authzToken, resourceJobManagerId);
      return recv_getResourceJobManager();
    }

    public void send_getResourceJobManager(org.apache.airavata.model.security.AuthzToken authzToken, String resourceJobManagerId) throws org.apache.thrift.TException
    {
      getResourceJobManager_args args = new getResourceJobManager_args();
      args.setAuthzToken(authzToken);
      args.setResourceJobManagerId(resourceJobManagerId);
      sendBase("getResourceJobManager", args);
    }

    public org.apache.airavata.model.appcatalog.computeresource.ResourceJobManager recv_getResourceJobManager() throws org.apache.airavata.model.error.InvalidRequestException, org.apache.airavata.model.error.AiravataClientException, org.apache.airavata.model.error.AiravataSystemException, org.apache.airavata.model.error.AuthorizationException, org.apache.thrift.TException
    {
      getResourceJobManager_result result = new getResourceJobManager_result();
      receiveBase(result, "getResourceJobManager");
      if (result.isSetSuccess()) {
        return result.success;
      }
      if (result.ire != null) {
        throw result.ire;
      }
      if (result.ace != null) {
        throw result.ace;
      }
      if (result.ase != null) {
        throw result.ase;
      }
      if (result.ae != null) {
        throw result.ae;
      }
      throw new org.apache.thrift.TApplicationException(org.apache.thrift.TApplicationException.MISSING_RESULT, "getResourceJobManager failed: unknown result");
    }

    public boolean deleteResourceJobManager(org.apache.airavata.model.security.AuthzToken authzToken, String resourceJobManagerId) throws org.apache.airavata.model.error.InvalidRequestException, org.apache.airavata.model.error.AiravataClientException, org.apache.airavata.model.error.AiravataSystemException, org.apache.airavata.model.error.AuthorizationException, org.apache.thrift.TException
    {
      send_deleteResourceJobManager(authzToken, resourceJobManagerId);
      return recv_deleteResourceJobManager();
    }

    public void send_deleteResourceJobManager(org.apache.airavata.model.security.AuthzToken authzToken, String resourceJobManagerId) throws org.apache.thrift.TException
    {
      deleteResourceJobManager_args args = new deleteResourceJobManager_args();
      args.setAuthzToken(authzToken);
      args.setResourceJobManagerId(resourceJobManagerId);
      sendBase("deleteResourceJobManager", args);
    }

    public boolean recv_deleteResourceJobManager() throws org.apache.airavata.model.error.InvalidRequestException, org.apache.airavata.model.error.AiravataClientException, org.apache.airavata.model.error.AiravataSystemException, org.apache.airavata.model.error.AuthorizationException, org.apache.thrift.TException
    {
      deleteResourceJobManager_result result = new deleteResourceJobManager_result();
      receiveBase(result, "deleteResourceJobManager");
      if (result.isSetSuccess()) {
        return result.success;
      }
      if (result.ire != null) {
        throw result.ire;
      }
      if (result.ace != null) {
        throw result.ace;
      }
      if (result.ase != null) {
        throw result.ase;
      }
      if (result.ae != null) {
        throw result.ae;
      }
      throw new org.apache.thrift.TApplicationException(org.apache.thrift.TApplicationException.MISSING_RESULT, "deleteResourceJobManager failed: unknown result");
    }

    public boolean deleteBatchQueue(org.apache.airavata.model.security.AuthzToken authzToken, String computeResourceId, String queueName) throws org.apache.airavata.model.error.InvalidRequestException, org.apache.airavata.model.error.AiravataClientException, org.apache.airavata.model.error.AiravataSystemException, org.apache.airavata.model.error.AuthorizationException, org.apache.thrift.TException
    {
      send_deleteBatchQueue(authzToken, computeResourceId, queueName);
      return recv_deleteBatchQueue();
    }

    public void send_deleteBatchQueue(org.apache.airavata.model.security.AuthzToken authzToken, String computeResourceId, String queueName) throws org.apache.thrift.TException
    {
      deleteBatchQueue_args args = new deleteBatchQueue_args();
      args.setAuthzToken(authzToken);
      args.setComputeResourceId(computeResourceId);
      args.setQueueName(queueName);
      sendBase("deleteBatchQueue", args);
    }

    public boolean recv_deleteBatchQueue() throws org.apache.airavata.model.error.InvalidRequestException, org.apache.airavata.model.error.AiravataClientException, org.apache.airavata.model.error.AiravataSystemException, org.apache.airavata.model.error.AuthorizationException, org.apache.thrift.TException
    {
      deleteBatchQueue_result result = new deleteBatchQueue_result();
      receiveBase(result, "deleteBatchQueue");
      if (result.isSetSuccess()) {
        return result.success;
      }
      if (result.ire != null) {
        throw result.ire;
      }
      if (result.ace != null) {
        throw result.ace;
      }
      if (result.ase != null) {
        throw result.ase;
      }
      if (result.ae != null) {
        throw result.ae;
      }
      throw new org.apache.thrift.TApplicationException(org.apache.thrift.TApplicationException.MISSING_RESULT, "deleteBatchQueue failed: unknown result");
    }

    public String registerGatewayResourceProfile(org.apache.airavata.model.security.AuthzToken authzToken, org.apache.airavata.model.appcatalog.gatewayprofile.GatewayResourceProfile gatewayResourceProfile) throws org.apache.airavata.model.error.InvalidRequestException, org.apache.airavata.model.error.AiravataClientException, org.apache.airavata.model.error.AiravataSystemException, org.apache.airavata.model.error.AuthorizationException, org.apache.thrift.TException
    {
      send_registerGatewayResourceProfile(authzToken, gatewayResourceProfile);
      return recv_registerGatewayResourceProfile();
    }

    public void send_registerGatewayResourceProfile(org.apache.airavata.model.security.AuthzToken authzToken, org.apache.airavata.model.appcatalog.gatewayprofile.GatewayResourceProfile gatewayResourceProfile) throws org.apache.thrift.TException
    {
      registerGatewayResourceProfile_args args = new registerGatewayResourceProfile_args();
      args.setAuthzToken(authzToken);
      args.setGatewayResourceProfile(gatewayResourceProfile);
      sendBase("registerGatewayResourceProfile", args);
    }

    public String recv_registerGatewayResourceProfile() throws org.apache.airavata.model.error.InvalidRequestException, org.apache.airavata.model.error.AiravataClientException, org.apache.airavata.model.error.AiravataSystemException, org.apache.airavata.model.error.AuthorizationException, org.apache.thrift.TException
    {
      registerGatewayResourceProfile_result result = new registerGatewayResourceProfile_result();
      receiveBase(result, "registerGatewayResourceProfile");
      if (result.isSetSuccess()) {
        return result.success;
      }
      if (result.ire != null) {
        throw result.ire;
      }
      if (result.ace != null) {
        throw result.ace;
      }
      if (result.ase != null) {
        throw result.ase;
      }
      if (result.ae != null) {
        throw result.ae;
      }
      throw new org.apache.thrift.TApplicationException(org.apache.thrift.TApplicationException.MISSING_RESULT, "registerGatewayResourceProfile failed: unknown result");
    }

    public org.apache.airavata.model.appcatalog.gatewayprofile.GatewayResourceProfile getGatewayResourceProfile(org.apache.airavata.model.security.AuthzToken authzToken, String gatewayID) throws org.apache.airavata.model.error.InvalidRequestException, org.apache.airavata.model.error.AiravataClientException, org.apache.airavata.model.error.AiravataSystemException, org.apache.airavata.model.error.AuthorizationException, org.apache.thrift.TException
    {
      send_getGatewayResourceProfile(authzToken, gatewayID);
      return recv_getGatewayResourceProfile();
    }

    public void send_getGatewayResourceProfile(org.apache.airavata.model.security.AuthzToken authzToken, String gatewayID) throws org.apache.thrift.TException
    {
      getGatewayResourceProfile_args args = new getGatewayResourceProfile_args();
      args.setAuthzToken(authzToken);
      args.setGatewayID(gatewayID);
      sendBase("getGatewayResourceProfile", args);
    }

    public org.apache.airavata.model.appcatalog.gatewayprofile.GatewayResourceProfile recv_getGatewayResourceProfile() throws org.apache.airavata.model.error.InvalidRequestException, org.apache.airavata.model.error.AiravataClientException, org.apache.airavata.model.error.AiravataSystemException, org.apache.airavata.model.error.AuthorizationException, org.apache.thrift.TException
    {
      getGatewayResourceProfile_result result = new getGatewayResourceProfile_result();
      receiveBase(result, "getGatewayResourceProfile");
      if (result.isSetSuccess()) {
        return result.success;
      }
      if (result.ire != null) {
        throw result.ire;
      }
      if (result.ace != null) {
        throw result.ace;
      }
      if (result.ase != null) {
        throw result.ase;
      }
      if (result.ae != null) {
        throw result.ae;
      }
      throw new org.apache.thrift.TApplicationException(org.apache.thrift.TApplicationException.MISSING_RESULT, "getGatewayResourceProfile failed: unknown result");
    }

    public boolean updateGatewayResourceProfile(org.apache.airavata.model.security.AuthzToken authzToken, String gatewayID, org.apache.airavata.model.appcatalog.gatewayprofile.GatewayResourceProfile gatewayResourceProfile) throws org.apache.airavata.model.error.InvalidRequestException, org.apache.airavata.model.error.AiravataClientException, org.apache.airavata.model.error.AiravataSystemException, org.apache.airavata.model.error.AuthorizationException, org.apache.thrift.TException
    {
      send_updateGatewayResourceProfile(authzToken, gatewayID, gatewayResourceProfile);
      return recv_updateGatewayResourceProfile();
    }

    public void send_updateGatewayResourceProfile(org.apache.airavata.model.security.AuthzToken authzToken, String gatewayID, org.apache.airavata.model.appcatalog.gatewayprofile.GatewayResourceProfile gatewayResourceProfile) throws org.apache.thrift.TException
    {
      updateGatewayResourceProfile_args args = new updateGatewayResourceProfile_args();
      args.setAuthzToken(authzToken);
      args.setGatewayID(gatewayID);
      args.setGatewayResourceProfile(gatewayResourceProfile);
      sendBase("updateGatewayResourceProfile", args);
    }

    public boolean recv_updateGatewayResourceProfile() throws org.apache.airavata.model.error.InvalidRequestException, org.apache.airavata.model.error.AiravataClientException, org.apache.airavata.model.error.AiravataSystemException, org.apache.airavata.model.error.AuthorizationException, org.apache.thrift.TException
    {
      updateGatewayResourceProfile_result result = new updateGatewayResourceProfile_result();
      receiveBase(result, "updateGatewayResourceProfile");
      if (result.isSetSuccess()) {
        return result.success;
      }
      if (result.ire != null) {
        throw result.ire;
      }
      if (result.ace != null) {
        throw result.ace;
      }
      if (result.ase != null) {
        throw result.ase;
      }
      if (result.ae != null) {
        throw result.ae;
      }
      throw new org.apache.thrift.TApplicationException(org.apache.thrift.TApplicationException.MISSING_RESULT, "updateGatewayResourceProfile failed: unknown result");
    }

    public boolean deleteGatewayResourceProfile(org.apache.airavata.model.security.AuthzToken authzToken, String gatewayID) throws org.apache.airavata.model.error.InvalidRequestException, org.apache.airavata.model.error.AiravataClientException, org.apache.airavata.model.error.AiravataSystemException, org.apache.airavata.model.error.AuthorizationException, org.apache.thrift.TException
    {
      send_deleteGatewayResourceProfile(authzToken, gatewayID);
      return recv_deleteGatewayResourceProfile();
    }

    public void send_deleteGatewayResourceProfile(org.apache.airavata.model.security.AuthzToken authzToken, String gatewayID) throws org.apache.thrift.TException
    {
      deleteGatewayResourceProfile_args args = new deleteGatewayResourceProfile_args();
      args.setAuthzToken(authzToken);
      args.setGatewayID(gatewayID);
      sendBase("deleteGatewayResourceProfile", args);
    }

    public boolean recv_deleteGatewayResourceProfile() throws org.apache.airavata.model.error.InvalidRequestException, org.apache.airavata.model.error.AiravataClientException, org.apache.airavata.model.error.AiravataSystemException, org.apache.airavata.model.error.AuthorizationException, org.apache.thrift.TException
    {
      deleteGatewayResourceProfile_result result = new deleteGatewayResourceProfile_result();
      receiveBase(result, "deleteGatewayResourceProfile");
      if (result.isSetSuccess()) {
        return result.success;
      }
      if (result.ire != null) {
        throw result.ire;
      }
      if (result.ace != null) {
        throw result.ace;
      }
      if (result.ase != null) {
        throw result.ase;
      }
      if (result.ae != null) {
        throw result.ae;
      }
      throw new org.apache.thrift.TApplicationException(org.apache.thrift.TApplicationException.MISSING_RESULT, "deleteGatewayResourceProfile failed: unknown result");
    }

    public boolean addGatewayComputeResourcePreference(org.apache.airavata.model.security.AuthzToken authzToken, String gatewayID, String computeResourceId, org.apache.airavata.model.appcatalog.gatewayprofile.ComputeResourcePreference computeResourcePreference) throws org.apache.airavata.model.error.InvalidRequestException, org.apache.airavata.model.error.AiravataClientException, org.apache.airavata.model.error.AiravataSystemException, org.apache.airavata.model.error.AuthorizationException, org.apache.thrift.TException
    {
      send_addGatewayComputeResourcePreference(authzToken, gatewayID, computeResourceId, computeResourcePreference);
      return recv_addGatewayComputeResourcePreference();
    }

    public void send_addGatewayComputeResourcePreference(org.apache.airavata.model.security.AuthzToken authzToken, String gatewayID, String computeResourceId, org.apache.airavata.model.appcatalog.gatewayprofile.ComputeResourcePreference computeResourcePreference) throws org.apache.thrift.TException
    {
      addGatewayComputeResourcePreference_args args = new addGatewayComputeResourcePreference_args();
      args.setAuthzToken(authzToken);
      args.setGatewayID(gatewayID);
      args.setComputeResourceId(computeResourceId);
      args.setComputeResourcePreference(computeResourcePreference);
      sendBase("addGatewayComputeResourcePreference", args);
    }

    public boolean recv_addGatewayComputeResourcePreference() throws org.apache.airavata.model.error.InvalidRequestException, org.apache.airavata.model.error.AiravataClientException, org.apache.airavata.model.error.AiravataSystemException, org.apache.airavata.model.error.AuthorizationException, org.apache.thrift.TException
    {
      addGatewayComputeResourcePreference_result result = new addGatewayComputeResourcePreference_result();
      receiveBase(result, "addGatewayComputeResourcePreference");
      if (result.isSetSuccess()) {
        return result.success;
      }
      if (result.ire != null) {
        throw result.ire;
      }
      if (result.ace != null) {
        throw result.ace;
      }
      if (result.ase != null) {
        throw result.ase;
      }
      if (result.ae != null) {
        throw result.ae;
      }
      throw new org.apache.thrift.TApplicationException(org.apache.thrift.TApplicationException.MISSING_RESULT, "addGatewayComputeResourcePreference failed: unknown result");
    }

    public boolean addGatewayDataStoragePreference(org.apache.airavata.model.security.AuthzToken authzToken, String gatewayID, String dataMoveId, org.apache.airavata.model.appcatalog.gatewayprofile.DataStoragePreference dataStoragePreference) throws org.apache.airavata.model.error.InvalidRequestException, org.apache.airavata.model.error.AiravataClientException, org.apache.airavata.model.error.AiravataSystemException, org.apache.airavata.model.error.AuthorizationException, org.apache.thrift.TException
    {
      send_addGatewayDataStoragePreference(authzToken, gatewayID, dataMoveId, dataStoragePreference);
      return recv_addGatewayDataStoragePreference();
    }

    public void send_addGatewayDataStoragePreference(org.apache.airavata.model.security.AuthzToken authzToken, String gatewayID, String dataMoveId, org.apache.airavata.model.appcatalog.gatewayprofile.DataStoragePreference dataStoragePreference) throws org.apache.thrift.TException
    {
      addGatewayDataStoragePreference_args args = new addGatewayDataStoragePreference_args();
      args.setAuthzToken(authzToken);
      args.setGatewayID(gatewayID);
      args.setDataMoveId(dataMoveId);
      args.setDataStoragePreference(dataStoragePreference);
      sendBase("addGatewayDataStoragePreference", args);
    }

    public boolean recv_addGatewayDataStoragePreference() throws org.apache.airavata.model.error.InvalidRequestException, org.apache.airavata.model.error.AiravataClientException, org.apache.airavata.model.error.AiravataSystemException, org.apache.airavata.model.error.AuthorizationException, org.apache.thrift.TException
    {
      addGatewayDataStoragePreference_result result = new addGatewayDataStoragePreference_result();
      receiveBase(result, "addGatewayDataStoragePreference");
      if (result.isSetSuccess()) {
        return result.success;
      }
      if (result.ire != null) {
        throw result.ire;
      }
      if (result.ace != null) {
        throw result.ace;
      }
      if (result.ase != null) {
        throw result.ase;
      }
      if (result.ae != null) {
        throw result.ae;
      }
      throw new org.apache.thrift.TApplicationException(org.apache.thrift.TApplicationException.MISSING_RESULT, "addGatewayDataStoragePreference failed: unknown result");
    }

    public org.apache.airavata.model.appcatalog.gatewayprofile.ComputeResourcePreference getGatewayComputeResourcePreference(org.apache.airavata.model.security.AuthzToken authzToken, String gatewayID, String computeResourceId) throws org.apache.airavata.model.error.InvalidRequestException, org.apache.airavata.model.error.AiravataClientException, org.apache.airavata.model.error.AiravataSystemException, org.apache.airavata.model.error.AuthorizationException, org.apache.thrift.TException
    {
      send_getGatewayComputeResourcePreference(authzToken, gatewayID, computeResourceId);
      return recv_getGatewayComputeResourcePreference();
    }

    public void send_getGatewayComputeResourcePreference(org.apache.airavata.model.security.AuthzToken authzToken, String gatewayID, String computeResourceId) throws org.apache.thrift.TException
    {
      getGatewayComputeResourcePreference_args args = new getGatewayComputeResourcePreference_args();
      args.setAuthzToken(authzToken);
      args.setGatewayID(gatewayID);
      args.setComputeResourceId(computeResourceId);
      sendBase("getGatewayComputeResourcePreference", args);
    }

    public org.apache.airavata.model.appcatalog.gatewayprofile.ComputeResourcePreference recv_getGatewayComputeResourcePreference() throws org.apache.airavata.model.error.InvalidRequestException, org.apache.airavata.model.error.AiravataClientException, org.apache.airavata.model.error.AiravataSystemException, org.apache.airavata.model.error.AuthorizationException, org.apache.thrift.TException
    {
      getGatewayComputeResourcePreference_result result = new getGatewayComputeResourcePreference_result();
      receiveBase(result, "getGatewayComputeResourcePreference");
      if (result.isSetSuccess()) {
        return result.success;
      }
      if (result.ire != null) {
        throw result.ire;
      }
      if (result.ace != null) {
        throw result.ace;
      }
      if (result.ase != null) {
        throw result.ase;
      }
      if (result.ae != null) {
        throw result.ae;
      }
      throw new org.apache.thrift.TApplicationException(org.apache.thrift.TApplicationException.MISSING_RESULT, "getGatewayComputeResourcePreference failed: unknown result");
    }

    public org.apache.airavata.model.appcatalog.gatewayprofile.DataStoragePreference getGatewayDataStoragePreference(org.apache.airavata.model.security.AuthzToken authzToken, String gatewayID, String dataMoveId) throws org.apache.airavata.model.error.InvalidRequestException, org.apache.airavata.model.error.AiravataClientException, org.apache.airavata.model.error.AiravataSystemException, org.apache.airavata.model.error.AuthorizationException, org.apache.thrift.TException
    {
      send_getGatewayDataStoragePreference(authzToken, gatewayID, dataMoveId);
      return recv_getGatewayDataStoragePreference();
    }

    public void send_getGatewayDataStoragePreference(org.apache.airavata.model.security.AuthzToken authzToken, String gatewayID, String dataMoveId) throws org.apache.thrift.TException
    {
      getGatewayDataStoragePreference_args args = new getGatewayDataStoragePreference_args();
      args.setAuthzToken(authzToken);
      args.setGatewayID(gatewayID);
      args.setDataMoveId(dataMoveId);
      sendBase("getGatewayDataStoragePreference", args);
    }

    public org.apache.airavata.model.appcatalog.gatewayprofile.DataStoragePreference recv_getGatewayDataStoragePreference() throws org.apache.airavata.model.error.InvalidRequestException, org.apache.airavata.model.error.AiravataClientException, org.apache.airavata.model.error.AiravataSystemException, org.apache.airavata.model.error.AuthorizationException, org.apache.thrift.TException
    {
      getGatewayDataStoragePreference_result result = new getGatewayDataStoragePreference_result();
      receiveBase(result, "getGatewayDataStoragePreference");
      if (result.isSetSuccess()) {
        return result.success;
      }
      if (result.ire != null) {
        throw result.ire;
      }
      if (result.ace != null) {
        throw result.ace;
      }
      if (result.ase != null) {
        throw result.ase;
      }
      if (result.ae != null) {
        throw result.ae;
      }
      throw new org.apache.thrift.TApplicationException(org.apache.thrift.TApplicationException.MISSING_RESULT, "getGatewayDataStoragePreference failed: unknown result");
    }

    public List<org.apache.airavata.model.appcatalog.gatewayprofile.ComputeResourcePreference> getAllGatewayComputeResourcePreferences(org.apache.airavata.model.security.AuthzToken authzToken, String gatewayID) throws org.apache.airavata.model.error.InvalidRequestException, org.apache.airavata.model.error.AiravataClientException, org.apache.airavata.model.error.AiravataSystemException, org.apache.airavata.model.error.AuthorizationException, org.apache.thrift.TException
    {
      send_getAllGatewayComputeResourcePreferences(authzToken, gatewayID);
      return recv_getAllGatewayComputeResourcePreferences();
    }

    public void send_getAllGatewayComputeResourcePreferences(org.apache.airavata.model.security.AuthzToken authzToken, String gatewayID) throws org.apache.thrift.TException
    {
      getAllGatewayComputeResourcePreferences_args args = new getAllGatewayComputeResourcePreferences_args();
      args.setAuthzToken(authzToken);
      args.setGatewayID(gatewayID);
      sendBase("getAllGatewayComputeResourcePreferences", args);
    }

    public List<org.apache.airavata.model.appcatalog.gatewayprofile.ComputeResourcePreference> recv_getAllGatewayComputeResourcePreferences() throws org.apache.airavata.model.error.InvalidRequestException, org.apache.airavata.model.error.AiravataClientException, org.apache.airavata.model.error.AiravataSystemException, org.apache.airavata.model.error.AuthorizationException, org.apache.thrift.TException
    {
      getAllGatewayComputeResourcePreferences_result result = new getAllGatewayComputeResourcePreferences_result();
      receiveBase(result, "getAllGatewayComputeResourcePreferences");
      if (result.isSetSuccess()) {
        return result.success;
      }
      if (result.ire != null) {
        throw result.ire;
      }
      if (result.ace != null) {
        throw result.ace;
      }
      if (result.ase != null) {
        throw result.ase;
      }
      if (result.ae != null) {
        throw result.ae;
      }
      throw new org.apache.thrift.TApplicationException(org.apache.thrift.TApplicationException.MISSING_RESULT, "getAllGatewayComputeResourcePreferences failed: unknown result");
    }

    public List<org.apache.airavata.model.appcatalog.gatewayprofile.DataStoragePreference> getAllGatewayDataStoragePreferences(org.apache.airavata.model.security.AuthzToken authzToken, String gatewayID) throws org.apache.airavata.model.error.InvalidRequestException, org.apache.airavata.model.error.AiravataClientException, org.apache.airavata.model.error.AiravataSystemException, org.apache.airavata.model.error.AuthorizationException, org.apache.thrift.TException
    {
      send_getAllGatewayDataStoragePreferences(authzToken, gatewayID);
      return recv_getAllGatewayDataStoragePreferences();
    }

    public void send_getAllGatewayDataStoragePreferences(org.apache.airavata.model.security.AuthzToken authzToken, String gatewayID) throws org.apache.thrift.TException
    {
      getAllGatewayDataStoragePreferences_args args = new getAllGatewayDataStoragePreferences_args();
      args.setAuthzToken(authzToken);
      args.setGatewayID(gatewayID);
      sendBase("getAllGatewayDataStoragePreferences", args);
    }

    public List<org.apache.airavata.model.appcatalog.gatewayprofile.DataStoragePreference> recv_getAllGatewayDataStoragePreferences() throws org.apache.airavata.model.error.InvalidRequestException, org.apache.airavata.model.error.AiravataClientException, org.apache.airavata.model.error.AiravataSystemException, org.apache.airavata.model.error.AuthorizationException, org.apache.thrift.TException
    {
      getAllGatewayDataStoragePreferences_result result = new getAllGatewayDataStoragePreferences_result();
      receiveBase(result, "getAllGatewayDataStoragePreferences");
      if (result.isSetSuccess()) {
        return result.success;
      }
      if (result.ire != null) {
        throw result.ire;
      }
      if (result.ace != null) {
        throw result.ace;
      }
      if (result.ase != null) {
        throw result.ase;
      }
      if (result.ae != null) {
        throw result.ae;
      }
      throw new org.apache.thrift.TApplicationException(org.apache.thrift.TApplicationException.MISSING_RESULT, "getAllGatewayDataStoragePreferences failed: unknown result");
    }

    public List<org.apache.airavata.model.appcatalog.gatewayprofile.GatewayResourceProfile> getAllGatewayResourceProfiles(org.apache.airavata.model.security.AuthzToken authzToken) throws org.apache.airavata.model.error.InvalidRequestException, org.apache.airavata.model.error.AiravataClientException, org.apache.airavata.model.error.AiravataSystemException, org.apache.airavata.model.error.AuthorizationException, org.apache.thrift.TException
    {
      send_getAllGatewayResourceProfiles(authzToken);
      return recv_getAllGatewayResourceProfiles();
    }

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

    public List<org.apache.airavata.model.appcatalog.gatewayprofile.GatewayResourceProfile> recv_getAllGatewayResourceProfiles() throws org.apache.airavata.model.error.InvalidRequestException, org.apache.airavata.model.error.AiravataClientException, org.apache.airavata.model.error.AiravataSystemException, org.apache.airavata.model.error.AuthorizationException, org.apache.thrift.TException
    {
      getAllGatewayResourceProfiles_result result = new getAllGatewayResourceProfiles_result();
      receiveBase(result, "getAllGatewayResourceProfiles");
      if (result.isSetSuccess()) {
        return result.success;
      }
      if (result.ire != null) {
        throw result.ire;
      }
      if (result.ace != null) {
        throw result.ace;
      }
      if (result.ase != null) {
        throw result.ase;
      }
      if (result.ae != null) {
        throw result.ae;
      }
      throw new org.apache.thrift.TApplicationException(org.apache.thrift.TApplicationException.MISSING_RESULT, "getAllGatewayResourceProfiles failed: unknown result");
    }

    public boolean updateGatewayComputeResourcePreference(org.apache.airavata.model.security.AuthzToken authzToken, String gatewayID, String computeResourceId, org.apache.airavata.model.appcatalog.gatewayprofile.ComputeResourcePreference computeResourcePreference) throws org.apache.airavata.model.error.InvalidRequestException, org.apache.airavata.model.error.AiravataClientException, org.apache.airavata.model.error.AiravataSystemException, org.apache.airavata.model.error.AuthorizationException, org.apache.thrift.TException
    {
      send_updateGatewayComputeResourcePreference(authzToken, gatewayID, computeResourceId, computeResourcePreference);
      return recv_updateGatewayComputeResourcePreference();
    }

    public void send_updateGatewayComputeResourcePreference(org.apache.airavata.model.security.AuthzToken authzToken, String gatewayID, String computeResourceId, org.apache.airavata.model.appcatalog.gatewayprofile.ComputeResourcePreference computeResourcePreference) throws org.apache.thrift.TException
    {
      updateGatewayComputeResourcePreference_args args = new updateGatewayComputeResourcePreference_args();
      args.setAuthzToken(authzToken);
      args.setGatewayID(gatewayID);
      args.setComputeResourceId(computeResourceId);
      args.setComputeResourcePreference(computeResourcePreference);
      sendBase("updateGatewayComputeResourcePreference", args);
    }

    public boolean recv_updateGatewayComputeResourcePreference() throws org.apache.airavata.model.error.InvalidRequestException, org.apache.airavata.model.error.AiravataClientException, org.apache.airavata.model.error.AiravataSystemException, org.apache.airavata.model.error.AuthorizationException, org.apache.thrift.TException
    {
      updateGatewayComputeResourcePreference_result result = new updateGatewayComputeResourcePreference_result();
      receiveBase(result, "updateGatewayComputeResourcePreference");
      if (result.isSetSuccess()) {
        return result.success;
      }
      if (result.ire != null) {
        throw result.ire;
      }
      if (result.ace != null) {
        throw result.ace;
      }
      if (result.ase != null) {
        throw result.ase;
      }
      if (result.ae != null) {
        throw result.ae;
      }
      throw new org.apache.thrift.TApplicationException(org.apache.thrift.TApplicationException.MISSING_RESULT, "updateGatewayComputeResourcePreference failed: unknown result");
    }

    public boolean updateGatewayDataStoragePreference(org.apache.airavata.model.security.AuthzToken authzToken, String gatewayID, String dataMoveId, org.apache.airavata.model.appcatalog.gatewayprofile.DataStoragePreference dataStoragePreference) throws org.apache.airavata.model.error.InvalidRequestException, org.apache.airavata.model.error.AiravataClientException, org.apache.airavata.model.error.AiravataSystemException, org.apache.airavata.model.error.AuthorizationException, org.apache.thrift.TException
    {
      send_updateGatewayDataStoragePreference(authzToken, gatewayID, dataMoveId, dataStoragePreference);
      return recv_updateGatewayDataStoragePreference();
    }

    public void send_updateGatewayDataStoragePreference(org.apache.airavata.model.security.AuthzToken authzToken, String gatewayID, String dataMoveId, org.apache.airavata.model.appcatalog.gatewayprofile.DataStoragePreference dataStoragePreference) throws org.apache.thrift.TException
    {
      updateGatewayDataStoragePreference_args args = new updateGatewayDataStoragePreference_args();
      args.setAuthzToken(authzToken);
      args.setGatewayID(gatewayID);
      args.setDataMoveId(dataMoveId);
      args.setDataStoragePreference(dataStoragePreference);
      sendBase("updateGatewayDataStoragePreference", args);
    }

    public boolean recv_updateGatewayDataStoragePreference() throws org.apache.airavata.model.error.InvalidRequestException, org.apache.airavata.model.error.AiravataClientException, org.apache.airavata.model.error.AiravataSystemException, org.apache.airavata.model.error.AuthorizationException, org.apache.thrift.TException
    {
      updateGatewayDataStoragePreference_result result = new updateGatewayDataStoragePreference_result();
      receiveBase(result, "updateGatewayDataStoragePreference");
      if (result.isSetSuccess()) {
        return result.success;
      }
      if (result.ire != null) {
        throw result.ire;
      }
      if (result.ace != null) {
        throw result.ace;
      }
      if (result.ase != null) {
        throw result.ase;
      }
      if (result.ae != null) {
        throw result.ae;
      }
      throw new org.apache.thrift.TApplicationException(org.apache.thrift.TApplicationException.MISSING_RESULT, "updateGatewayDataStoragePreference failed: unknown result");
    }

    public boolean deleteGatewayComputeResourcePreference(org.apache.airavata.model.security.AuthzToken authzToken, String gatewayID, String computeResourceId) throws org.apache.airavata.model.error.InvalidRequestException, org.apache.airavata.model.error.AiravataClientException, org.apache.airavata.model.error.AiravataSystemException, org.apache.airavata.model.error.AuthorizationException, org.apache.thrift.TException
    {
      send_deleteGatewayComputeResourcePreference(authzToken, gatewayID, computeResourceId);
      return recv_deleteGatewayComputeResourcePreference();
    }

    public void send_deleteGatewayComputeResourcePreference(org.apache.airavata.model.security.AuthzToken authzToken, String gatewayID, String computeResourceId) throws org.apache.thrift.TException
    {
      deleteGatewayComputeResourcePreference_args args = new deleteGatewayComputeResourcePreference_args();
      args.setAuthzToken(authzToken);
      args.setGatewayID(gatewayID);
      args.setComputeResourceId(computeResourceId);
      sendBase("deleteGatewayComputeResourcePreference", args);
    }

    public boolean recv_deleteGatewayComputeResourcePreference() throws org.apache.airavata.model.error.InvalidRequestException, org.apache.airavata.model.error.AiravataClientException, org.apache.airavata.model.error.AiravataSystemException, org.apache.airavata.model.error.AuthorizationException, org.apache.thrift.TException
    {
      deleteGatewayComputeResourcePreference_result result = new deleteGatewayComputeResourcePreference_result();
      receiveBase(result, "deleteGatewayComputeResourcePreference");
      if (result.isSetSuccess()) {
        return result.success;
      }
      if (result.ire != null) {
        throw result.ire;
      }
      if (result.ace != null) {
        throw result.ace;
      }
      if (result.ase != null) {
        throw result.ase;
      }
      if (result.ae != null) {
        throw result.ae;
      }
      throw new org.apache.thrift.TApplicationException(org.apache.thrift.TApplicationException.MISSING_RESULT, "deleteGatewayComputeResourcePreference failed: unknown result");
    }

    public boolean deleteGatewayDataStoragePreference(org.apache.airavata.model.security.AuthzToken authzToken, String gatewayID, String dataMoveId) throws org.apache.airavata.model.error.InvalidRequestException, org.apache.airavata.model.error.AiravataClientException, org.apache.airavata.model.error.AiravataSystemException, org.apache.airavata.model.error.AuthorizationException, org.apache.thrift.TException
    {
      send_deleteGatewayDataStoragePreference(authzToken, gatewayID, dataMoveId);
      return recv_deleteGatewayDataStoragePreference();
    }

    public void send_deleteGatewayDataStoragePreference(org.apache.airavata.model.security.AuthzToken authzToken, String gatewayID, String dataMoveId) throws org.apache.thrift.TException
    {
      deleteGatewayDataStoragePreference_args args = new deleteGatewayDataStoragePreference_args();
      args.setAuthzToken(authzToken);
      args.setGatewayID(gatewayID);
      args.setDataMoveId(dataMoveId);
      sendBase("deleteGatewayDataStoragePreference", args);
    }

    public boolean recv_deleteGatewayDataStoragePreference() throws org.apache.airavata.model.error.InvalidRequestException, org.apache.airavata.model.error.AiravataClientException, org.apache.airavata.model.error.AiravataSystemException, org.apache.airavata.model.error.AuthorizationException, org.apache.thrift.TException
    {
      deleteGatewayDataStoragePreference_result result = new deleteGatewayDataStoragePreference_result();
      receiveBase(result, "deleteGatewayDataStoragePreference");
      if (result.isSetSuccess()) {
        return result.success;
      }
      if (result.ire != null) {
        throw result.ire;
      }
      if (result.ace != null) {
        throw result.ace;
      }
      if (result.ase != null) {
        throw result.ase;
      }
      if (result.ae != null) {
        throw result.ae;
      }
      throw new org.apache.thrift.TApplicationException(org.apache.thrift.TApplicationException.MISSING_RESULT, "deleteGatewayDataStoragePreference failed: unknown result");
    }

    public List<String> getAllWorkflows(org.apache.airavata.model.security.AuthzToken authzToken, String gatewayId) throws org.apache.airavata.model.error.InvalidRequestException, org.apache.airavata.model.error.AiravataClientException, org.apache.airavata.model.error.AiravataSystemException, org.apache.airavata.model.error.AuthorizationException, org.apache.thrift.TException
    {
      send_getAllWorkflows(authzToken, gatewayId);
      return recv_getAllWorkflows();
    }

    public void send_getAllWorkflows(org.apache.airavata.model.security.AuthzToken authzToken, String gatewayId) throws org.apache.thrift.TException
    {
      getAllWorkflows_args args = new getAllWorkflows_args();
      args.setAuthzToken(authzToken);
      args.setGatewayId(gatewayId);
      sendBase("getAllWorkflows", args);
    }

    public List<String> recv_getAllWorkflows() throws org.apache.airavata.model.error.InvalidRequestException, org.apache.airavata.model.error.AiravataClientException, org.apache.airavata.model.error.AiravataSystemException, org.apache.airavata.model.error.AuthorizationException, org.apache.thrift.TException
    {
      getAllWorkflows_result result = new getAllWorkflows_result();
      receiveBase(result, "getAllWorkflows");
      if (result.isSetSuccess()) {
        return result.success;
      }
      if (result.ire != null) {
        throw result.ire;
      }
      if (result.ace != null) {
        throw result.ace;
      }
      if (result.ase != null) {
        throw result.ase;
      }
      if (result.ae != null) {
        throw result.ae;
      }
      throw new org.apache.thrift.TApplicationException(org.apache.thrift.TApplicationException.MISSING_RESULT, "getAllWorkflows failed: unknown result");
    }

    public org.apache.airavata.model.Workflow getWorkflow(org.apache.airavata.model.security.AuthzToken authzToken, String workflowTemplateId) throws org.apache.airavata.model.error.InvalidRequestException, org.apache.airavata.model.error.AiravataClientException, org.apache.airavata.model.error.AiravataSystemException, org.apache.airavata.model.error.AuthorizationException, org.apache.thrift.TException
    {
      send_getWorkflow(authzToken, workflowTemplateId);
      return recv_getWorkflow();
    }

    public void send_getWorkflow(org.apache.airavata.model.security.AuthzToken authzToken, String workflowTemplateId) throws org.apache.thrift.TException
    {
      getWorkflow_args args = new getWorkflow_args();
      args.setAuthzToken(authzToken);
      args.setWorkflowTemplateId(workflowTemplateId);
      sendBase("getWorkflow", args);
    }

    public org.apache.airavata.model.Workflow recv_getWorkflow() throws org.apache.airavata.model.error.InvalidRequestException, org.apache.airavata.model.error.AiravataClientException, org.apache.airavata.model.error.AiravataSystemException, org.apache.airavata.model.error.AuthorizationException, org.apache.thrift.TException
    {
      getWorkflow_result result = new getWorkflow_result();
      receiveBase(result, "getWorkflow");
      if (result.isSetSuccess()) {
        return result.success;
      }
      if (result.ire != null) {
        throw result.ire;
      }
      if (result.ace != null) {
        throw result.ace;
      }
      if (result.ase != null) {
        throw result.ase;
      }
      if (result.ae != null) {
        throw result.ae;
      }
      throw new org.apache.thrift.TApplicationException(org.apache.thrift.TApplicationException.MISSING_RESULT, "getWorkflow failed: unknown result");
    }

    public void deleteWorkflow(org.apache.airavata.model.security.AuthzToken authzToken, String workflowTemplateId) throws org.apache.airavata.model.error.InvalidRequestException, org.apache.airavata.model.error.AiravataClientException, org.apache.airavata.model.error.AiravataSystemException, org.apache.airavata.model.error.AuthorizationException, org.apache.thrift.TException
    {
      send_deleteWorkflow(authzToken, workflowTemplateId);
      recv_deleteWorkflow();
    }

    public void send_deleteWorkflow(org.apache.airavata.model.security.AuthzToken authzToken, String workflowTemplateId) throws org.apache.thrift.TException
    {
      deleteWorkflow_args args = new deleteWorkflow_args();
      args.setAuthzToken(authzToken);
      args.setWorkflowTemplateId(workflowTemplateId);
      sendBase("deleteWorkflow", args);
    }

    public void recv_deleteWorkflow() throws org.apache.airavata.model.error.InvalidRequestException, org.apache.airavata.model.error.AiravataClientException, org.apache.airavata.model.error.AiravataSystemException, org.apache.airavata.model.error.AuthorizationException, org.apache.thrift.TException
    {
      deleteWorkflow_result result = new deleteWorkflow_result();
      receiveBase(result, "deleteWorkflow");
      if (result.ire != null) {
        throw result.ire;
      }
      if (result.ace != null) {
        throw result.ace;
      }
      if (result.ase != null) {
        throw result.ase;
      }
      if (result.ae != null) {
        throw result.ae;
      }
      return;
    }

    public String registerWorkflow(org.apache.airavata.model.security.AuthzToken authzToken, String gatewayId, org.apache.airavata.model.Workflow workflow) throws org.apache.airavata.model.error.InvalidRequestException, org.apache.airavata.model.error.AiravataClientException, org.apache.airavata.model.error.AiravataSystemException, org.apache.airavata.model.error.AuthorizationException, org.apache.thrift.TException
    {
      send_registerWorkflow(authzToken, gatewayId, workflow);
      return recv_registerWorkflow();
    }

    public void send_registerWorkflow(org.apache.airavata.model.security.AuthzToken authzToken, String gatewayId, org.apache.airavata.model.Workflow workflow) throws org.apache.thrift.TException
    {
      registerWorkflow_args args = new registerWorkflow_args();
      args.setAuthzToken(authzToken);
      args.setGatewayId(gatewayId);
      args.setWorkflow(workflow);
      sendBase("registerWorkflow", args);
    }

    public String recv_registerWorkflow() throws org.apache.airavata.model.error.InvalidRequestException, org.apache.airavata.model.error.AiravataClientException, org.apache.airavata.model.error.AiravataSystemException, org.apache.airavata.model.error.AuthorizationException, org.apache.thrift.TException
    {
      registerWorkflow_result result = new registerWorkflow_result();
      receiveBase(result, "registerWorkflow");
      if (result.isSetSuccess()) {
        return result.success;
      }
      if (result.ire != null) {
        throw result.ire;
      }
      if (result.ace != null) {
        throw result.ace;
      }
      if (result.ase != null) {
        throw result.ase;
      }
      if (result.ae != null) {
        throw result.ae;
      }
      throw new org.apache.thrift.TApplicationException(org.apache.thrift.TApplicationException.MISSING_RESULT, "registerWorkflow failed: unknown result");
    }

    public void updateWorkflow(org.apache.airavata.model.security.AuthzToken authzToken, String workflowTemplateId, org.apache.airavata.model.Workflow workflow) throws org.apache.airavata.model.error.InvalidRequestException, org.apache.airavata.model.error.AiravataClientException, org.apache.airavata.model.error.AiravataSystemException, org.apache.airavata.model.error.AuthorizationException, org.apache.thrift.TException
    {
      send_updateWorkflow(authzToken, workflowTemplateId, workflow);
      recv_updateWorkflow();
    }

    public void send_updateWorkflow(org.apache.airavata.model.security.AuthzToken authzToken, String workflowTemplateId, org.apache.airavata.model.Workflow workflow) throws org.apache.thrift.TException
    {
      updateWorkflow_args args = new updateWorkflow_args();
      args.setAuthzToken(authzToken);
      args.setWorkflowTemplateId(workflowTemplateId);
      args.setWorkflow(workflow);
      sendBase("updateWorkflow", args);
    }

    public void recv_updateWorkflow() throws org.apache.airavata.model.error.InvalidRequestException, org.apache.airavata.model.error.AiravataClientException, org.apache.airavata.model.error.AiravataSystemException, org.apache.airavata.model.error.AuthorizationException, org.apache.thrift.TException
    {
      updateWorkflow_result result = new updateWorkflow_result();
      receiveBase(result, "updateWorkflow");
      if (result.ire != null) {
        throw result.ire;
      }
      if (result.ace != null) {
        throw result.ace;
      }
      if (result.ase != null) {
        throw result.ase;
      }
      if (result.ae != null) {
        throw result.ae;
      }
      return;
    }

    public String getWorkflowTemplateId(org.apache.airavata.model.security.AuthzToken authzToken, String workflowName) throws org.apache.airavata.model.error.InvalidRequestException, org.apache.airavata.model.error.AiravataClientException, org.apache.airavata.model.error.AiravataSystemException, org.apache.airavata.model.error.AuthorizationException, org.apache.thrift.TException
    {
      send_getWorkflowTemplateId(authzToken, workflowName);
      return recv_getWorkflowTemplateId();
    }

    public void send_getWorkflowTemplateId(org.apache.airavata.model.security.AuthzToken authzToken, String workflowName) throws org.apache.thrift.TException
    {
      getWorkflowTemplateId_args args = new getWorkflowTemplateId_args();
      args.setAuthzToken(authzToken);
      args.setWorkflowName(workflowName);
      sendBase("getWorkflowTemplateId", args);
    }

    public String recv_getWorkflowTemplateId() throws org.apache.airavata.model.error.InvalidRequestException, org.apache.airavata.model.error.AiravataClientException, org.apache.airavata.model.error.AiravataSystemException, org.apache.airavata.model.error.AuthorizationException, org.apache.thrift.TException
    {
      getWorkflowTemplateId_result result = new getWorkflowTemplateId_result();
      receiveBase(result, "getWorkflowTemplateId");
      if (result.isSetSuccess()) {
        return result.success;
      }
      if (result.ire != null) {
        throw result.ire;
      }
      if (result.ace != null) {
        throw result.ace;
      }
      if (result.ase != null) {
        throw result.ase;
      }
      if (result.ae != null) {
        throw result.ae;
      }
      throw new org.apache.thrift.TApplicationException(org.apache.thrift.TApplicationException.MISSING_RESULT, "getWorkflowTemplateId failed: unknown result");
    }

    public boolean isWorkflowExistWithName(org.apache.airavata.model.security.AuthzToken authzToken, String workflowName) throws org.apache.airavata.model.error.InvalidRequestException, org.apache.airavata.model.error.AiravataClientException, org.apache.airavata.model.error.AiravataSystemException, org.apache.airavata.model.error.AuthorizationException, org.apache.thrift.TException
    {
      send_isWorkflowExistWithName(authzToken, workflowName);
      return recv_isWorkflowExistWithName();
    }

    public void send_isWorkflowExistWithName(org.apache.airavata.model.security.AuthzToken authzToken, String workflowName) throws org.apache.thrift.TException
    {
      isWorkflowExistWithName_args args = new isWorkflowExistWithName_args();
      args.setAuthzToken(authzToken);
      args.setWorkflowName(workflowName);
      sendBase("isWorkflowExistWithName", args);
    }

    public boolean recv_isWorkflowExistWithName() throws org.apache.airavata.model.error.InvalidRequestException, org.apache.airavata.model.error.AiravataClientException, org.apache.airavata.model.error.AiravataSystemException, org.apache.airavata.model.error.AuthorizationException, org.apache.thrift.TException
    {
      isWorkflowExistWithName_result result = new isWorkflowExistWithName_result();
      receiveBase(result, "isWorkflowExistWithName");
      if (result.isSetSuccess()) {
        return result.success;
      }
      if (result.ire != null) {
        throw result.ire;
      }
      if (result.ace != null) {
        throw result.ace;
      }
      if (result.ase != null) {
        throw result.ase;
      }
      if (result.ae != null) {
        throw result.ae;
      }
      throw new org.apache.thrift.TApplicationException(org.apache.thrift.TApplicationException.MISSING_RESULT, "isWorkflowExistWithName failed: unknown result");
    }

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

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

    public void getAPIVersion(org.apache.airavata.model.security.AuthzToken authzToken, org.apache.thrift.async.AsyncMethodCallback resultHandler) throws org.apache.thrift.TException {
      checkReady();
      getAPIVersion_call method_call = new getAPIVersion_call(authzToken, resultHandler, this, ___protocolFactory, ___transport);
      this.___currentMethod = method_call;
      ___manager.call(method_call);
    }

    public static class getAPIVersion_call extends org.apache.thrift.async.TAsyncMethodCall {
      private org.apache.airavata.model.security.AuthzToken authzToken;
      public getAPIVersion_call(org.apache.airavata.model.security.AuthzToken authzToken, org.apache.thrift.async.AsyncMethodCallback resultHandler, org.apache.thrift.async.TAsyncClient client, org.apache.thrift.protocol.TProtocolFactory protocolFactory, org.apache.thrift.transport.TNonblockingTransport transport) throws org.apache.thrift.TException {
        super(client, protocolFactory, transport, resultHandler, false);
        this.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("getAPIVersion", org.apache.thrift.protocol.TMessageType.CALL, 0));
        getAPIVersion_args args = new getAPIVersion_args();
        args.setAuthzToken(authzToken);
        args.write(prot);
        prot.writeMessageEnd();
      }

      public String getResult() throws org.apache.airavata.model.error.InvalidRequestException, org.apache.airavata.model.error.AiravataClientException, org.apache.airavata.model.error.AiravataSystemException, org.apache.airavata.model.error.AuthorizationException, org.apache.thrift.TException {
        if (getState() != org.apache.thrift.async.TAsyncMethodCall.State.RESPONSE_READ) {
          throw new IllegalStateException("Method call not finished!");
        }
        org.apache.thrift.transport.TMemoryInputTransport memoryTransport = new org.apache.thrift.transport.TMemoryInputTransport(getFrameBuffer().array());
        org.apache.thrift.protocol.TProtocol prot = client.getProtocolFactory().getProtocol(memoryTransport);
        return (new Client(prot)).recv_getAPIVersion();
      }
    }

    public void addGateway(org.apache.airavata.model.security.AuthzToken authzToken, org.apache.airavata.model.workspace.Gateway gateway, org.apache.thrift.async.AsyncMethodCallback 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 {
      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 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 String getResult() throws org.apache.airavata.model.error.InvalidRequestException, org.apache.airavata.model.error.AiravataClientException, org.apache.airavata.model.error.AiravataSystemException, org.apache.airavata.model.error.AuthorizationException, org.apache.thrift.TException {
        if (getState() != org.apache.thrift.async.TAsyncMethodCall.State.RESPONSE_READ) {
          throw new IllegalStateException("Method call not finished!");
        }
        org.apache.thrift.transport.TMemoryInputTransport memoryTransport = new org.apache.thrift.transport.TMemoryInputTransport(getFrameBuffer().array());
        org.apache.thrift.protocol.TProtocol prot = client.getProtocolFactory().getProtocol(memoryTransport);
        return (new Client(prot)).recv_addGateway();
      }
    }

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

    public static class updateGateway_call extends org.apache.thrift.async.TAsyncMethodCall {
      private org.apache.airavata.model.security.AuthzToken authzToken;
      private String gatewayId;
      private org.apache.airavata.model.workspace.Gateway updatedGateway;
      public updateGateway_call(org.apache.airavata.model.security.AuthzToken authzToken, String gatewayId, org.apache.airavata.model.workspace.Gateway updatedGateway, org.apache.thrift.async.AsyncMethodCallback resultHandler, org.apache.thrift.async.TAsyncClient client, org.apache.thrift.protocol.TProtocolFactory protocolFactory, org.apache.thrift.transport.TNonblockingTransport transport) throws org.apache.thrift.TException {
        super(client, protocolFactory, transport, resultHandler, false);
        this.authzToken = authzToken;
        this.gatewayId = gatewayId;
        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.setGatewayId(gatewayId);
        args.setUpdatedGateway(updatedGateway);
        args.write(prot);
        prot.writeMessageEnd();
      }

      public void getResult() throws org.apache.airavata.model.error.InvalidRequestException, org.apache.airavata.model.error.AiravataClientException, org.apache.airavata.model.error.AiravataSystemException, org.apache.airavata.model.error.AuthorizationException, org.apache.thrift.TException {
        if (getState() != org.apache.thrift.async.TAsyncMethodCall.State.RESPONSE_READ) {
          throw new IllegalStateException("Method call not finished!");
        }
        org.apache.thrift.transport.TMemoryInputTransport memoryTransport = new org.apache.thrift.transport.TMemoryInputTransport(getFrameBuffer().array());
        org.apache.thrift.protocol.TProtocol prot = client.getProtocolFactory().getProtocol(memoryTransport);
        (new Client(prot)).recv_updateGateway();
      }
    }

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

    public static class getGateway_call extends org.apache.thrift.async.TAsyncMethodCall {
      private org.apache.airavata.model.security.AuthzToken authzToken;
      private String gatewayId;
      public getGateway_call(org.apache.airavata.model.security.AuthzToken authzToken, String gatewayId, org.apache.thrift.async.AsyncMethodCallback resultHandler, org.apache.thrift.async.TAsyncClient client, org.apache.thrift.protocol.TProtocolFactory protocolFactory, org.apache.thrift.transport.TNonblockingTransport transport) throws org.apache.thrift.TException {
        super(client, protocolFactory, transport, resultHandler, false);
        this.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("getGateway", org.apache.thrift.protocol.TMessageType.CALL, 0));
        getGateway_args args = new getGateway_args();
        args.setAuthzToken(authzToken);
        args.setGatewayId(gatewayId);
        args.write(prot);
        prot.writeMessageEnd();
      }

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

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

    public static class deleteGateway_call extends org.apache.thrift.async.TAsyncMethodCall {
      private org.apache.airavata.model.security.AuthzToken authzToken;
      private String gatewayId;
      public deleteGateway_call(org.apache.airavata.model.security.AuthzToken authzToken, String gatewayId, org.apache.thrift.async.AsyncMethodCallback resultHandler, org.apache.thrift.async.TAsyncClient client, org.apache.thrift.protocol.TProtocolFactory protocolFactory, org.apache.thrift.transport.TNonblockingTransport transport) throws org.apache.thrift.TException {
        super(client, protocolFactory, transport, resultHandler, false);
        this.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("deleteGateway", org.apache.thrift.protocol.TMessageType.CALL, 0));
        deleteGateway_args args = new deleteGateway_args();
        args.setAuthzToken(authzToken);
        args.setGatewayId(gatewayId);
        args.write(prot);
        prot.writeMessageEnd();
      }

      public boolean getResult() throws org.apache.airavata.model.error.InvalidRequestException, org.apache.airavata.model.error.AiravataClientException, org.apache.airavata.model.error.AiravataSystemException, org.apache.airavata.model.error.AuthorizationException, org.apache.thrift.TException {
        if (getState() != org.apache.thrift.async.TAsyncMethodCall.State.RESPONSE_READ) {
          throw new IllegalStateException("Method call not finished!");
        }
        org.apache.thrift.transport.TMemoryInputTransport memoryTransport = new org.apache.thrift.transport.TMemoryInputTransport(getFrameBuffer().array());
        org.apache.thrift.protocol.TProtocol prot = client.getProtocolFactory().getProtocol(memoryTransport);
        return (new Client(prot)).recv_deleteGateway();
      }
    }

    public void getAllGateways(org.apache.airavata.model.security.AuthzToken authzToken, org.apache.thrift.async.AsyncMethodCallback 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 {
      private org.apache.airavata.model.security.AuthzToken authzToken;
      public getAllGateways_call(org.apache.airavata.model.security.AuthzToken authzToken, org.apache.thrift.async.AsyncMethodCallback resultHandler, org.apache.thrift.async.TAsyncClient client, org.apache.thrift.protocol.TProtocolFactory protocolFactory, org.apache.thrift.transport.TNonblockingTransport transport) throws org.apache.thrift.TException {
        super(client, protocolFactory, transport, resultHandler, false);
        this.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 List<org.apache.airavata.model.workspace.Gateway> getResult() throws org.apache.airavata.model.error.InvalidRequestException, org.apache.airavata.model.error.AiravataClientException, org.apache.airavata.model.error.AiravataSystemException, org.apache.airavata.model.error.AuthorizationException, org.apache.thrift.TException {
        if (getState() != org.apache.thrift.async.TAsyncMethodCall.State.RESPONSE_READ) {
          throw new IllegalStateException("Method call not finished!");
        }
        org.apache.thrift.transport.TMemoryInputTransport memoryTransport = new org.apache.thrift.transport.TMemoryInputTransport(getFrameBuffer().array());
        org.apache.thrift.protocol.TProtocol prot = client.getProtocolFactory().getProtocol(memoryTransport);
        return (new Client(prot)).recv_getAllGateways();
      }
    }

    public void isGatewayExist(org.apache.airavata.model.security.AuthzToken authzToken, String gatewayId, org.apache.thrift.async.AsyncMethodCallback 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 {
      private org.apache.airavata.model.security.AuthzToken authzToken;
      private String gatewayId;
      public isGatewayExist_call(org.apache.airavata.model.security.AuthzToken authzToken, String gatewayId, org.apache.thrift.async.AsyncMethodCallback resultHandler, org.apache.thrift.async.TAsyncClient client, org.apache.thrift.protocol.TProtocolFactory protocolFactory, org.apache.thrift.transport.TNonblockingTransport transport) throws org.apache.thrift.TException {
        super(client, protocolFactory, transport, resultHandler, false);
        this.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 boolean getResult() throws org.apache.airavata.model.error.InvalidRequestException, org.apache.airavata.model.error.AiravataClientException, org.apache.airavata.model.error.AiravataSystemException, org.apache.airavata.model.error.AuthorizationException, org.apache.thrift.TException {
        if (getState() != org.apache.thrift.async.TAsyncMethodCall.State.RESPONSE_READ) {
          throw new IllegalStateException("Method call not finished!");
        }
        org.apache.thrift.transport.TMemoryInputTransport memoryTransport = new org.apache.thrift.transport.TMemoryInputTransport(getFrameBuffer().array());
        org.apache.thrift.protocol.TProtocol prot = client.getProtocolFactory().getProtocol(memoryTransport);
        return (new Client(prot)).recv_isGatewayExist();
      }
    }

    public void generateAndRegisterSSHKeys(org.apache.airavata.model.security.AuthzToken authzToken, String gatewayId, String userName, org.apache.thrift.async.AsyncMethodCallback resultHandler) throws org.apache.thrift.TException {
      checkReady();
      generateAndRegisterSSHKeys_call method_call = new generateAndRegisterSSHKeys_call(authzToken, gatewayId, userName, resultHandler, this, ___protocolFactory, ___transport);
      this.___currentMethod = method_call;
      ___manager.call(method_call);
    }

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

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

      public String getResult() throws org.apache.airavata.model.error.InvalidRequestException, org.apache.airavata.model.error.AiravataClientException, org.apache.airavata.model.error.AiravataSystemException, org.apache.thrift.TException {
        if (getState() != org.apache.thrift.async.TAsyncMethodCall.State.RESPONSE_READ) {
          throw new IllegalStateException("Method call not finished!");
        }
        org.apache.thrift.transport.TMemoryInputTransport memoryTransport = new org.apache.thrift.transport.TMemoryInputTransport(getFrameBuffer().array());
        org.apache.thrift.protocol.TProtocol prot = client.getProtocolFactory().getProtocol(memoryTransport);
        return (new Client(prot)).recv_generateAndRegisterSSHKeys();
      }
    }

    public void getSSHPubKey(org.apache.airavata.model.security.AuthzToken authzToken, String airavataCredStoreToken, String gatewayId, org.apache.thrift.async.AsyncMethodCallback resultHandler) throws org.apache.thrift.TException {
      checkReady();
      getSSHPubKey_call method_call = new getSSHPubKey_call(authzToken, airavataCredStoreToken, gatewayId, resultHandler, this, ___protocolFactory, ___transport);
      this.___currentMethod = method_call;
      ___manager.call(method_call);
    }

    public static class getSSHPubKey_call extends org.apache.thrift.async.TAsyncMethodCall {
      private org.apache.airavata.model.security.AuthzToken authzToken;
      private String airavataCredStoreToken;
      private String gatewayId;
      public getSSHPubKey_call(org.apache.airavata.model.security.AuthzToken authzToken, String airavataCredStoreToken, String gatewayId, org.apache.thrift.async.AsyncMethodCallback resultHandler, org.apache.thrift.async.TAsyncClient client, org.apache.thrift.protocol.TProtocolFactory protocolFactory, org.apache.thrift.transport.TNonblockingTransport transport) throws org.apache.thrift.TException {
        super(client, protocolFactory, transport, resultHandler, false);
        this.authzToken = authzToken;
        this.airavataCredStoreToken = airavataCredStoreToken;
        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("getSSHPubKey", org.apache.thrift.protocol.TMessageType.CALL, 0));
        getSSHPubKey_args args = new getSSHPubKey_args();
        args.setAuthzToken(authzToken);
        args.setAiravataCredStoreToken(airavataCredStoreToken);
        args.setGatewayId(gatewayId);
        args.write(prot);
        prot.writeMessageEnd();
      }

      public String getResult() throws org.apache.airavata.model.error.InvalidRequestException, org.apache.airavata.model.error.AiravataClientException, org.apache.airavata.model.error.AiravataSystemException, org.apache.thrift.TException {
        if (getState() != org.apache.thrift.async.TAsyncMethodCall.State.RESPONSE_READ) {
          throw new IllegalStateException("Method call not finished!");
        }
        org.apache.thrift.transport.TMemoryInputTransport memoryTransport = new org.apache.thrift.transport.TMemoryInputTransport(getFrameBuffer().array());
        org.apache.thrift.protocol.TProtocol prot = client.getProtocolFactory().getProtocol(memoryTransport);
        return (new Client(prot)).recv_getSSHPubKey();
      }
    }

    public void getAllUserSSHPubKeys(org.apache.airavata.model.security.AuthzToken authzToken, String userName, org.apache.thrift.async.AsyncMethodCallback resultHandler) throws org.apache.thrift.TException {
      checkReady();
      getAllUserSSHPubKeys_call method_call = new getAllUserSSHPubKeys_call(authzToken, userName, resultHandler, this, ___protocolFactory, ___transport);
      this.___currentMethod = method_call;
      ___manager.call(method_call);
    }

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

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

      public Map<String,String> getResult() throws org.apache.airavata.model.error.InvalidRequestException, org.apache.airavata.model.error.AiravataClientException, org.apache.airavata.model.error.AiravataSystemException, org.apache.thrift.TException {
        if (getState() != org.apache.thrift.async.TAsyncMethodCall.State.RESPONSE_READ) {
          throw new IllegalStateException("Method call not finished!");
        }
        org.apache.thrift.transport.TMemoryInputTransport memoryTransport = new org.apache.thrift.transport.TMemoryInputTransport(getFrameBuffer().array());
        org.apache.thrift.protocol.TProtocol prot = client.getProtocolFactory().getProtocol(memoryTransport);
        return (new Client(prot)).recv_getAllUserSSHPubKeys();
      }
    }

    public void createProject(org.apache.airavata.model.security.AuthzToken authzToken, String gatewayId, org.apache.airavata.model.workspace.Project project, org.apache.thrift.async.AsyncMethodCallback resultHandler) throws org.apache.thrift.TException {
      checkReady();
      createProject_call method_call = new createProject_call(authzToken, gatewayId, project, resultHandler, this, ___protocolFactory, ___transport);
      this.___currentMethod = method_call;
      ___manager.call(method_call);
    }

    public static class createProject_call extends org.apache.thrift.async.TAsyncMethodCall {
      private org.apache.airavata.model.security.AuthzToken authzToken;
      private String gatewayId;
      private org.apache.airavata.model.workspace.Project project;
      public createProject_call(org.apache.airavata.model.security.AuthzToken authzToken, String gatewayId, org.apache.airavata.model.workspace.Project project, org.apache.thrift.async.AsyncMethodCallback resultHandler, org.apache.thrift.async.TAsyncClient client, org.apache.thrift.protocol.TProtocolFactory protocolFactory, org.apache.thrift.transport.TNonblockingTransport transport) throws org.apache.thrift.TException {
        super(client, protocolFactory, transport, resultHandler, false);
        this.authzToken = authzToken;
        this.gatewayId = gatewayId;
        this.project = project;
      }

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

      public String getResult() throws org.apache.airavata.model.error.InvalidRequestException, org.apache.airavata.model.error.AiravataClientException, org.apache.airavata.model.error.AiravataSystemException, org.apache.airavata.model.error.AuthorizationException, org.apache.thrift.TException {
        if (getState() != org.apache.thrift.async.TAsyncMethodCall.State.RESPONSE_READ) {
          throw new IllegalStateException("Method call not finished!");
        }
        org.apache.thrift.transport.TMemoryInputTransport memoryTransport = new org.apache.thrift.transport.TMemoryInputTransport(getFrameBuffer().array());
        org.apache.thrift.protocol.TProtocol prot = client.getProtocolFactory().getProtocol(memoryTransport);
        return (new Client(prot)).recv_createProject();
      }
    }

    public void updateProject(org.apache.airavata.model.security.AuthzToken authzToken, String projectId, org.apache.airavata.model.workspace.Project updatedProject, org.apache.thrift.async.AsyncMethodCallback resultHandler) throws org.apache.thrift.TException {
      checkReady();
      updateProject_call method_call = new updateProject_call(authzToken, projectId, updatedProject, resultHandler, this, ___protocolFactory, ___transport);
      this.___currentMethod = method_call;
      ___manager.call(method_call);
    }

    public static class updateProject_call extends org.apache.thrift.async.TAsyncMethodCall {
      private org.apache.airavata.model.security.AuthzToken authzToken;
      private String projectId;
      private org.apache.airavata.model.workspace.Project updatedProject;
      public updateProject_call(org.apache.airavata.model.security.AuthzToken authzToken, String projectId, org.apache.airavata.model.workspace.Project updatedProject, org.apache.thrift.async.AsyncMethodCallback resultHandler, org.apache.thrift.async.TAsyncClient client, org.apache.thrift.protocol.TProtocolFactory protocolFactory, org.apache.thrift.transport.TNonblockingTransport transport) throws org.apache.thrift.TException {
        super(client, protocolFactory, transport, resultHandler, false);
        this.authzToken = authzToken;
        this.projectId = projectId;
        this.updatedProject = updatedProject;
      }

      public void write_args(org.apache.thrift.protocol.TProtocol prot) throws org.apache.thrift.TException {
        prot.writeMessageBegin(new org.apache.thrift.protocol.TMessage("updateProject", org.apache.thrift.protocol.TMessageType.CALL, 0));
        updateProject_args args = new updateProject_args();
        args.setAuthzToken(authzToken);
        args.setProjectId(projectId);
        args.setUpdatedProject(updatedProject);
        args.write(prot);
        prot.writeMessageEnd();
      }

      public void getResult() throws org.apache.airavata.model.error.InvalidRequestException, org.apache.airavata.model.error.AiravataClientException, org.apache.airavata.model.error.AiravataSystemException, org.apache.airavata.model.error.ProjectNotFoundException, org.apache.airavata.model.error.AuthorizationException, org.apache.thrift.TException {
        if (getState() != org.apache.thrift.async.TAsyncMethodCall.State.RESPONSE_READ) {
          throw new IllegalStateException("Method call not finished!");
        }
        org.apache.thrift.transport.TMemoryInputTransport memoryTransport = new org.apache.thrift.transport.TMemoryInputTransport(getFrameBuffer().array());
        org.apache.thrift.protocol.TProtocol prot = client.getProtocolFactory().getProtocol(memoryTransport);
        (new Client(prot)).recv_updateProject();
      }
    }

    public void getProject(org.apache.airavata.model.security.AuthzToken authzToken, String projectId, org.apache.thrift.async.AsyncMethodCallback resultHandler) throws org.apache.thrift.TException {
      checkReady();
      getProject_call method_call = new getProject_call(authzToken, projectId, resultHandler, this, ___protocolFactory, ___transport);
      this.___currentMethod = method_call;
      ___manager.call(method_call);
    }

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

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

      public org.apache.airavata.model.workspace.Project getResult() throws org.apache.airavata.model.error.InvalidRequestException, org.apache.airavata.model.error.AiravataClientException, org.apache.airavata.model.error.AiravataSystemException, org.apache.airavata.model.error.ProjectNotFoundException, org.apache.airavata.model.error.AuthorizationException, org.apache.thrift.TException {
        if (getState() != org.apache.thrift.async.TAsyncMethodCall.State.RESPONSE_READ) {
          throw new IllegalStateException("Method call not finished!");
        }
        org.apache.thrift.transport.TMemoryInputTransport memoryTransport = new org.apache.thrift.transport.TMemoryInputTransport(getFrameBuffer().array());
        org.apache.thrift.protocol.TProtocol prot = client.getProtocolFactory().getProtocol(memoryTransport);
        return (new Client(prot)).recv_getProject();
      }
    }

    public void deleteProject(org.apache.airavata.model.security.AuthzToken authzToken, String projectId, org.apache.thrift.async.AsyncMethodCallback resultHandler) throws org.apache.thrift.TException {
      checkReady();
      deleteProject_call method_call = new deleteProject_call(authzToken, projectId, resultHandler, this, ___protocolFactory, ___transport);
      this.___currentMethod = method_call;
      ___manager.call(method_call);
    }

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

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

      public boolean getResult() throws org.apache.airavata.model.error.InvalidRequestException, org.apache.airavata.model.error.AiravataClientException, org.apache.airavata.model.error.AiravataSystemException, org.apache.airavata.model.error.ProjectNotFoundException, org.apache.airavata.model.error.AuthorizationException, org.apache.thrift.TException {
        if (getState() != org.apache.thrift.async.TAsyncMethodCall.State.RESPONSE_READ) {
          throw new IllegalStateException("Method call not finished!");
        }
        org.apache.thrift.transport.TMemoryInputTransport memoryTransport = new org.apache.thrift.transport.TMemoryInputTransport(getFrameBuffer().array());
        org.apache.thrift.protocol.TProtocol prot = client.getProtocolFactory().getProtocol(memoryTransport);
        return (new Client(prot)).recv_deleteProject();
      }
    }

    public void getUserProjects(org.apache.airavata.model.security.AuthzToken authzToken, String gatewayId, String userName, int limit, int offset, org.apache.thrift.async.AsyncMethodCallback resultHandler) throws org.apache.thrift.TException {
      checkReady();
      getUserProjects_call method_call = new getUserProjects_call(authzToken, gatewayId, userName, limit, offset, resultHandler, this, ___protocolFactory, ___transport);
      this.___currentMethod = method_call;
      ___manager.call(method_call);
    }

    public static class getUserProjects_call extends org.apache.thrift.async.TAsyncMethodCall {
      private org.apache.airavata.model.security.AuthzToken authzToken;
      private String gatewayId;
      private String userName;
      private int limit;
      private int offset;
      public getUserProjects_call(org.apache.airavata.model.security.AuthzToken authzToken, String gatewayId, String userName, int limit, int offset, org.apache.thrift.async.AsyncMethodCallback resultHandler, org.apache.thrift.async.TAsyncClient client, org.apache.thrift.protocol.TProtocolFactory protocolFactory, org.apache.thrift.transport.TNonblockingTransport transport) throws org.apache.thrift.TException {
        super(client, protocolFactory, transport, resultHandler, false);
        this.authzToken = authzToken;
        this.gatewayId = gatewayId;
        this.userName = userName;
        this.limit = limit;
        this.offset = offset;
      }

      public void write_args(org.apache.thrift.protocol.TProtocol prot) throws org.apache.thrift.TException {
        prot.writeMessageBegin(new org.apache.thrift.protocol.TMessage("getUserProjects", org.apache.thrift.protocol.TMessageType.CALL, 0));
        getUserProjects_args args = new getUserProjects_args();
        args.setAuthzToken(authzToken);
        args.setGatewayId(gatewayId);
        args.setUserName(userName);
        args.setLimit(limit);
        args.setOffset(offset);
        args.write(prot);
        prot.writeMessageEnd();
      }

      public List<org.apache.airavata.model.workspace.Project> getResult() throws org.apache.airavata.model.error.InvalidRequestException, org.apache.airavata.model.error.AiravataClientException, org.apache.airavata.model.error.AiravataSystemException, org.apache.airavata.model.error.AuthorizationException, org.apache.thrift.TException {
        if (getState() != org.apache.thrift.async.TAsyncMethodCall.State.RESPONSE_READ) {
          throw new IllegalStateException("Method call not finished!");
        }
        org.apache.thrift.transport.TMemoryInputTransport memoryTransport = new org.apache.thrift.transport.TMemoryInputTransport(getFrameBuffer().array());
        org.apache.thrift.protocol.TProtocol prot = client.getProtocolFactory().getProtocol(memoryTransport);
        return (new Client(prot)).recv_getUserProjects();
      }
    }

    public void searchProjectsByProjectName(org.apache.airavata.model.security.AuthzToken authzToken, String gatewayId, String userName, String projectName, int limit, int offset, org.apache.thrift.async.AsyncMethodCallback resultHandler) throws org.apache.thrift.TException {
      checkReady();
      searchProjectsByProjectName_call method_call = new searchProjectsByProjectName_call(authzToken, gatewayId, userName, projectName, limit, offset, resultHandler, this, ___protocolFactory, ___transport);
      this.___currentMethod = method_call;
      ___manager.call(method_call);
    }

    public static class searchProjectsByProjectName_call extends org.apache.thrift.async.TAsyncMethodCall {
      private org.apache.airavata.model.security.AuthzToken authzToken;
      private String gatewayId;
      private String userName;
      private String projectName;
      private int limit;
      private int offset;
      public searchProjectsByProjectName_call(org.apache.airavata.model.security.AuthzToken authzToken, String gatewayId, String userName, String projectName, int limit, int offset, org.apache.thrift.async.AsyncMethodCallback resultHandler, org.apache.thrift.async.TAsyncClient client, org.apache.thrift.protocol.TProtocolFactory protocolFactory, org.apache.thrift.transport.TNonblockingTransport transport) throws org.apache.thrift.TException {
        super(client, protocolFactory, transport, resultHandler, false);
        this.authzToken = authzToken;
        this.gatewayId = gatewayId;
        this.userName = userName;
        this.projectName = projectName;
        this.limit = limit;
        this.offset = offset;
      }

      public void write_args(org.apache.thrift.protocol.TProtocol prot) throws org.apache.thrift.TException {
        prot.writeMessageBegin(new org.apache.thrift.protocol.TMessage("searchProjectsByProjectName", org.apache.thrift.protocol.TMessageType.CALL, 0));
        searchProjectsByProjectName_args args = new searchProjectsByProjectName_args();
        args.setAuthzToken(authzToken);
        args.setGatewayId(gatewayId);
        args.setUserName(userName);
        args.setProjectName(projectName);
        args.setLimit(limit);
        args.setOffset(offset);
        args.write(prot);
        prot.writeMessageEnd();
      }

      public List<org.apache.airavata.model.workspace.Project> getResult() throws org.apache.airavata.model.error.InvalidRequestException, org.apache.airavata.model.error.AiravataClientException, org.apache.airavata.model.error.AiravataSystemException, org.apache.airavata.model.error.AuthorizationException, org.apache.thrift.TException {
        if (getState() != org.apache.thrift.async.TAsyncMethodCall.State.RESPONSE_READ) {
          throw new IllegalStateException("Method call not finished!");
        }
        org.apache.thrift.transport.TMemoryInputTransport memoryTransport = new org.apache.thrift.transport.TMemoryInputTransport(getFrameBuffer().array());
        org.apache.thrift.protocol.TProtocol prot = client.getProtocolFactory().getProtocol(memoryTransport);
        return (new Client(prot)).recv_searchProjectsByProjectName();
      }
    }

    public void searchProjectsByProjectDesc(org.apache.airavata.model.security.AuthzToken authzToken, String gatewayId, String userName, String description, int limit, int offset, org.apache.thrift.async.AsyncMethodCallback resultHandler) throws org.apache.thrift.TException {
      checkReady();
      searchProjectsByProjectDesc_call method_call = new searchProjectsByProjectDesc_call(authzToken, gatewayId, userName, description, limit, offset, resultHandler, this, ___protocolFactory, ___transport);
      this.___currentMethod = method_call;
      ___manager.call(method_call);
    }

    public static class searchProjectsByProjectDesc_call extends org.apache.thrift.async.TAsyncMethodCall {
      private org.apache.airavata.model.security.AuthzToken authzToken;
      private String gatewayId;
      private String userName;
      private String description;
      private int limit;
      private int offset;
      public searchProjectsByProjectDesc_call(org.apache.airavata.model.security.AuthzToken authzToken, String gatewayId, String userName, String description, int limit, int offset, org.apache.thrift.async.AsyncMethodCallback resultHandler, org.apache.thrift.async.TAsyncClient client, org.apache.thrift.protocol.TProtocolFactory protocolFactory, org.apache.thrift.transport.TNonblockingTransport transport) throws org.apache.thrift.TException {
        super(client, protocolFactory, transport, resultHandler, false);
        this.authzToken = authzToken;
        this.gatewayId = gatewayId;
        this.userName = userName;
        this.description = description;
        this.limit = limit;
        this.offset = offset;
      }

      public void write_args(org.apache.thrift.protocol.TProtocol prot) throws org.apache.thrift.TException {
        prot.writeMessageBegin(new org.apache.thrift.protocol.TMessage("searchProjectsByProjectDesc", org.apache.thrift.protocol.TMessageType.CALL, 0));
        searchProjectsByProjectDesc_args args = new searchProjectsByProjectDesc_args();
        args.setAuthzToken(authzToken);
        args.setGatewayId(gatewayId);
        args.setUserName(userName);
        args.setDescription(description);
        args.setLimit(limit);
        args.setOffset(offset);
        args.write(prot);
        prot.writeMessageEnd();
      }

      public List<org.apache.airavata.model.workspace.Project> getResult() throws org.apache.airavata.model.error.InvalidRequestException, org.apache.airavata.model.error.AiravataClientException, org.apache.airavata.model.error.AiravataSystemException, org.apache.airavata.model.error.AuthorizationException, org.apache.thrift.TException {
        if (getState() != org.apache.thrift.async.TAsyncMethodCall.State.RESPONSE_READ) {
          throw new IllegalStateException("Method call not finished!");
        }
        org.apache.thrift.transport.TMemoryInputTransport memoryTransport = new org.apache.thrift.transport.TMemoryInputTransport(getFrameBuffer().array());
        org.apache.thrift.protocol.TProtocol prot = client.getProtocolFactory().getProtocol(memoryTransport);
        return (new Client(prot)).recv_searchProjectsByProjectDesc();
      }
    }

    public void searchExperimentsByName(org.apache.airavata.model.security.AuthzToken authzToken, String gatewayId, String userName, String expName, int limit, int offset, org.apache.thrift.async.AsyncMethodCallback resultHandler) throws org.apache.thrift.TException {
      checkReady();
      searchExperimentsByName_call method_call = new searchExperimentsByName_call(authzToken, gatewayId, userName, expName, limit, offset, resultHandler, this, ___protocolFactory, ___transport);
      this.___currentMethod = method_call;
      ___manager.call(method_call);
    }

    public static class searchExperimentsByName_call extends org.apache.thrift.async.TAsyncMethodCall {
      private org.apache.airavata.model.security.AuthzToken authzToken;
      private String gatewayId;
      private String userName;
      private String expName;
      private int limit;
      private int offset;
      public searchExperimentsByName_call(org.apache.airavata.model.security.AuthzToken authzToken, String gatewayId, String userName, String expName, int limit, int offset, org.apache.thrift.async.AsyncMethodCallback resultHandler, org.apache.thrift.async.TAsyncClient client, org.apache.thrift.protocol.TProtocolFactory protocolFactory, org.apache.thrift.transport.TNonblockingTransport transport) throws org.apache.thrift.TException {
        super(client, protocolFactory, transport, resultHandler, false);
        this.authzToken = authzToken;
        this.gatewayId = gatewayId;
        this.userName = userName;
        this.expName = expName;
        this.limit = limit;
        this.offset = offset;
      }

      public void write_args(org.apache.thrift.protocol.TProtocol prot) throws org.apache.thrift.TException {
        prot.writeMessageBegin(new org.apache.thrift.protocol.TMessage("searchExperimentsByName", org.apache.thrift.protocol.TMessageType.CALL, 0));
        searchExperimentsByName_args args = new searchExperimentsByName_args();
        args.setAuthzToken(authzToken);
        args.setGatewayId(gatewayId);
        args.setUserName(userName);
        args.setExpName(expName);
        args.setLimit(limit);
        args.setOffset(offset);
        args.write(prot);
        prot.writeMessageEnd();
      }

      public List<org.apache.airavata.model.experiment.ExperimentSummaryModel> getResult() throws org.apache.airavata.model.error.InvalidRequestException, org.apache.airavata.model.error.AiravataClientException, org.apache.airavata.model.error.AiravataSystemException, org.apache.airavata.model.error.AuthorizationException, org.apache.thrift.TException {
        if (getState() != org.apache.thrift.async.TAsyncMethodCall.State.RESPONSE_READ) {
          throw new IllegalStateException("Method call not finished!");
        }
        org.apache.thrift.transport.TMemoryInputTransport memoryTransport = new org.apache.thrift.transport.TMemoryInputTransport(getFrameBuffer().array());
        org.apache.thrift.protocol.TProtocol prot = client.getProtocolFactory().getProtocol(memoryTransport);
        return (new Client(prot)).recv_searchExperimentsByName();
      }
    }

    public void searchExperimentsByDesc(org.apache.airavata.model.security.AuthzToken authzToken, String gatewayId, String userName, String description, int limit, int offset, org.apache.thrift.async.AsyncMethodCallback resultHandler) throws org.apache.thrift.TException {
      checkReady();
      searchExperimentsByDesc_call method_call = new searchExperimentsByDesc_call(authzToken, gatewayId, userName, description, limit, offset, resultHandler, this, ___protocolFactory, ___transport);
      this.___currentMethod = method_call;
      ___manager.call(method_call);
    }

    public static class searchExperimentsByDesc_call extends org.apache.thrift.async.TAsyncMethodCall {
      private org.apache.airavata.model.security.AuthzToken authzToken;
      private String gatewayId;
      private String userName;
      private String description;
      private int limit;
      private int offset;
      public searchExperimentsByDesc_call(org.apache.airavata.model.security.AuthzToken authzToken, String gatewayId, String userName, String description, int limit, int offset, org.apache.thrift.async.AsyncMethodCallback resultHandler, org.apache.thrift.async.TAsyncClient client, org.apache.thrift.protocol.TProtocolFactory protocolFactory, org.apache.thrift.transport.TNonblockingTransport transport) throws org.apache.thrift.TException {
        super(client, protocolFactory, transport, resultHandler, false);
        this.authzToken = authzToken;
        this.gatewayId = gatewayId;
        this.userName = userName;
        this.description = description;
        this.limit = limit;
        this.offset = offset;
      }

      public void write_args(org.apache.thrift.protocol.TProtocol prot) throws org.apache.thrift.TException {
        prot.writeMessageBegin(new org.apache.thrift.protocol.TMessage("searchExperimentsByDesc", org.apache.thrift.protocol.TMessageType.CALL, 0));
        searchExperimentsByDesc_args args = new searchExperimentsByDesc_args();
        args.setAuthzToken(authzToken);
        args.setGatewayId(gatewayId);
        args.setUserName(userName);
        args.setDescription(description);
        args.setLimit(limit);
        args.setOffset(offset);
        args.write(prot);
        prot.writeMessageEnd();
      }

      public List<org.apache.airavata.model.experiment.ExperimentSummaryModel> getResult() throws org.apache.airavata.model.error.InvalidRequestException, org.apache.airavata.model.error.AiravataClientException, org.apache.airavata.model.error.AiravataSystemException, org.apache.airavata.model.error.AuthorizationException, org.apache.thrift.TException {
        if (getState() != org.apache.thrift.async.TAsyncMethodCall.State.RESPONSE_READ) {
          throw new IllegalStateException("Method call not finished!");
        }
        org.apache.thrift.transport.TMemoryInputTransport memoryTransport = new org.apache.thrift.transport.TMemoryInputTransport(getFrameBuffer().array());
        org.apache.thrift.protocol.TProtocol prot = client.getProtocolFactory().getProtocol(memoryTransport);
        return (new Client(prot)).recv_searchExperimentsByDesc();
      }
    }

    public void searchExperimentsByApplication(org.apache.airavata.model.security.AuthzToken authzToken, String gatewayId, String userName, String applicationId, int limit, int offset, org.apache.thrift.async.AsyncMethodCallback resultHandler) throws org.apache.thrift.TException {
      checkReady();
      searchExperimentsByApplication_call method_call = new searchExperimentsByApplication_call(authzToken, gatewayId, userName, applicationId, limit, offset, resultHandler, this, ___protocolFactory, ___transport);
      this.___currentMethod = method_call;
      ___manager.call(method_call);
    }

    public static class searchExperimentsByApplication_call extends org.apache.thrift.async.TAsyncMethodCall {
      private org.apache.airavata.model.security.AuthzToken authzToken;
      private String gatewayId;
      private String userName;
      private String applicationId;
      private int limit;
      private int offset;
      public searchExperimentsByApplication_call(org.apache.airavata.model.security.AuthzToken authzToken, String gatewayId, String userName, String applicationId, int limit, int offset, org.apache.thrift.async.AsyncMethodCallback resultHandler, org.apache.thrift.async.TAsyncClient client, org.apache.thrift.protocol.TProtocolFactory protocolFactory, org.apache.thrift.transport.TNonblockingTransport transport) throws org.apache.thrift.TException {
        super(client, protocolFactory, transport, resultHandler, false);
        this.authzToken = authzToken;
        this.gatewayId = gatewayId;
        this.userName = userName;
        this.applicationId = applicationId;
        this.limit = limit;
        this.offset = offset;
      }

      public void write_args(org.apache.thrift.protocol.TProtocol prot) throws org.apache.thrift.TException {
        prot.writeMessageBegin(new org.apache.thrift.protocol.TMessage("searchExperimentsByApplication", org.apache.thrift.protocol.TMessageType.CALL, 0));
        searchExperimentsByApplication_args args = new searchExperimentsByApplication_args();
        args.setAuthzToken(authzToken);
        args.setGatewayId(gatewayId);
        args.setUserName(userName);
        args.setApplicationId(applicationId);
        args.setLimit(limit);
        args.setOffset(offset);
        args.write(prot);
        prot.writeMessageEnd();
      }

      public List<org.apache.airavata.model.experiment.ExperimentSummaryModel> getResult() throws org.apache.airavata.model.error.InvalidRequestException, org.apache.airavata.model.error.AiravataClientException, org.apache.airavata.model.error.AiravataSystemException, org.apache.airavata.model.error.AuthorizationException, org.apache.thrift.TException {
        if (getState() != org.apache.thrift.async.TAsyncMethodCall.State.RESPONSE_READ) {
          throw new IllegalStateException("Method call not finished!");
        }
        org.apache.thrift.transport.TMemoryInputTransport memoryTransport = new org.apache.thrift.transport.TMemoryInputTransport(getFrameBuffer().array());
        org.apache.thrift.protocol.TProtocol prot = client.getProtocolFactory().getProtocol(memoryTransport);
        return (new Client(prot)).recv_searchExperimentsByApplication();
      }
    }

    public void searchExperimentsByStatus(org.apache.airavata.model.security.AuthzToken authzToken, String gatewayId, String userName, org.apache.airavata.model.status.ExperimentState experimentState, int limit, int offset, org.apache.thrift.async.AsyncMethodCallback resultHandler) throws org.apache.thrift.TException {
      checkReady();
      searchExperimentsByStatus_call method_call = new searchExperimentsByStatus_call(authzToken, gatewayId, userName, experimentState, limit, offset, resultHandler, this, ___protocolFactory, ___transport);
      this.___currentMethod = method_call;
      ___manager.call(method_call);
    }

    public static class searchExperimentsByStatus_call extends org.apache.thrift.async.TAsyncMethodCall {
      private org.apache.airavata.model.security.AuthzToken authzToken;
      private String gatewayId;
      private String userName;
      private org.apache.airavata.model.status.ExperimentState experimentState;
      private int limit;
      private int offset;
      public searchExperimentsByStatus_call(org.apache.airavata.model.security.AuthzToken authzToken, String gatewayId, String userName, org.apache.airavata.model.status.ExperimentState experimentState, int limit, int offset, org.apache.thrift.async.AsyncMethodCallback resultHandler, org.apache.thrift.async.TAsyncClient client, org.apache.thrift.protocol.TProtocolFactory protocolFactory, org.apache.thrift.transport.TNonblockingTransport transport) throws org.apache.thrift.TException {
        super(client, protocolFactory, transport, resultHandler, false);
        this.authzToken = authzToken;
        this.gatewayId = gatewayId;
        this.userName = userName;
        this.experimentState = experimentState;
        this.limit = limit;
        this.offset = offset;
      }

      public void write_args(org.apache.thrift.protocol.TProtocol prot) throws org.apache.thrift.TException {
        prot.writeMessageBegin(new org.apache.thrift.protocol.TMessage("searchExperimentsByStatus", org.apache.thrift.protocol.TMessageType.CALL, 0));
        searchExperimentsByStatus_args args = new searchExperimentsByStatus_args();
        args.setAuthzToken(authzToken);
        args.setGatewayId(gatewayId);
        args.setUserName(userName);
        args.setExperimentState(experimentState);
        args.setLimit(limit);
        args.setOffset(offset);
        args.write(prot);
        prot.writeMessageEnd();
      }

      public List<org.apache.airavata.model.experiment.ExperimentSummaryModel> getResult() throws org.apache.airavata.model.error.InvalidRequestException, org.apache.airavata.model.error.AiravataClientException, org.apache.airavata.model.error.AiravataSystemException, org.apache.airavata.model.error.AuthorizationException, org.apache.thrift.TException {
        if (getState() != org.apache.thrift.async.TAsyncMethodCall.State.RESPONSE_READ) {
          throw new IllegalStateException("Method call not finished!");
        }
        org.apache.thrift.transport.TMemoryInputTransport memoryTransport = new org.apache.thrift.transport.TMemoryInputTransport(getFrameBuffer().array());
        org.apache.thrift.protocol.TProtocol prot = client.getProtocolFactory().getProtocol(memoryTransport);
        return (new Client(prot)).recv_searchExperimentsByStatus();
      }
    }

    public void searchExperimentsByCreationTime(org.apache.airavata.model.security.AuthzToken authzToken, String gatewayId, String userName, long fromTime, long toTime, int limit, int offset, org.apache.thrift.async.AsyncMethodCallback resultHandler) throws org.apache.thrift.TException {
      checkReady();
      searchExperimentsByCreationTime_call method_call = new searchExperimentsByCreationTime_call(authzToken, gatewayId, userName, fromTime, toTime, limit, offset, resultHandler, this, ___protocolFactory, ___transport);
      this.___currentMethod = method_call;
      ___manager.call(method_call);
    }

    public static class searchExperimentsByCreationTime_call extends org.apache.thrift.async.TAsyncMethodCall {
      private org.apache.airavata.model.security.AuthzToken authzToken;
      private String gatewayId;
      private String userName;
      private long fromTime;
      private long toTime;
      private int limit;
      private int offset;
      public searchExperimentsByCreationTime_call(org.apache.airavata.model.security.AuthzToken authzToken, String gatewayId, String userName, long fromTime, long toTime, int limit, int offset, org.apache.thrift.async.AsyncMethodCallback resultHandler, org.apache.thrift.async.TAsyncClient client, org.apache.thrift.protocol.TProtocolFactory protocolFactory, org.apache.thrift.transport.TNonblockingTransport transport) throws org.apache.thrift.TException {
        super(client, protocolFactory, transport, resultHandler, false);
        this.authzToken = authzToken;
        this.gatewayId = gatewayId;
        this.userName = userName;
        this.fromTime = fromTime;
        this.toTime = toTime;
        this.limit = limit;
        this.offset = offset;
      }

      public void write_args(org.apache.thrift.protocol.TProtocol prot) throws org.apache.thrift.TException {
        prot.writeMessageBegin(new org.apache.thrift.protocol.TMessage("searchExperimentsByCreationTime", org.apache.thrift.protocol.TMessageType.CALL, 0));
        searchExperimentsByCreationTime_args args = new searchExperimentsByCreationTime_args();
        args.setAuthzToken(authzToken);
        args.setGatewayId(gatewayId);
        args.setUserName(userName);
        args.setFromTime(fromTime);
        args.setToTime(toTime);
        args.setLimit(limit);
        args.setOffset(offset);
        args.write(prot);
        prot.writeMessageEnd();
      }

      public List<org.apache.airavata.model.experiment.ExperimentSummaryModel> getResult() throws org.apache.airavata.model.error.InvalidRequestException, org.apache.airavata.model.error.AiravataClientException, org.apache.airavata.model.error.AiravataSystemException, org.apache.airavata.model.error.AuthorizationException, org.apache.thrift.TException {
        if (getState() != org.apache.thrift.async.TAsyncMethodCall.State.RESPONSE_READ) {
          throw new IllegalStateException("Method call not finished!");
        }
        org.apache.thrift.transport.TMemoryInputTransport memoryTransport = new org.apache.thrift.transport.TMemoryInputTransport(getFrameBuffer().array());
        org.apache.thrift.protocol.TProtocol prot = client.getProtocolFactory().getProtocol(memoryTransport);
        return (new Client(prot)).recv_searchExperimentsByCreationTime();
      }
    }

    public void searchExperiments(org.apache.airavata.model.security.AuthzToken authzToken, String gatewayId, String userName, Map<org.apache.airavata.model.experiment.ExperimentSearchFields,String> filters, int limit, int offset, org.apache.thrift.async.AsyncMethodCallback resultHandler) throws org.apache.thrift.TException {
      checkReady();
      searchExperiments_call method_call = new searchExperiments_call(authzToken, gatewayId, userName, filters, limit, offset, resultHandler, this, ___protocolFactory, ___transport);
      this.___currentMethod = method_call;
      ___manager.call(method_call);
    }

    public static class searchExperiments_call extends org.apache.thrift.async.TAsyncMethodCall {
      private org.apache.airavata.model.security.AuthzToken authzToken;
      private String gatewayId;
      private String userName;
      private Map<org.apache.airavata.model.experiment.ExperimentSearchFields,String> filters;
      private int limit;
      private int offset;
      public searchExperiments_call(org.apache.airavata.model.security.AuthzToken authzToken, String gatewayId, String userName, Map<org.apache.airavata.model.experiment.ExperimentSearchFields,String> filters, int limit, int offset, org.apache.thrift.async.AsyncMethodCallback resultHandler, org.apache.thrift.async.TAsyncClient client, org.apache.thrift.protocol.TProtocolFactory protocolFactory, org.apache.thrift.transport.TNonblockingTransport transport) throws org.apache.thrift.TException {
        super(client, protocolFactory, transport, resultHandler, false);
        this.authzToken = authzToken;
        this.gatewayId = gatewayId;
        this.userName = userName;
        this.filters = filters;
        this.limit = limit;
        this.offset = offset;
      }

      public void write_args(org.apache.thrift.protocol.TProtocol prot) throws org.apache.thrift.TException {
        prot.writeMessageBegin(new org.apache.thrift.protocol.TMessage("searchExperiments", org.apache.thrift.protocol.TMessageType.CALL, 0));
        searchExperiments_args args = new searchExperiments_args();
        args.setAuthzToken(authzToken);
        args.setGatewayId(gatewayId);
        args.setUserName(userName);
        args.setFilters(filters);
        args.setLimit(limit);
        args.setOffset(offset);
        args.write(prot);
        prot.writeMessageEnd();
      }

      public List<org.apache.airavata.model.experiment.ExperimentSummaryModel> getResult() throws org.apache.airavata.model.error.InvalidRequestException, org.apache.airavata.model.error.AiravataClientException, org.apache.airavata.model.error.AiravataSystemException, org.apache.airavata.model.error.AuthorizationException, org.apache.thrift.TException {
        if (getState() != org.apache.thrift.async.TAsyncMethodCall.State.RESPONSE_READ) {
          throw new IllegalStateException("Method call not finished!");
        }
        org.apache.thrift.transport.TMemoryInputTransport memoryTransport = new org.apache.thrift.transport.TMemoryInputTransport(getFrameBuffer().array());
        org.apache.thrift.protocol.TProtocol prot = client.getProtocolFactory().getProtocol(memoryTransport);
        return (new Client(prot)).recv_searchExperiments();
      }
    }

    public void getExperimentStatistics(org.apache.airavata.model.security.AuthzToken authzToken, String gatewayId, long fromTime, long toTime, org.apache.thrift.async.AsyncMethodCallback resultHandler) throws org.apache.thrift.TException {
      checkReady();
      getExperimentStatistics_call method_call = new getExperimentStatistics_call(authzToken, gatewayId, fromTime, toTime, resultHandler, this, ___protocolFactory, ___transport);
      this.___currentMethod = method_call;
      ___manager.call(method_call);
    }

    public static class getExperimentStatistics_call extends org.apache.thrift.async.TAsyncMethodCall {
      private org.apache.airavata.model.security.AuthzToken authzToken;
      private String gatewayId;
      private long fromTime;
      private long toTime;
      public getExperimentStatistics_call(org.apache.airavata.model.security.AuthzToken authzToken, String gatewayId, long fromTime, long toTime, org.apache.thrift.async.AsyncMethodCallback resultHandler, org.apache.thrift.async.TAsyncClient client, org.apache.thrift.protocol.TProtocolFactory protocolFactory, org.apache.thrift.transport.TNonblockingTransport transport) throws org.apache.thrift.TException {
        super(client, protocolFactory, transport, resultHandler, false);
        this.authzToken = authzToken;
        this.gatewayId = gatewayId;
        this.fromTime = fromTime;
        this.toTime = toTime;
      }

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

      public org.apache.airavata.model.experiment.ExperimentStatistics getResult() throws org.apache.airavata.model.error.InvalidRequestException, org.apache.airavata.model.error.AiravataClientException, org.apache.airavata.model.error.AiravataSystemException, org.apache.airavata.model.error.AuthorizationException, org.apache.thrift.TException {
        if (getState() != org.apache.thrift.async.TAsyncMethodCall.State.RESPONSE_READ) {
          throw new IllegalStateException("Method call not finished!");
        }
        org.apache.thrift.transport.TMemoryInputTransport memoryTransport = new org.apache.thrift.transport.TMemoryInputTransport(getFrameBuffer().array());
        org.apache.thrift.protocol.TProtocol prot = client.getProtocolFactory().getProtocol(memoryTransport);
        return (new Client(prot)).recv_getExperimentStatistics();
      }
    }

    public void getExperimentsInProject(org.apache.airavata.model.security.AuthzToken authzToken, String projectId, int limit, int offset, org.apache.thrift.async.AsyncMethodCallback resultHandler) throws org.apache.thrift.TException {
      checkReady();
      getExperimentsInProject_call method_call = new getExperimentsInProject_call(authzToken, projectId, limit, offset, resultHandler, this, ___protocolFactory, ___transport);
      this.___currentMethod = method_call;
      ___manager.call(method_call);
    }

    public static class getExperimentsInProject_call extends org.apache.thrift.async.TAsyncMethodCall {
      private org.apache.airavata.model.security.AuthzToken authzToken;
      private String projectId;
      private int limit;
      private int offset;
      public getExperimentsInProject_call(org.apache.airavata.model.security.AuthzToken authzToken, String projectId, int limit, int offset, org.apache.thrift.async.AsyncMethodCallback resultHandler, org.apache.thrift.async.TAsyncClient client, org.apache.thrift.protocol.TProtocolFactory protocolFactory, org.apache.thrift.transport.TNonblockingTransport transport) throws org.apache.thrift.TException {
        super(client, protocolFactory, transport, resultHandler, false);
        this.authzToken = authzToken;
        this.projectId = projectId;
        this.limit = limit;
        this.offset = offset;
      }

      public void write_args(org.apache.thrift.protocol.TProtocol prot) throws org.apache.thrift.TException {
        prot.writeMessageBegin(new org.apache.thrift.protocol.TMessage("getExperimentsInProject", org.apache.thrift.protocol.TMessageType.CALL, 0));
        getExperimentsInProject_args args = new getExperimentsInProject_args();
        args.setAuthzToken(authzToken);
        args.setProjectId(projectId);
        args.setLimit(limit);
        args.setOffset(offset);
        args.write(prot);
        prot.writeMessageEnd();
      }

      public List<org.apache.airavata.model.experiment.ExperimentModel> getResult() throws org.apache.airavata.model.error.InvalidRequestException, org.apache.airavata.model.error.AiravataClientException, org.apache.airavata.model.error.AiravataSystemException, org.apache.airavata.model.error.ProjectNotFoundException, org.apache.airavata.model.error.AuthorizationException, org.apache.thrift.TException {
        if (getState() != org.apache.thrift.async.TAsyncMethodCall.State.RESPONSE_READ) {
          throw new IllegalStateException("Method call not finished!");
        }
        org.apache.thrift.transport.TMemoryInputTransport memoryTransport = new org.apache.thrift.transport.TMemoryInputTransport(getFrameBuffer().array());
        org.apache.thrift.protocol.TProtocol prot = client.getProtocolFactory().getProtocol(memoryTransport);
        return (new Client(prot)).recv_getExperimentsInProject();
      }
    }

    public void getUserExperiments(org.apache.airavata.model.security.AuthzToken authzToken, String gatewayId, String userName, int limit, int offset, org.apache.thrift.async.AsyncMethodCallback resultHandler) throws org.apache.thrift.TException {
      checkReady();
      getUserExperiments_call method_call = new getUserExperiments_call(authzToken, gatewayId, userName, limit, offset, resultHandler, this, ___protocolFactory, ___transport);
      this.___currentMethod = method_call;
      ___manager.call(method_call);
    }

    public static class getUserExperiments_call extends org.apache.thrift.async.TAsyncMethodCall {
      private org.apache.airavata.model.security.AuthzToken authzToken;
      private String gatewayId;
      private String userName;
      private int limit;
      private int offset;
      public getUserExperiments_call(org.apache.airavata.model.security.AuthzToken authzToken, String gatewayId, String userName, int limit, int offset, org.apache.thrift.async.AsyncMethodCallback resultHandler, org.apache.thrift.async.TAsyncClient client, org.apache.thrift.protocol.TProtocolFactory protocolFactory, org.apache.thrift.transport.TNonblockingTransport transport) throws org.apache.thrift.TException {
        super(client, protocolFactory, transport, resultHandler, false);
        this.authzToken = authzToken;
        this.gatewayId = gatewayId;
        this.userName = userName;
        this.limit = limit;
        this.offset = offset;
      }

      public void write_args(org.apache.thrift.protocol.TProtocol prot) throws org.apache.thrift.TException {
        prot.writeMessageBegin(new org.apache.thrift.protocol.TMessage("getUserExperiments", org.apache.thrift.protocol.TMessageType.CALL, 0));
        getUserExperiments_args args = new getUserExperiments_args();
        args.setAuthzToken(authzToken);
        args.setGatewayId(gatewayId);
        args.setUserName(userName);
        args.setLimit(limit);
        args.setOffset(offset);
        args.write(prot);
        prot.writeMessageEnd();
      }

      public List<org.apache.airavata.model.experiment.ExperimentModel> getResult() throws org.apache.airavata.model.error.InvalidRequestException, org.apache.airavata.model.error.AiravataClientException, org.apache.airavata.model.error.AiravataSystemException, org.apache.airavata.model.error.AuthorizationException, org.apache.thrift.TException {
        if (getState() != org.apache.thrift.async.TAsyncMethodCall.State.RESPONSE_READ) {
          throw new IllegalStateException("Method call not finished!");
        }
        org.apache.thrift.transport.TMemoryInputTransport memoryTransport = new org.apache.thrift.transport.TMemoryInputTransport(getFrameBuffer().array());
        org.apache.thrift.protocol.TProtocol prot = client.getProtocolFactory().getProtocol(memoryTransport);
        return (new Client(prot)).recv_getUserExperiments();
      }
    }

    public void createExperiment(org.apache.airavata.model.security.AuthzToken authzToken, String gatewayId, org.apache.airavata.model.experiment.ExperimentModel experiment, org.apache.thrift.async.AsyncMethodCallback resultHandler) throws org.apache.thrift.TException {
      checkReady();
      createExperiment_call method_call = new createExperiment_call(authzToken, gatewayId, experiment, resultHandler, this, ___protocolFactory, ___transport);
      this.___currentMethod = method_call;
      ___manager.call(method_call);
    }

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

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

      public String getResult() throws org.apache.airavata.model.error.InvalidRequestException, org.apache.airavata.model.error.AiravataClientException, org.apache.airavata.model.error.AiravataSystemException, org.apache.airavata.model.error.AuthorizationException, org.apache.thrift.TException {
        if (getState() != org.apache.thrift.async.TAsyncMethodCall.State.RESPONSE_READ) {
          throw new IllegalStateException("Method call not finished!");
        }
        org.apache.thrift.transport.TMemoryInputTransport memoryTransport = new org.apache.thrift.transport.TMemoryInputTransport(getFrameBuffer().array());
        org.apache.thrift.protocol.TProtocol prot = client.getProtocolFactory().getProtocol(memoryTransport);
        return (new Client(prot)).recv_createExperiment();
      }
    }

    public void deleteExperiment(org.apache.airavata.model.security.AuthzToken authzToken, String experimentId, org.apache.thrift.async.AsyncMethodCallback resultHandler) throws org.apache.thrift.TException {
      checkReady();
      deleteExperiment_call method_call = new deleteExperiment_call(authzToken, experimentId, resultHandler, this, ___protocolFactory, ___transport);
      this.___currentMethod = method_call;
      ___manager.call(method_call);
    }

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

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

      public boolean getResult() throws org.apache.airavata.model.error.InvalidRequestException, org.apache.airavata.model.error.AiravataClientException, org.apache.airavata.model.error.AiravataSystemException, org.apache.airavata.model.error.AuthorizationException, org.apache.thrift.TException {
        if (getState() != org.apache.thrift.async.TAsyncMethodCall.State.RESPONSE_READ) {
          throw new IllegalStateException("Method call not finished!");
        }
        org.apache.thrift.transport.TMemoryInputTransport memoryTransport = new org.apache.thrift.transport.TMemoryInputTransport(getFrameBuffer().array());
        org.apache.thrift.protocol.TProtocol prot = client.getProtocolFactory().getProtocol(memoryTransport);
        return (new Client(prot)).recv_deleteExperiment();
      }
    }

    public void getExperiment(org.apache.airavata.model.security.AuthzToken authzToken, String airavataExperimentId, org.apache.thrift.async.AsyncMethodCallback resultHandler) throws org.apache.thrift.TException {
      checkReady();
      getExperiment_call method_call = new getExperiment_call(authzToken, airavataExperimentId, resultHandler, this, ___protocolFactory, ___transport);
      this.___currentMethod = method_call;
      ___manager.call(method_call);
    }

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

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

      public org.apache.airavata.model.experiment.ExperimentModel getResult() throws org.apache.airavata.model.error.InvalidRequestException, org.apache.airavata.model.error.ExperimentNotFoundException, org.apache.airavata.model.error.AiravataClientException, org.apache.airavata.model.error.AiravataSystemException, org.apache.airavata.model.error.AuthorizationException, org.apache.thrift.TException {
        if (getState() != org.apache.thrift.async.TAsyncMethodCall.State.RESPONSE_READ) {
          throw new IllegalStateException("Method call not finished!");
        }
        org.apache.thrift.transport.TMemoryInputTransport memoryTransport = new org.apache.thrift.transport.TMemoryInputTransport(getFrameBuffer().array());
        org.apache.thrift.protocol.TProtocol prot = client.getProtocolFactory().getProtocol(memoryTransport);
        return (new Client(prot)).recv_getExperiment();
      }
    }

    public void getDetailedExperimentTree(org.apache.airavata.model.security.AuthzToken authzToken, String airavataExperimentId, org.apache.thrift.async.AsyncMethodCallback resultHandler) throws org.apache.thrift.TException {
      checkReady();
      getDetailedExperimentTree_call method_call = new getDetailedExperimentTree_call(authzToken, airavataExperimentId, resultHandler, this, ___protocolFactory, ___transport);
      this.___currentMethod = method_call;
      ___manager.call(method_call);
    }

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

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

      public org.apache.airavata.model.experiment.ExperimentModel getResult() throws org.apache.airavata.model.error.InvalidRequestException, org.apache.airavata.model.error.ExperimentNotFoundException, org.apache.airavata.model.error.AiravataClientException, org.apache.airavata.model.error.AiravataSystemException, org.apache.airavata.model.error.AuthorizationException, org.apache.thrift.TException {
        if (getState() != org.apache.thrift.async.TAsyncMethodCall.State.RESPONSE_READ) {
          throw new IllegalStateException("Method call not finished!");
        }
        org.apache.thrift.transport.TMemoryInputTransport memoryTransport = new org.apache.thrift.transport.TMemoryInputTransport(getFrameBuffer().array());
        org.apache.thrift.protocol.TProtocol prot = client.getProtocolFactory().getProtocol(memoryTransport);
        return (new Client(prot)).recv_getDetailedExperimentTree();
      }
    }

    public void updateExperiment(org.apache.airavata.model.security.AuthzToken authzToken, String airavataExperimentId, org.apache.airavata.model.experiment.ExperimentModel experiment, org.apache.thrift.async.AsyncMethodCallback resultHandler) throws org.apache.thrift.TException {
      checkReady();
      updateExperiment_call method_call = new updateExperiment_call(authzToken, airavataExperimentId, experiment, resultHandler, this, ___protocolFactory, ___transport);
      this.___currentMethod = method_call;
      ___manager.call(method_call);
    }

    public static class updateExperiment_call extends org.apache.thrift.async.TAsyncMethodCall {
      private org.apache.airavata.model.security.AuthzToken authzToken;
      private String airavataExperimentId;
      private org.apache.airavata.model.experiment.ExperimentModel experiment;
      public updateExperiment_call(org.apache.airavata.model.security.AuthzToken authzToken, String airavataExperimentId, org.apache.airavata.model.experiment.ExperimentModel experiment, org.apache.thrift.async.AsyncMethodCallback resultHandler, org.apache.thrift.async.TAsyncClient client, org.apache.thrift.protocol.TProtocolFactory protocolFactory, org.apache.thrift.transport.TNonblockingTransport transport) throws org.apache.thrift.TException {
        super(client, protocolFactory, transport, resultHandler, false);
        this.authzToken = authzToken;
        this.airavataExperimentId = airavataExperimentId;
        this.experiment = experiment;
      }

      public void write_args(org.apache.thrift.protocol.TProtocol prot) throws org.apache.thrift.TException {
        prot.writeMessageBegin(new org.apache.thrift.protocol.TMessage("updateExperiment", org.apache.thrift.protocol.TMessageType.CALL, 0));
        updateExperiment_args args = new updateExperiment_args();
        args.setAuthzToken(authzToken);
        args.setAiravataExperimentId(airavataExperimentId);
        args.setExperiment(experiment);
        args.write(prot);
        prot.writeMessageEnd();
      }

      public void getResult() throws org.apache.airavata.model.error.InvalidRequestException, org.apache.airavata.model.error.ExperimentNotFoundException, org.apache.airavata.model.error.AiravataClientException, org.apache.airavata.model.error.AiravataSystemException, org.apache.airavata.model.error.AuthorizationException, org.apache.thrift.TException {
        if (getState() != org.apache.thrift.async.TAsyncMethodCall.State.RESPONSE_READ) {
          throw new IllegalStateException("Method call not finished!");
        }
        org.apache.thrift.transport.TMemoryInputTransport memoryTransport = new org.apache.thrift.transport.TMemoryInputTransport(getFrameBuffer().array());
        org.apache.thrift.protocol.TProtocol prot = client.getProtocolFactory().getProtocol(memoryTransport);
        (new Client(prot)).recv_updateExperiment();
      }
    }

    public void updateExperimentConfiguration(org.apache.airavata.model.security.AuthzToken authzToken, String airavataExperimentId, org.apache.airavata.model.experiment.UserConfigurationDataModel userConfiguration, org.apache.thrift.async.AsyncMethodCallback resultHandler) throws org.apache.thrift.TException {
      checkReady();
      updateExperimentConfiguration_call method_call = new updateExperimentConfiguration_call(authzToken, airavataExperimentId, userConfiguration, resultHandler, this, ___protocolFactory, ___transport);
      this.___currentMethod = method_call;
      ___manager.call(method_call);
    }

    public static class updateExperimentConfiguration_call extends org.apache.thrift.async.TAsyncMethodCall {
      private org.apache.airavata.model.security.AuthzToken authzToken;
      private String airavataExperimentId;
      private org.apache.airavata.model.experiment.UserConfigurationDataModel userConfiguration;
      public updateExperimentConfiguration_call(org.apache.airavata.model.security.AuthzToken authzToken, String airavataExperimentId, org.apache.airavata.model.experiment.UserConfigurationDataModel userConfiguration, org.apache.thrift.async.AsyncMethodCallback resultHandler, org.apache.thrift.async.TAsyncClient client, org.apache.thrift.protocol.TProtocolFactory protocolFactory, org.apache.thrift.transport.TNonblockingTransport transport) throws org.apache.thrift.TException {
        super(client, protocolFactory, transport, resultHandler, false);
        this.authzToken = authzToken;
        this.airavataExperimentId = airavataExperimentId;
        this.userConfiguration = userConfiguration;
      }

      public void write_args(org.apache.thrift.protocol.TProtocol prot) throws org.apache.thrift.TException {
        prot.writeMessageBegin(new org.apache.thrift.protocol.TMessage("updateExperimentConfiguration", org.apache.thrift.protocol.TMessageType.CALL, 0));
        updateExperimentConfiguration_args args = new updateExperimentConfiguration_args();
        args.setAuthzToken(authzToken);
        args.setAiravataExperimentId(airavataExperimentId);
        args.setUserConfiguration(userConfiguration);
        args.write(prot);
        prot.writeMessageEnd();
      }

      public void getResult() throws org.apache.airavata.model.error.AuthorizationException, org.apache.thrift.TException {
        if (getState() != org.apache.thrift.async.TAsyncMethodCall.State.RESPONSE_READ) {
          throw new IllegalStateException("Method call not finished!");
        }
        org.apache.thrift.transport.TMemoryInputTransport memoryTransport = new org.apache.thrift.transport.TMemoryInputTransport(getFrameBuffer().array());
        org.apache.thrift.protocol.TProtocol prot = client.getProtocolFactory().getProtocol(memoryTransport);
        (new Client(prot)).recv_updateExperimentConfiguration();
      }
    }

    public void updateResourceScheduleing(org.apache.airavata.model.security.AuthzToken authzToken, String airavataExperimentId, org.apache.airavata.model.scheduling.ComputationalResourceSchedulingModel resourceScheduling, org.apache.thrift.async.AsyncMethodCallback resultHandler) throws org.apache.thrift.TException {
      checkReady();
      updateResourceScheduleing_call method_call = new updateResourceScheduleing_call(authzToken, airavataExperimentId, resourceScheduling, resultHandler, this, ___protocolFactory, ___transport);
      this.___currentMethod = method_call;
      ___manager.call(method_call);
    }

    public static class updateResourceScheduleing_call extends org.apache.thrift.async.TAsyncMethodCall {
      private org.apache.airavata.model.security.AuthzToken authzToken;
      private String airavataExperimentId;
      private org.apache.airavata.model.scheduling.ComputationalResourceSchedulingModel resourceScheduling;
      public updateResourceScheduleing_call(org.apache.airavata.model.security.AuthzToken authzToken, String airavataExperimentId, org.apache.airavata.model.scheduling.ComputationalResourceSchedulingModel resourceScheduling, org.apache.thrift.async.AsyncMethodCallback resultHandler, org.apache.thrift.async.TAsyncClient client, org.apache.thrift.protocol.TProtocolFactory protocolFactory, org.apache.thrift.transport.TNonblockingTransport transport) throws org.apache.thrift.TException {
        super(client, protocolFactory, transport, resultHandler, false);
        this.authzToken = authzToken;
        this.airavataExperimentId = airavataExperimentId;
        this.resourceScheduling = resourceScheduling;
      }

      public void write_args(org.apache.thrift.protocol.TProtocol prot) throws org.apache.thrift.TException {
        prot.writeMessageBegin(new org.apache.thrift.protocol.TMessage("updateResourceScheduleing", org.apache.thrift.protocol.TMessageType.CALL, 0));
        updateResourceScheduleing_args args = new updateResourceScheduleing_args();
        args.setAuthzToken(authzToken);
        args.setAiravataExperimentId(airavataExperimentId);
        args.setResourceScheduling(resourceScheduling);
        args.write(prot);
        prot.writeMessageEnd();
      }

      public void getResult() throws org.apache.airavata.model.error.AuthorizationException, org.apache.thrift.TException {
        if (getState() != org.apache.thrift.async.TAsyncMethodCall.State.RESPONSE_READ) {
          throw new IllegalStateException("Method call not finished!");
        }
        org.apache.thrift.transport.TMemoryInputTransport memoryTransport = new org.apache.thrift.transport.TMemoryInputTransport(getFrameBuffer().array());
        org.apache.thrift.protocol.TProtocol prot = client.getProtocolFactory().getProtocol(memoryTransport);
        (new Client(prot)).recv_updateResourceScheduleing();
      }
    }

    public void validateExperiment(org.apache.airavata.model.security.AuthzToken authzToken, String airavataExperimentId, org.apache.thrift.async.AsyncMethodCallback resultHandler) throws org.apache.thrift.TException {
      checkReady();
      validateExperiment_call method_call = new validateExperiment_call(authzToken, airavataExperimentId, resultHandler, this, ___protocolFactory, ___transport);
      this.___currentMethod = method_call;
      ___manager.call(method_call);
    }

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

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

      public boolean getResult() throws org.apache.airavata.model.error.InvalidRequestException, org.apache.airavata.model.error.ExperimentNotFoundException, org.apache.airavata.model.error.AiravataClientException, org.apache.airavata.model.error.AiravataSystemException, org.apache.airavata.model.error.AuthorizationException, org.apache.thrift.TException {
        if (getState() != org.apache.thrift.async.TAsyncMethodCall.State.RESPONSE_READ) {
          throw new IllegalStateException("Method call not finished!");
        }
        org.apache.thrift.transport.TMemoryInputTransport memoryTransport = new org.apache.thrift.transport.TMemoryInputTransport(getFrameBuffer().array());
        org.apache.thrift.protocol.TProtocol prot = client.getProtocolFactory().getProtocol(memoryTransport);
        return (new Client(prot)).recv_validateExperiment();
      }
    }

    public void launchExperiment(org.apache.airavata.model.security.AuthzToken authzToken, String airavataExperimentId, String gatewayId, org.apache.thrift.async.AsyncMethodCallback resultHandler) throws org.apache.thrift.TException {
      checkReady();
      launchExperiment_call method_call = new launchExperiment_call(authzToken, airavataExperimentId, gatewayId, resultHandler, this, ___protocolFactory, ___transport);
      this.___currentMethod = method_call;
      ___manager.call(method_call);
    }

    public static class launchExperiment_call extends org.apache.thrift.async.TAsyncMethodCall {
      private org.apache.airavata.model.security.AuthzToken authzToken;
      private String airavataExperimentId;
      private String gatewayId;
      public launchExperiment_call(org.apache.airavata.model.security.AuthzToken authzToken, String airavataExperimentId, String gatewayId, org.apache.thrift.async.AsyncMethodCallback resultHandler, org.apache.thrift.async.TAsyncClient client, org.apache.thrift.protocol.TProtocolFactory protocolFactory, org.apache.thrift.transport.TNonblockingTransport transport) throws org.apache.thrift.TException {
        super(client, protocolFactory, transport, resultHandler, false);
        this.authzToken = authzToken;
        this.airavataExperimentId = airavataExperimentId;
        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("launchExperiment", org.apache.thrift.protocol.TMessageType.CALL, 0));
        launchExperiment_args args = new launchExperiment_args();
        args.setAuthzToken(authzToken);
        args.setAiravataExperimentId(airavataExperimentId);
        args.setGatewayId(gatewayId);
        args.write(prot);
        prot.writeMessageEnd();
      }

      public void getResult() throws org.apache.airavata.model.error.InvalidRequestException, org.apache.airavata.model.error.ExperimentNotFoundException, org.apache.airavata.model.error.AiravataClientException, org.apache.airavata.model.error.AiravataSystemException, org.apache.airavata.model.error.AuthorizationException, org.apache.thrift.TException {
        if (getState() != org.apache.thrift.async.TAsyncMethodCall.State.RESPONSE_READ) {
          throw new IllegalStateException("Method call not finished!");
        }
        org.apache.thrift.transport.TMemoryInputTransport memoryTransport = new org.apache.thrift.transport.TMemoryInputTransport(getFrameBuffer().array());
        org.apache.thrift.protocol.TProtocol prot = client.getProtocolFactory().getProtocol(memoryTransport);
        (new Client(prot)).recv_launchExperiment();
      }
    }

    public void getExperimentStatus(org.apache.airavata.model.security.AuthzToken authzToken, String airavataExperimentId, org.apache.thrift.async.AsyncMethodCallback resultHandler) throws org.apache.thrift.TException {
      checkReady();
      getExperimentStatus_call method_call = new getExperimentStatus_call(authzToken, airavataExperimentId, resultHandler, this, ___protocolFactory, ___transport);
      this.___currentMethod = method_call;
      ___manager.call(method_call);
    }

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

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

      public org.apache.airavata.model.status.ExperimentStatus getResult() throws org.apache.airavata.model.error.InvalidRequestException, org.apache.airavata.model.error.ExperimentNotFoundException, org.apache.airavata.model.error.AiravataClientException, org.apache.airavata.model.error.AiravataSystemException, org.apache.airavata.model.error.AuthorizationException, org.apache.thrift.TException {
        if (getState() != org.apache.thrift.async.TAsyncMethodCall.State.RESPONSE_READ) {
          throw new IllegalStateException("Method call not finished!");
        }
        org.apache.thrift.transport.TMemoryInputTransport memoryTransport = new org.apache.thrift.transport.TMemoryInputTransport(getFrameBuffer().array());
        org.apache.thrift.protocol.TProtocol prot = client.getProtocolFactory().getProtocol(memoryTransport);
        return (new Client(prot)).recv_getExperimentStatus();
      }
    }

    public void getExperimentOutputs(org.apache.airavata.model.security.AuthzToken authzToken, String airavataExperimentId, org.apache.thrift.async.AsyncMethodCallback resultHandler) throws org.apache.thrift.TException {
      checkReady();
      getExperimentOutputs_call method_call = new getExperimentOutputs_call(authzToken, airavataExperimentId, resultHandler, this, ___protocolFactory, ___transport);
      this.___currentMethod = method_call;
      ___manager.call(method_call);
    }

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

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

      public List<org.apache.airavata.model.application.io.OutputDataObjectType> getResult() throws org.apache.airavata.model.error.InvalidRequestException, org.apache.airavata.model.error.ExperimentNotFoundException, org.apache.airavata.model.error.AiravataClientException, org.apache.airavata.model.error.AiravataSystemException, org.apache.airavata.model.error.AuthorizationException, org.apache.thrift.TException {
        if (getState() != org.apache.thrift.async.TAsyncMethodCall.State.RESPONSE_READ) {
          throw new IllegalStateException("Method call not finished!");
        }
        org.apache.thrift.transport.TMemoryInputTransport memoryTransport = new org.apache.thrift.transport.TMemoryInputTransport(getFrameBuffer().array());
        org.apache.thrift.protocol.TProtocol prot = client.getProtocolFactory().getProtocol(memoryTransport);
        return (new Client(prot)).recv_getExperimentOutputs();
      }
    }

    public void getIntermediateOutputs(org.apache.airavata.model.security.AuthzToken authzToken, String airavataExperimentId, org.apache.thrift.async.AsyncMethodCallback resultHandler) throws org.apache.thrift.TException {
      checkReady();
      getIntermediateOutputs_call method_call = new getIntermediateOutputs_call(authzToken, airavataExperimentId, resultHandler, this, ___protocolFactory, ___transport);
      this.___currentMethod = method_call;
      ___manager.call(method_call);
    }

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

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

      public List<org.apache.airavata.model.application.io.OutputDataObjectType> getResult() throws org.apache.airavata.model.error.InvalidRequestException, org.apache.airavata.model.error.ExperimentNotFoundException, org.apache.airavata.model.error.AiravataClientException, org.apache.airavata.model.error.AiravataSystemException, org.apache.airavata.model.error.AuthorizationException, org.apache.thrift.TException {
        if (getState() != org.apache.thrift.async.TAsyncMethodCall.State.RESPONSE_READ) {
          throw new IllegalStateException("Method call not finished!");
        }
        org.apache.thrift.transport.TMemoryInputTransport memoryTransport = new org.apache.thrift.transport.TMemoryInputTransport(getFrameBuffer().array());
        org.apache.thrift.protocol.TProtocol prot = client.getProtocolFactory().getProtocol(memoryTransport);
        return (new Client(prot)).recv_getIntermediateOutputs();
      }
    }

    public void getJobStatuses(org.apache.airavata.model.security.AuthzToken authzToken, String airavataExperimentId, org.apache.thrift.async.AsyncMethodCallback resultHandler) throws org.apache.thrift.TException {
      checkReady();
      getJobStatuses_call method_call = new getJobStatuses_call(authzToken, airavataExperimentId, resultHandler, this, ___protocolFactory, ___transport);
      this.___currentMethod = method_call;
      ___manager.call(method_call);
    }

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

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

      public Map<String,org.apache.airavata.model.status.JobStatus> getResult() throws org.apache.airavata.model.error.InvalidRequestException, org.apache.airavata.model.error.ExperimentNotFoundException, org.apache.airavata.model.error.AiravataClientException, org.apache.airavata.model.error.AiravataSystemException, org.apache.airavata.model.error.AuthorizationException, org.apache.thrift.TException {
        if (getState() != org.apache.thrift.async.TAsyncMethodCall.State.RESPONSE_READ) {
          throw new IllegalStateException("Method call not finished!");
        }
        org.apache.thrift.transport.TMemoryInputTransport memoryTransport = new org.apache.thrift.transport.TMemoryInputTransport(getFrameBuffer().array());
        org.apache.thrift.protocol.TProtocol prot = client.getProtocolFactory().getProtocol(memoryTransport);
        return (new Client(prot)).recv_getJobStatuses();
      }
    }

    public void getJobDetails(org.apache.airavata.model.security.AuthzToken authzToken, String airavataExperimentId, org.apache.thrift.async.AsyncMethodCallback resultHandler) throws org.apache.thrift.TException {
      checkReady();
      getJobDetails_call method_call = new getJobDetails_call(authzToken, airavataExperimentId, resultHandler, this, ___protocolFactory, ___transport);
      this.___currentMethod = method_call;
      ___manager.call(method_call);
    }

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

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

      public List<org.apache.airavata.model.job.JobModel> getResult() throws org.apache.airavata.model.error.InvalidRequestException, org.apache.airavata.model.error.ExperimentNotFoundException, org.apache.airavata.model.error.AiravataClientException, org.apache.airavata.model.error.AiravataSystemException, org.apache.airavata.model.error.AuthorizationException, org.apache.thrift.TException {
        if (getState() != org.apache.thrift.async.TAsyncMethodCall.State.RESPONSE_READ) {
          throw new IllegalStateException("Method call not finished!");
        }
        org.apache.thrift.transport.TMemoryInputTransport memoryTransport = new org.apache.thrift.transport.TMemoryInputTransport(getFrameBuffer().array());
        org.apache.thrift.protocol.TProtocol prot = client.getProtocolFactory().getProtocol(memoryTransport);
        return (new Client(prot)).recv_getJobDetails();
      }
    }

    public void cloneExperiment(org.apache.airavata.model.security.AuthzToken authzToken, String existingExperimentID, String newExperimentName, org.apache.thrift.async.AsyncMethodCallback resultHandler) throws org.apache.thrift.TException {
      checkReady();
      cloneExperiment_call method_call = new cloneExperiment_call(authzToken, existingExperimentID, newExperimentName, resultHandler, this, ___protocolFactory, ___transport);
      this.___currentMethod = method_call;
      ___manager.call(method_call);
    }

    public static class cloneExperiment_call extends org.apache.thrift.async.TAsyncMethodCall {
      private org.apache.airavata.model.security.AuthzToken authzToken;
      private String existingExperimentID;
      private String newExperimentName;
      public cloneExperiment_call(org.apache.airavata.model.security.AuthzToken authzToken, String existingExperimentID, String newExperimentName, org.apache.thrift.async.AsyncMethodCallback resultHandler, org.apache.thrift.async.TAsyncClient client, org.apache.thrift.protocol.TProtocolFactory protocolFactory, org.apache.thrift.transport.TNonblockingTransport transport) throws org.apache.thrift.TException {
        super(client, protocolFactory, transport, resultHandler, false);
        this.authzToken = authzToken;
        this.existingExperimentID = existingExperimentID;
        this.newExperimentName = newExperimentName;
      }

      public void write_args(org.apache.thrift.protocol.TProtocol prot) throws org.apache.thrift.TException {
        prot.writeMessageBegin(new org.apache.thrift.protocol.TMessage("cloneExperiment", org.apache.thrift.protocol.TMessageType.CALL, 0));
        cloneExperiment_args args = new cloneExperiment_args();
        args.setAuthzToken(authzToken);
        args.setExistingExperimentID(existingExperimentID);
        args.setNewExperimentName(newExperimentName);
        args.write(prot);
        prot.writeMessageEnd();
      }

      public String getResult() throws org.apache.airavata.model.error.InvalidRequestException, org.apache.airavata.model.error.ExperimentNotFoundException, org.apache.airavata.model.error.AiravataClientException, org.apache.airavata.model.error.AiravataSystemException, org.apache.airavata.model.error.AuthorizationException, org.apache.thrift.TException {
        if (getState() != org.apache.thrift.async.TAsyncMethodCall.State.RESPONSE_READ) {
          throw new IllegalStateException("Method call not finished!");
        }
        org.apache.thrift.transport.TMemoryInputTransport memoryTransport = new org.apache.thrift.transport.TMemoryInputTransport(getFrameBuffer().array());
        org.apache.thrift.protocol.TProtocol prot = client.getProtocolFactory().getProtocol(memoryTransport);
        return (new Client(prot)).recv_cloneExperiment();
      }
    }

    public void terminateExperiment(org.apache.airavata.model.security.AuthzToken authzToken, String airavataExperimentId, String gatewayId, org.apache.thrift.async.AsyncMethodCallback resultHandler) throws org.apache.thrift.TException {
      checkReady();
      terminateExperiment_call method_call = new terminateExperiment_call(authzToken, airavataExperimentId, gatewayId, resultHandler, this, ___protocolFactory, ___transport);
      this.___currentMethod = method_call;
      ___manager.call(method_call);
    }

    public static class terminateExperiment_call extends org.apache.thrift.async.TAsyncMethodCall {
      private org.apache.airavata.model.security.AuthzToken authzToken;
      private String airavataExperimentId;
      private String gatewayId;
      public terminateExperiment_call(org.apache.airavata.model.security.AuthzToken authzToken, String airavataExperimentId, String gatewayId, org.apache.thrift.async.AsyncMethodCallback resultHandler, org.apache.thrift.async.TAsyncClient client, org.apache.thrift.protocol.TProtocolFactory protocolFactory, org.apache.thrift.transport.TNonblockingTransport transport) throws org.apache.thrift.TException {
        super(client, protocolFactory, transport, resultHandler, false);
        this.authzToken = authzToken;
        this.airavataExperimentId = airavataExperimentId;
        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("terminateExperiment", org.apache.thrift.protocol.TMessageType.CALL, 0));
        terminateExperiment_args args = new terminateExperiment_args();
        args.setAuthzToken(authzToken);
        args.setAiravataExperimentId(airavataExperimentId);
        args.setGatewayId(gatewayId);
        args.write(prot);
        prot.writeMessageEnd();
      }

      public void getResult() throws org.apache.airavata.model.error.InvalidRequestException, org.apache.airavata.model.error.ExperimentNotFoundException, org.apache.airavata.model.error.AiravataClientException, org.apache.airavata.model.error.AiravataSystemException, org.apache.airavata.model.error.AuthorizationException, org.apache.thrift.TException {
        if (getState() != org.apache.thrift.async.TAsyncMethodCall.State.RESPONSE_READ) {
          throw new IllegalStateException("Method call not finished!");
        }
        org.apache.thrift.transport.TMemoryInputTransport memoryTransport = new org.apache.thrift.transport.TMemoryInputTransport(getFrameBuffer().array());
        org.apache.thrift.protocol.TProtocol prot = client.getProtocolFactory().getProtocol(memoryTransport);
        (new Client(prot)).recv_terminateExperiment();
      }
    }

    public void registerApplicationModule(org.apache.airavata.model.security.AuthzToken authzToken, String gatewayId, org.apache.airavata.model.appcatalog.appdeployment.ApplicationModule applicationModule, org.apache.thrift.async.AsyncMethodCallback resultHandler) throws org.apache.thrift.TException {
      checkReady();
      registerApplicationModule_call method_call = new registerApplicationModule_call(authzToken, gatewayId, applicationModule, resultHandler, this, ___protocolFactory, ___transport);
      this.___currentMethod = method_call;
      ___manager.call(method_call);
    }

    public static class registerApplicationModule_call extends org.apache.thrift.async.TAsyncMethodCall {
      private org.apache.airavata.model.security.AuthzToken authzToken;
      private String gatewayId;
      private org.apache.airavata.model.appcatalog.appdeployment.ApplicationModule applicationModule;
      public registerApplicationModule_call(org.apache.airavata.model.security.AuthzToken authzToken, String gatewayId, org.apache.airavata.model.appcatalog.appdeployment.ApplicationModule applicationModule, org.apache.thrift.async.AsyncMethodCallback resultHandler, org.apache.thrift.async.TAsyncClient client, org.apache.thrift.protocol.TProtocolFactory protocolFactory, org.apache.thrift.transport.TNonblockingTransport transport) throws org.apache.thrift.TException {
        super(client, protocolFactory, transport, resultHandler, false);
        this.authzToken = authzToken;
        this.gatewayId = gatewayId;
        this.applicationModule = applicationModule;
      }

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

      public String getResult() throws org.apache.airavata.model.error.InvalidRequestException, org.apache.airavata.model.error.AiravataClientException, org.apache.airavata.model.error.AiravataSystemException, org.apache.airavata.model.error.AuthorizationException, org.apache.thrift.TException {
        if (getState() != org.apache.thrift.async.TAsyncMethodCall.State.RESPONSE_READ) {
          throw new IllegalStateException("Method call not finished!");
        }
        org.apache.thrift.transport.TMemoryInputTransport memoryTransport = new org.apache.thrift.transport.TMemoryInputTransport(getFrameBuffer().array());
        org.apache.thrift.protocol.TProtocol prot = client.getProtocolFactory().getProtocol(memoryTransport);
        return (new Client(prot)).recv_registerApplicationModule();
      }
    }

    public void getApplicationModule(org.apache.airavata.model.security.AuthzToken authzToken, String appModuleId, org.apache.thrift.async.AsyncMethodCallback resultHandler) throws org.apache.thrift.TException {
      checkReady();
      getApplicationModule_call method_call = new getApplicationModule_call(authzToken, appModuleId, resultHandler, this, ___protocolFactory, ___transport);
      this.___currentMethod = method_call;
      ___manager.call(method_call);
    }

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

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

      public org.apache.airavata.model.appcatalog.appdeployment.ApplicationModule getResult() throws org.apache.airavata.model.error.InvalidRequestException, org.apache.airavata.model.error.AiravataClientException, org.apache.airavata.model.error.AiravataSystemException, org.apache.airavata.model.error.AuthorizationException, org.apache.thrift.TException {
        if (getState() != org.apache.thrift.async.TAsyncMethodCall.State.RESPONSE_READ) {
          throw new IllegalStateException("Method call not finished!");
        }
        org.apache.thrift.transport.TMemoryInputTransport memoryTransport = new org.apache.thrift.transport.TMemoryInputTransport(getFrameBuffer().array());
        org.apache.thrift.protocol.TProtocol prot = client.getProtocolFactory().getProtocol(memoryTransport);
        return (new Client(prot)).recv_getApplicationModule();
      }
    }

    public void updateApplicationModule(org.apache.airavata.model.security.AuthzToken authzToken, String appModuleId, org.apache.airavata.model.appcatalog.appdeployment.ApplicationModule applicationModule, org.apache.thrift.async.AsyncMethodCallback resultHandler) throws org.apache.thrift.TException {
      checkReady();
      updateApplicationModule_call method_call = new updateApplicationModule_call(authzToken, appModuleId, applicationModule, resultHandler, this, ___protocolFactory, ___transport);
      this.___currentMethod = method_call;
      ___manager.call(method_call);
    }

    public static class updateApplicationModule_call extends org.apache.thrift.async.TAsyncMethodCall {
      private org.apache.airavata.model.security.AuthzToken authzToken;
      private String appModuleId;
      private org.apache.airavata.model.appcatalog.appdeployment.ApplicationModule applicationModule;
      public updateApplicationModule_call(org.apache.airavata.model.security.AuthzToken authzToken, String appModuleId, org.apache.airavata.model.appcatalog.appdeployment.ApplicationModule applicationModule, org.apache.thrift.async.AsyncMethodCallback resultHandler, org.apache.thrift.async.TAsyncClient client, org.apache.thrift.protocol.TProtocolFactory protocolFactory, org.apache.thrift.transport.TNonblockingTransport transport) throws org.apache.thrift.TException {
        super(client, protocolFactory, transport, resultHandler, false);
        this.authzToken = authzToken;
        this.appModuleId = appModuleId;
        this.applicationModule = applicationModule;
      }

      public void write_args(org.apache.thrift.protocol.TProtocol prot) throws org.apache.thrift.TException {
        prot.writeMessageBegin(new org.apache.thrift.protocol.TMessage("updateApplicationModule", org.apache.thrift.protocol.TMessageType.CALL, 0));
        updateApplicationModule_args args = new updateApplicationModule_args();
        args.setAuthzToken(authzToken);
        args.setAppModuleId(appModuleId);
        args.setApplicationModule(applicationModule);
        args.write(prot);
        prot.writeMessageEnd();
      }

      public boolean getResult() throws org.apache.airavata.model.error.InvalidRequestException, org.apache.airavata.model.error.AiravataClientException, org.apache.airavata.model.error.AiravataSystemException, org.apache.airavata.model.error.AuthorizationException, org.apache.thrift.TException {
        if (getState() != org.apache.thrift.async.TAsyncMethodCall.State.RESPONSE_READ) {
          throw new IllegalStateException("Method call not finished!");
        }
        org.apache.thrift.transport.TMemoryInputTransport memoryTransport = new org.apache.thrift.transport.TMemoryInputTransport(getFrameBuffer().array());
        org.apache.thrift.protocol.TProtocol prot = client.getProtocolFactory().getProtocol(memoryTransport);
        return (new Client(prot)).recv_updateApplicationModule();
      }
    }

    public void getAllAppModules(org.apache.airavata.model.security.AuthzToken authzToken, String gatewayId, org.apache.thrift.async.AsyncMethodCallback resultHandler) throws org.apache.thrift.TException {
      checkReady();
      getAllAppModules_call method_call = new getAllAppModules_call(authzToken, gatewayId, resultHandler, this, ___protocolFactory, ___transport);
      this.___currentMethod = method_call;
      ___manager.call(method_call);
    }

    public static class getAllAppModules_call extends org.apache.thrift.async.TAsyncMethodCall {
      private org.apache.airavata.model.security.AuthzToken authzToken;
      private String gatewayId;
      public getAllAppModules_call(org.apache.airavata.model.security.AuthzToken authzToken, String gatewayId, org.apache.thrift.async.AsyncMethodCallback resultHandler, org.apache.thrift.async.TAsyncClient client, org.apache.thrift.protocol.TProtocolFactory protocolFactory, org.apache.thrift.transport.TNonblockingTransport transport) throws org.apache.thrift.TException {
        super(client, protocolFactory, transport, resultHandler, false);
        this.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("getAllAppModules", org.apache.thrift.protocol.TMessageType.CALL, 0));
        getAllAppModules_args args = new getAllAppModules_args();
        args.setAuthzToken(authzToken);
        args.setGatewayId(gatewayId);
        args.write(prot);
        prot.writeMessageEnd();
      }

      public List<org.apache.airavata.model.appcatalog.appdeployment.ApplicationModule> getResult() throws org.apache.airavata.model.error.InvalidRequestException, org.apache.airavata.model.error.AiravataClientException, org.apache.airavata.model.error.AiravataSystemException, org.apache.airavata.model.error.AuthorizationException, org.apache.thrift.TException {
        if (getState() != org.apache.thrift.async.TAsyncMethodCall.State.RESPONSE_READ) {
          throw new IllegalStateException("Method call not finished!");
        }
        org.apache.thrift.transport.TMemoryInputTransport memoryTransport = new org.apache.thrift.transport.TMemoryInputTransport(getFrameBuffer().array());
        org.apache.thrift.protocol.TProtocol prot = client.getProtocolFactory().getProtocol(memoryTransport);
        return (new Client(prot)).recv_getAllAppModules();
      }
    }

    public void deleteApplicationModule(org.apache.airavata.model.security.AuthzToken authzToken, String appModuleId, org.apache.thrift.async.AsyncMethodCallback resultHandler) throws org.apache.thrift.TException {
      checkReady();
      deleteApplicationModule_call method_call = new deleteApplicationModule_call(authzToken, appModuleId, resultHandler, this, ___protocolFactory, ___transport);
      this.___currentMethod = method_call;
      ___manager.call(method_call);
    }

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

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

      public boolean getResult() throws org.apache.airavata.model.error.InvalidRequestException, org.apache.airavata.model.error.AiravataClientException, org.apache.airavata.model.error.AiravataSystemException, org.apache.airavata.model.error.AuthorizationException, org.apache.thrift.TException {
        if (getState() != org.apache.thrift.async.TAsyncMethodCall.State.RESPONSE_READ) {
          throw new IllegalStateException("Method call not finished!");
        }
        org.apache.thrift.transport.TMemoryInputTransport memoryTransport = new org.apache.thrift.transport.TMemoryInputTransport(getFrameBuffer().array());
        org.apache.thrift.protocol.TProtocol prot = client.getProtocolFactory().getProtocol(memoryTransport);
        return (new Client(prot)).recv_deleteApplicationModule();
      }
    }

    public void registerApplicationDeployment(org.apache.airavata.model.security.AuthzToken authzToken, String gatewayId, org.apache.airavata.model.appcatalog.appdeployment.ApplicationDeploymentDescription applicationDeployment, org.apache.thrift.async.AsyncMethodCallback resultHandler) throws org.apache.thrift.TException {
      checkReady();
      registerApplicationDeployment_call method_call = new registerApplicationDeployment_call(authzToken, gatewayId, applicationDeployment, resultHandler, this, ___protocolFactory, ___transport);
      this.___currentMethod = method_call;
      ___manager.call(method_call);
    }

    public static class registerApplicationDeployment_call extends org.apache.thrift.async.TAsyncMethodCall {
      private org.apache.airavata.model.security.AuthzToken authzToken;
      private String gatewayId;
      private org.apache.airavata.model.appcatalog.appdeployment.ApplicationDeploymentDescription applicationDeployment;
      public registerApplicationDeployment_call(org.apache.airavata.model.security.AuthzToken authzToken, String gatewayId, org.apache.airavata.model.appcatalog.appdeployment.ApplicationDeploymentDescription applicationDeployment, org.apache.thrift.async.AsyncMethodCallback resultHandler, org.apache.thrift.async.TAsyncClient client, org.apache.thrift.protocol.TProtocolFactory protocolFactory, org.apache.thrift.transport.TNonblockingTransport transport) throws org.apache.thrift.TException {
        super(client, protocolFactory, transport, resultHandler, false);
        this.authzToken = authzToken;
        this.gatewayId = gatewayId;
        this.applicationDeployment = applicationDeployment;
      }

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

      public String getResult() throws org.apache.airavata.model.error.InvalidRequestException, org.apache.airavata.model.error.AiravataClientException, org.apache.airavata.model.error.AiravataSystemException, org.apache.airavata.model.error.AuthorizationException, org.apache.thrift.TException {
        if (getState() != org.apache.thrift.async.TAsyncMethodCall.State.RESPONSE_READ) {
          throw new IllegalStateException("Method call not finished!");
        }
        org.apache.thrift.transport.TMemoryInputTransport memoryTransport = new org.apache.thrift.transport.TMemoryInputTransport(getFrameBuffer().array());
        org.apache.thrift.protocol.TProtocol prot = client.getProtocolFactory().getProtocol(memoryTransport);
        return (new Client(prot)).recv_registerApplicationDeployment();
      }
    }

    public void getApplicationDeployment(org.apache.airavata.model.security.AuthzToken authzToken, String appDeploymentId, org.apache.thrift.async.AsyncMethodCallback resultHandler) throws org.apache.thrift.TException {
      checkReady();
      getApplicationDeployment_call method_call = new getApplicationDeployment_call(authzToken, appDeploymentId, resultHandler, this, ___protocolFactory, ___transport);
      this.___currentMethod = method_call;
      ___manager.call(method_call);
    }

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

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

      public org.apache.airavata.model.appcatalog.appdeployment.ApplicationDeploymentDescription getResult() throws org.apache.airavata.model.error.InvalidRequestException, org.apache.airavata.model.error.AiravataClientException, org.apache.airavata.model.error.AiravataSystemException, org.apache.airavata.model.error.AuthorizationException, org.apache.thrift.TException {
        if (getState() != org.apache.thrift.async.TAsyncMethodCall.State.RESPONSE_READ) {
          throw new IllegalStateException("Method call not finished!");
        }
        org.apache.thrift.transport.TMemoryInputTransport memoryTransport = new org.apache.thrift.transport.TMemoryInputTransport(getFrameBuffer().array());
        org.apache.thrift.protocol.TProtocol prot = client.getProtocolFactory().getProtocol(memoryTransport);
        return (new Client(prot)).recv_getApplicationDeployment();
      }
    }

    public void updateApplicationDeployment(org.apache.airavata.model.security.AuthzToken authzToken, String appDeploymentId, org.apache.airavata.model.appcatalog.appdeployment.ApplicationDeploymentDescription applicationDeployment, org.apache.thrift.async.AsyncMethodCallback resultHandler) throws org.apache.thrift.TException {
      checkReady();
      updateApplicationDeployment_call method_call = new updateApplicationDeployment_call(authzToken, appDeploymentId, applicationDeployment, resultHandler, this, ___protocolFactory, ___transport);
      this.___currentMethod = method_call;
      ___manager.call(method_call);
    }

    public static class updateApplicationDeployment_call extends org.apache.thrift.async.TAsyncMethodCall {
      private org.apache.airavata.model.security.AuthzToken authzToken;
      private String appDeploymentId;
      private org.apache.airavata.model.appcatalog.appdeployment.ApplicationDeploymentDescription applicationDeployment;
      public updateApplicationDeployment_call(org.apache.airavata.model.security.AuthzToken authzToken, String appDeploymentId, org.apache.airavata.model.appcatalog.appdeployment.ApplicationDeploymentDescription applicationDeployment, org.apache.thrift.async.AsyncMethodCallback resultHandler, org.apache.thrift.async.TAsyncClient client, org.apache.thrift.protocol.TProtocolFactory protocolFactory, org.apache.thrift.transport.TNonblockingTransport transport) throws org.apache.thrift.TException {
        super(client, protocolFactory, transport, resultHandler, false);
        this.authzToken = authzToken;
        this.appDeploymentId = appDeploymentId;
        this.applicationDeployment = applicationDeployment;
      }

      public void write_args(org.apache.thrift.protocol.TProtocol prot) throws org.apache.thrift.TException {
        prot.writeMessageBegin(new org.apache.thrift.protocol.TMessage("updateApplicationDeployment", org.apache.thrift.protocol.TMessageType.CALL, 0));
        updateApplicationDeployment_args args = new updateApplicationDeployment_args();
        args.setAuthzToken(authzToken);
        args.setAppDeploymentId(appDeploymentId);
        args.setApplicationDeployment(applicationDeployment);
        args.write(prot);
        prot.writeMessageEnd();
      }

      public boolean getResult() throws org.apache.airavata.model.error.InvalidRequestException, org.apache.airavata.model.error.AiravataClientException, org.apache.airavata.model.error.AiravataSystemException, org.apache.airavata.model.error.AuthorizationException, org.apache.thrift.TException {
        if (getState() != org.apache.thrift.async.TAsyncMethodCall.State.RESPONSE_READ) {
          throw new IllegalStateException("Method call not finished!");
        }
        org.apache.thrift.transport.TMemoryInputTransport memoryTransport = new org.apache.thrift.transport.TMemoryInputTransport(getFrameBuffer().array());
        org.apache.thrift.protocol.TProtocol prot = client.getProtocolFactory().getProtocol(memoryTransport);
        return (new Client(prot)).recv_updateApplicationDeployment();
      }
    }

    public void deleteApplicationDeployment(org.apache.airavata.model.security.AuthzToken authzToken, String appDeploymentId, org.apache.thrift.async.AsyncMethodCallback resultHandler) throws org.apache.thrift.TException {
      checkReady();
      deleteApplicationDeployment_call method_call = new deleteApplicationDeployment_call(authzToken, appDeploymentId, resultHandler, this, ___protocolFactory, ___transport);
      this.___currentMethod = method_call;
      ___manager.call(method_call);
    }

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

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

      public boolean getResult() throws org.apache.airavata.model.error.InvalidRequestException, org.apache.airavata.model.error.AiravataClientException, org.apache.airavata.model.error.AiravataSystemException, org.apache.airavata.model.error.AuthorizationException, org.apache.thrift.TException {
        if (getState() != org.apache.thrift.async.TAsyncMethodCall.State.RESPONSE_READ) {
          throw new IllegalStateException("Method call not finished!");
        }
        org.apache.thrift.transport.TMemoryInputTransport memoryTransport = new org.apache.thrift.transport.TMemoryInputTransport(getFrameBuffer().array());
        org.apache.thrift.protocol.TProtocol prot = client.getProtocolFactory().getProtocol(memoryTransport);
        return (new Client(prot)).recv_deleteApplicationDeployment();
      }
    }

    public void getAllApplicationDeployments(org.apache.airavata.model.security.AuthzToken authzToken, String gatewayId, org.apache.thrift.async.AsyncMethodCallback resultHandler) throws org.apache.thrift.TException {
      checkReady();
      getAllApplicationDeployments_call method_call = new getAllApplicationDeployments_call(authzToken, gatewayId, resultHandler, this, ___protocolFactory, ___transport);
      this.___currentMethod = method_call;
      ___manager.call(method_call);
    }

    public static class getAllApplicationDeployments_call extends org.apache.thrift.async.TAsyncMethodCall {
      private org.apache.airavata.model.security.AuthzToken authzToken;
      private String gatewayId;
      public getAllApplicationDeployments_call(org.apache.airavata.model.security.AuthzToken authzToken, String gatewayId, org.apache.thrift.async.AsyncMethodCallback resultHandler, org.apache.thrift.async.TAsyncClient client, org.apache.thrift.protocol.TProtocolFactory protocolFactory, org.apache.thrift.transport.TNonblockingTransport transport) throws org.apache.thrift.TException {
        super(client, protocolFactory, transport, resultHandler, false);
        this.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("getAllApplicationDeployments", org.apache.thrift.protocol.TMessageType.CALL, 0));
        getAllApplicationDeployments_args args = new getAllApplicationDeployments_args();
        args.setAuthzToken(authzToken);
        args.setGatewayId(gatewayId);
        args.write(prot);
        prot.writeMessageEnd();
      }

      public List<org.apache.airavata.model.appcatalog.appdeployment.ApplicationDeploymentDescription> getResult() throws org.apache.airavata.model.error.InvalidRequestException, org.apache.airavata.model.error.AiravataClientException, org.apache.airavata.model.error.AiravataSystemException, org.apache.airavata.model.error.AuthorizationException, org.apache.thrift.TException {
        if (getState() != org.apache.thrift.async.TAsyncMethodCall.State.RESPONSE_READ) {
          throw new IllegalStateException("Method call not finished!");
        }
        org.apache.thrift.transport.TMemoryInputTransport memoryTransport = new org.apache.thrift.transport.TMemoryInputTransport(getFrameBuffer().array());
        org.apache.thrift.protocol.TProtocol prot = client.getProtocolFactory().getProtocol(memoryTransport);
        return (new Client(prot)).recv_getAllApplicationDeployments();
      }
    }

    public void getAppModuleDeployedResources(org.apache.airavata.model.security.AuthzToken authzToken, String appModuleId, org.apache.thrift.async.AsyncMethodCallback resultHandler) throws org.apache.thrift.TException {
      checkReady();
      getAppModuleDeployedResources_call method_call = new getAppModuleDeployedResources_call(authzToken, appModuleId, resultHandler, this, ___protocolFactory, ___transport);
      this.___currentMethod = method_call;
      ___manager.call(method_call);
    }

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

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

      public List<String> getResult() throws org.apache.airavata.model.error.InvalidRequestException, org.apache.airavata.model.error.AiravataClientException, org.apache.airavata.model.error.AiravataSystemException, org.apache.airavata.model.error.AuthorizationException, org.apache.thrift.TException {
        if (getState() != org.apache.thrift.async.TAsyncMethodCall.State.RESPONSE_READ) {
          throw new IllegalStateException("Method call not finished!");
        }
        org.apache.thrift.transport.TMemoryInputTransport memoryTransport = new org.apache.thrift.transport.TMemoryInputTransport(getFrameBuffer().array());
        org.apache.thrift.protocol.TProtocol prot = client.getProtocolFactory().getProtocol(memoryTransport);
        return (new Client(prot)).recv_getAppModuleDeployedResources();
      }
    }

    public void registerApplicationInterface(org.apache.airavata.model.security.AuthzToken authzToken, String gatewayId, org.apache.airavata.model.appcatalog.appinterface.ApplicationInterfaceDescription applicationInterface, org.apache.thrift.async.AsyncMethodCallback resultHandler) throws org.apache.thrift.TException {
      checkReady();
      registerApplicationInterface_call method_call = new registerApplicationInterface_call(authzToken, gatewayId, applicationInterface, resultHandler, this, ___protocolFactory, ___transport);
      this.___currentMethod = method_call;
      ___manager.call(method_call);
    }

    public static class registerApplicationInterface_call extends org.apache.thrift.async.TAsyncMethodCall {
      private org.apache.airavata.model.security.AuthzToken authzToken;
      private String gatewayId;
      private org.apache.airavata.model.appcatalog.appinterface.ApplicationInterfaceDescription applicationInterface;
      public registerApplicationInterface_call(org.apache.airavata.model.security.AuthzToken authzToken, String gatewayId, org.apache.airavata.model.appcatalog.appinterface.ApplicationInterfaceDescription applicationInterface, org.apache.thrift.async.AsyncMethodCallback resultHandler, org.apache.thrift.async.TAsyncClient client, org.apache.thrift.protocol.TProtocolFactory protocolFactory, org.apache.thrift.transport.TNonblockingTransport transport) throws org.apache.thrift.TException {
        super(client, protocolFactory, transport, resultHandler, false);
        this.authzToken = authzToken;
        this.gatewayId = gatewayId;
        this.applicationInterface = applicationInterface;
      }

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

      public String getResult() throws org.apache.airavata.model.error.InvalidRequestException, org.apache.airavata.model.error.AiravataClientException, org.apache.airavata.model.error.AiravataSystemException, org.apache.airavata.model.error.AuthorizationException, org.apache.thrift.TException {
        if (getState() != org.apache.thrift.async.TAsyncMethodCall.State.RESPONSE_READ) {
          throw new IllegalStateException("Method call not finished!");
        }
        org.apache.thrift.transport.TMemoryInputTransport memoryTransport = new org.apache.thrift.transport.TMemoryInputTransport(getFrameBuffer().array());
        org.apache.thrift.protocol.TProtocol prot = client.getProtocolFactory().getProtocol(memoryTransport);
        return (new Client(prot)).recv_registerApplicationInterface();
      }
    }

    public void getApplicationInterface(org.apache.airavata.model.security.AuthzToken authzToken, String appInterfaceId, org.apache.thrift.async.AsyncMethodCallback resultHandler) throws org.apache.thrift.TException {
      checkReady();
      getApplicationInterface_call method_call = new getApplicationInterface_call(authzToken, appInterfaceId, resultHandler, this, ___protocolFactory, ___transport);
      this.___currentMethod = method_call;
      ___manager.call(method_call);
    }

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

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

      public org.apache.airavata.model.appcatalog.appinterface.ApplicationInterfaceDescription getResult() throws org.apache.airavata.model.error.InvalidRequestException, org.apache.airavata.model.error.AiravataClientException, org.apache.airavata.model.error.AiravataSystemException, org.apache.airavata.model.error.AuthorizationException, org.apache.thrift.TException {
        if (getState() != org.apache.thrift.async.TAsyncMethodCall.State.RESPONSE_READ) {
          throw new IllegalStateException("Method call not finished!");
        }
        org.apache.thrift.transport.TMemoryInputTransport memoryTransport = new org.apache.thrift.transport.TMemoryInputTransport(getFrameBuffer().array());
        org.apache.thrift.protocol.TProtocol prot = client.getProtocolFactory().getProtocol(memoryTransport);
        return (new Client(prot)).recv_getApplicationInterface();
      }
    }

    public void updateApplicationInterface(org.apache.airavata.model.security.AuthzToken authzToken, String appInterfaceId, org.apache.airavata.model.appcatalog.appinterface.ApplicationInterfaceDescription applicationInterface, org.apache.thrift.async.AsyncMethodCallback resultHandler) throws org.apache.thrift.TException {
      checkReady();
      updateApplicationInterface_call method_call = new updateApplicationInterface_call(authzToken, appInterfaceId, applicationInterface, resultHandler, this, ___protocolFactory, ___transport);
      this.___currentMethod = method_call;
      ___manager.call(method_call);
    }

    public static class updateApplicationInterface_call extends org.apache.thrift.async.TAsyncMethodCall {
      private org.apache.airavata.model.security.AuthzToken authzToken;
      private String appInterfaceId;
      private org.apache.airavata.model.appcatalog.appinterface.ApplicationInterfaceDescription applicationInterface;
      public updateApplicationInterface_call(org.apache.airavata.model.security.AuthzToken authzToken, String appInterfaceId, org.apache.airavata.model.appcatalog.appinterface.ApplicationInterfaceDescription applicationInterface, org.apache.thrift.async.AsyncMethodCallback resultHandler, org.apache.thrift.async.TAsyncClient client, org.apache.thrift.protocol.TProtocolFactory protocolFactory, org.apache.thrift.transport.TNonblockingTransport transport) throws org.apache.thrift.TException {
        super(client, protocolFactory, transport, resultHandler, false);
        this.authzToken = authzToken;
        this.appInterfaceId = appInterfaceId;
        this.applicationInterface = applicationInterface;
      }

      public void write_args(org.apache.thrift.protocol.TProtocol prot) throws org.apache.thrift.TException {
        prot.writeMessageBegin(new org.apache.thrift.protocol.TMessage("updateApplicationInterface", org.apache.thrift.protocol.TMessageType.CALL, 0));
        updateApplicationInterface_args args = new updateApplicationInterface_args();
        args.setAuthzToken(authzToken);
        args.setAppInterfaceId(appInterfaceId);
        args.setApplicationInterface(applicationInterface);
        args.write(prot);
        prot.writeMessageEnd();
      }

      public boolean getResult() throws org.apache.airavata.model.error.InvalidRequestException, org.apache.airavata.model.error.AiravataClientException, org.apache.airavata.model.error.AiravataSystemException, org.apache.airavata.model.error.AuthorizationException, org.apache.thrift.TException {
        if (getState() != org.apache.thrift.async.TAsyncMethodCall.State.RESPONSE_READ) {
          throw new IllegalStateException("Method call not finished!");
        }
        org.apache.thrift.transport.TMemoryInputTransport memoryTransport = new org.apache.thrift.transport.TMemoryInputTransport(getFrameBuffer().array());
        org.apache.thrift.protocol.TProtocol prot = client.getProtocolFactory().getProtocol(memoryTransport);
        return (new Client(prot)).recv_updateApplicationInterface();
      }
    }

    public void deleteApplicationInterface(org.apache.airavata.model.security.AuthzToken authzToken, String appInterfaceId, org.apache.thrift.async.AsyncMethodCallback resultHandler) throws org.apache.thrift.TException {
      checkReady();
      deleteApplicationInterface_call method_call = new deleteApplicationInterface_call(authzToken, appInterfaceId, resultHandler, this, ___protocolFactory, ___transport);
      this.___currentMethod = method_call;
      ___manager.call(method_call);
    }

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

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

      public boolean getResult() throws org.apache.airavata.model.error.InvalidRequestException, org.apache.airavata.model.error.AiravataClientException, org.apache.airavata.model.error.AiravataSystemException, org.apache.airavata.model.error.AuthorizationException, org.apache.thrift.TException {
        if (getState() != org.apache.thrift.async.TAsyncMethodCall.State.RESPONSE_READ) {
          throw new IllegalStateException("Method call not finished!");
        }
        org.apache.thrift.transport.TMemoryInputTransport memoryTransport = new org.apache.thrift.transport.TMemoryInputTransport(getFrameBuffer().array());
        org.apache.thrift.protocol.TProtocol prot = client.getProtocolFactory().getProtocol(memoryTransport);
        return (new Client(prot)).recv_deleteApplicationInterface();
      }
    }

    public void getAllApplicationInterfaceNames(org.apache.airavata.model.security.AuthzToken authzToken, String gatewayId, org.apache.thrift.async.AsyncMethodCallback resultHandler) throws org.apache.thrift.TException {
      checkReady();
      getAllApplicationInterfaceNames_call method_call = new getAllApplicationInterfaceNames_call(authzToken, gatewayId, resultHandler, this, ___protocolFactory, ___transport);
      this.___currentMethod = method_call;
      ___manager.call(method_call);
    }

    public static class getAllApplicationInterfaceNames_call extends org.apache.thrift.async.TAsyncMethodCall {
      private org.apache.airavata.model.security.AuthzToken authzToken;
      private String gatewayId;
      public getAllApplicationInterfaceNames_call(org.apache.airavata.model.security.AuthzToken authzToken, String gatewayId, org.apache.thrift.async.AsyncMethodCallback resultHandler, org.apache.thrift.async.TAsyncClient client, org.apache.thrift.protocol.TProtocolFactory protocolFactory, org.apache.thrift.transport.TNonblockingTransport transport) throws org.apache.thrift.TException {
        super(client, protocolFactory, transport, resultHandler, false);
        this.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("getAllApplicationInterfaceNames", org.apache.thrift.protocol.TMessageType.CALL, 0));
        getAllApplicationInterfaceNames_args args = new getAllApplicationInterfaceNames_args();
        args.setAuthzToken(authzToken);
        args.setGatewayId(gatewayId);
        args.write(prot);
        prot.writeMessageEnd();
      }

      public Map<String,String> getResult() throws org.apache.airavata.model.error.InvalidRequestException, org.apache.airavata.model.error.AiravataClientException, org.apache.airavata.model.error.AiravataSystemException, org.apache.airavata.model.error.AuthorizationException, org.apache.thrift.TException {
        if (getState() != org.apache.thrift.async.TAsyncMethodCall.State.RESPONSE_READ) {
          throw new IllegalStateException("Method call not finished!");
        }
        org.apache.thrift.transport.TMemoryInputTransport memoryTransport = new org.apache.thrift.transport.TMemoryInputTransport(getFrameBuffer().array());
        org.apache.thrift.protocol.TProtocol prot = client.getProtocolFactory().getProtocol(memoryTransport);
        return (new Client(prot)).recv_getAllApplicationInterfaceNames();
      }
    }

    public void getAllApplicationInterfaces(org.apache.airavata.model.security.AuthzToken authzToken, String gatewayId, org.apache.thrift.async.AsyncMethodCallback resultHandler) throws org.apache.thrift.TException {
      checkReady();
      getAllApplicationInterfaces_call method_call = new getAllApplicationInterfaces_call(authzToken, gatewayId, resultHandler, this, ___protocolFactory, ___transport);
      this.___currentMethod = method_call;
      ___manager.call(method_call);
    }

    public static class getAllApplicationInterfaces_call extends org.apache.thrift.async.TAsyncMethodCall {
      private org.apache.airavata.model.security.AuthzToken authzToken;
      private String gatewayId;
      public getAllApplicationInterfaces_call(org.apache.airavata.model.security.AuthzToken authzToken, String gatewayId, org.apache.thrift.async.AsyncMethodCallback resultHandler, org.apache.thrift.async.TAsyncClient client, org.apache.thrift.protocol.TProtocolFactory protocolFactory, org.apache.thrift.transport.TNonblockingTransport transport) throws org.apache.thrift.TException {
        super(client, protocolFactory, transport, resultHandler, false);
        this.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("getAllApplicationInterfaces", org.apache.thrift.protocol.TMessageType.CALL, 0));
        getAllApplicationInterfaces_args args = new getAllApplicationInterfaces_args();
        args.setAuthzToken(authzToken);
        args.setGatewayId(gatewayId);
        args.write(prot);
        prot.writeMessageEnd();
      }

      public List<org.apache.airavata.model.appcatalog.appinterface.ApplicationInterfaceDescription> getResult() throws org.apache.airavata.model.error.InvalidRequestException, org.apache.airavata.model.error.AiravataClientException, org.apache.airavata.model.error.AiravataSystemException, org.apache.airavata.model.error.AuthorizationException, org.apache.thrift.TException {
        if (getState() != org.apache.thrift.async.TAsyncMethodCall.State.RESPONSE_READ) {
          throw new IllegalStateException("Method call not finished!");
        }
        org.apache.thrift.transport.TMemoryInputTransport memoryTransport = new org.apache.thrift.transport.TMemoryInputTransport(getFrameBuffer().array());
        org.apache.thrift.protocol.TProtocol prot = client.getProtocolFactory().getProtocol(memoryTransport);
        return (new Client(prot)).recv_getAllApplicationInterfaces();
      }
    }

    public void getApplicationInputs(org.apache.airavata.model.security.AuthzToken authzToken, String appInterfaceId, org.apache.thrift.async.AsyncMethodCallback resultHandler) throws org.apache.thrift.TException {
      checkReady();
      getApplicationInputs_call method_call = new getApplicationInputs_call(authzToken, appInterfaceId, resultHandler, this, ___protocolFactory, ___transport);
      this.___currentMethod = method_call;
      ___manager.call(method_call);
    }

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

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

      public List<org.apache.airavata.model.application.io.InputDataObjectType> getResult() throws org.apache.airavata.model.error.InvalidRequestException, org.apache.airavata.model.error.AiravataClientException, org.apache.airavata.model.error.AiravataSystemException, org.apache.airavata.model.error.AuthorizationException, org.apache.thrift.TException {
        if (getState() != org.apache.thrift.async.TAsyncMethodCall.State.RESPONSE_READ) {
          throw new IllegalStateException("Method call not finished!");
        }
        org.apache.thrift.transport.TMemoryInputTransport memoryTransport = new org.apache.thrift.transport.TMemoryInputTransport(getFrameBuffer().array());
        org.apache.thrift.protocol.TProtocol prot = client.getProtocolFactory().getProtocol(memoryTransport);
        return (new Client(prot)).recv_getApplicationInputs();
      }
    }

    public void getApplicationOutputs(org.apache.airavata.model.security.AuthzToken authzToken, String appInterfaceId, org.apache.thrift.async.AsyncMethodCallback resultHandler) throws org.apache.thrift.TException {
      checkReady();
      getApplicationOutputs_call method_call = new getApplicationOutputs_call(authzToken, appInterfaceId, resultHandler, this, ___protocolFactory, ___transport);
      this.___currentMethod = method_call;
      ___manager.call(method_call);
    }

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

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

      public List<org.apache.airavata.model.application.io.OutputDataObjectType> getResult() throws org.apache.airavata.model.error.InvalidRequestException, org.apache.airavata.model.error.AiravataClientException, org.apache.airavata.model.error.AiravataSystemException, org.apache.airavata.model.error.AuthorizationException, org.apache.thrift.TException {
        if (getState() != org.apache.thrift.async.TAsyncMethodCall.State.RESPONSE_READ) {
          throw new IllegalStateException("Method call not finished!");
        }
        org.apache.thrift.transport.TMemoryInputTransport memoryTransport = new org.apache.thrift.transport.TMemoryInputTransport(getFrameBuffer().array());
        org.apache.thrift.protocol.TProtocol prot = client.getProtocolFactory().getProtocol(memoryTransport);
        return (new Client(prot)).recv_getApplicationOutputs();
      }
    }

    public void getAvailableAppInterfaceComputeResources(org.apache.airavata.model.security.AuthzToken authzToken, String appInterfaceId, org.apache.thrift.async.AsyncMethodCallback resultHandler) throws org.apache.thrift.TException {
      checkReady();
      getAvailableAppInterfaceComputeResources_call method_call = new getAvailableAppInterfaceComputeResources_call(authzToken, appInterfaceId, resultHandler, this, ___protocolFactory, ___transport);
      this.___currentMethod = method_call;
      ___manager.call(method_call);
    }

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

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

      public Map<String,String> getResult() throws org.apache.airavata.model.error.InvalidRequestException, org.apache.airavata.model.error.AiravataClientException, org.apache.airavata.model.error.AiravataSystemException, org.apache.airavata.model.error.AuthorizationException, org.apache.thrift.TException {
        if (getState() != org.apache.thrift.async.TAsyncMethodCall.State.RESPONSE_READ) {
          throw new IllegalStateException("Method call not finished!");
        }
        org.apache.thrift.transport.TMemoryInputTransport memoryTransport = new org.apache.thrift.transport.TMemoryInputTransport(getFrameBuffer().array());
        org.apache.thrift.protocol.TProtocol prot = client.getProtocolFactory().getProtocol(memoryTransport);
        return (new Client(prot)).recv_getAvailableAppInterfaceComputeResources();
      }
    }

    public void registerComputeResource(org.apache.airavata.model.security.AuthzToken authzToken, org.apache.airavata.model.appcatalog.computeresource.ComputeResourceDescription computeResourceDescription, org.apache.thrift.async.AsyncMethodCallback resultHandler) throws org.apache.thrift.TException {
      checkReady();
      registerComputeResource_call method_call = new registerComputeResource_call(authzToken, computeResourceDescription, resultHandler, this, ___protocolFactory, ___transport);
      this.___currentMethod = method_call;
      ___manager.call(method_call);
    }

    public static class registerComputeResource_call extends org.apache.thrift.async.TAsyncMethodCall {
      private org.apache.airavata.model.security.AuthzToken authzToken;
      private org.apache.airavata.model.appcatalog.computeresource.ComputeResourceDescription computeResourceDescription;
      public registerComputeResource_call(org.apache.airavata.model.security.AuthzToken authzToken, org.apache.airavata.model.appcatalog.computeresource.ComputeResourceDescription computeResourceDescription, org.apache.thrift.async.AsyncMethodCallback resultHandler, org.apache.thrift.async.TAsyncClient client, org.apache.thrift.protocol.TProtocolFactory protocolFactory, org.apache.thrift.transport.TNonblockingTransport transport) throws org.apache.thrift.TException {
        super(client, protocolFactory, transport, resultHandler, false);
        this.authzToken = authzToken;
        this.computeResourceDescription = computeResourceDescription;
      }

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

      public String getResult() throws org.apache.airavata.model.error.InvalidRequestException, org.apache.airavata.model.error.AiravataClientException, org.apache.airavata.model.error.AiravataSystemException, org.apache.airavata.model.error.AuthorizationException, org.apache.thrift.TException {
        if (getState() != org.apache.thrift.async.TAsyncMethodCall.State.RESPONSE_READ) {
          throw new IllegalStateException("Method call not finished!");
        }
        org.apache.thrift.transport.TMemoryInputTransport memoryTransport = new org.apache.thrift.transport.TMemoryInputTransport(getFrameBuffer().array());
        org.apache.thrift.protocol.TProtocol prot = client.getProtocolFactory().getProtocol(memoryTransport);
        return (new Client(prot)).recv_registerComputeResource();
      }
    }

    public void getComputeResource(org.apache.airavata.model.security.AuthzToken authzToken, String computeResourceId, org.apache.thrift.async.AsyncMethodCallback resultHandler) throws org.apache.thrift.TException {
      checkReady();
      getComputeResource_call method_call = new getComputeResource_call(authzToken, computeResourceId, resultHandler, this, ___protocolFactory, ___transport);
      this.___currentMethod = method_call;
      ___manager.call(method_call);
    }

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

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

      public org.apache.airavata.model.appcatalog.computeresource.ComputeResourceDescription getResult() throws org.apache.airavata.model.error.InvalidRequestException, org.apache.airavata.model.error.AiravataClientException, org.apache.airavata.model.error.AiravataSystemException, org.apache.airavata.model.error.AuthorizationException, org.apache.thrift.TException {
        if (getState() != org.apache.thrift.async.TAsyncMethodCall.State.RESPONSE_READ) {
          throw new IllegalStateException("Method call not finished!");
        }
        org.apache.thrift.transport.TMemoryInputTransport memoryTransport = new org.apache.thrift.transport.TMemoryInputTransport(getFrameBuffer().array());
        org.apache.thrift.protocol.TProtocol prot = client.getProtocolFactory().getProtocol(memoryTransport);
        return (new Client(prot)).recv_getComputeResource();
      }
    }

    public void getAllComputeResourceNames(org.apache.airavata.model.security.AuthzToken authzToken, org.apache.thrift.async.AsyncMethodCallback resultHandler) throws org.apache.thrift.TException {
      checkReady();
      getAllComputeResourceNames_call method_call = new getAllComputeResourceNames_call(authzToken, resultHandler, this, ___protocolFactory, ___transport);
      this.___currentMethod = method_call;
      ___manager.call(method_call);
    }

    public static class getAllComputeResourceNames_call extends org.apache.thrift.async.TAsyncMethodCall {
      private org.apache.airavata.model.security.AuthzToken authzToken;
      public getAllComputeResourceNames_call(org.apache.airavata.model.security.AuthzToken authzToken, org.apache.thrift.async.AsyncMethodCallback resultHandler, org.apache.thrift.async.TAsyncClient client, org.apache.thrift.protocol.TProtocolFactory protocolFactory, org.apache.thrift.transport.TNonblockingTransport transport) throws org.apache.thrift.TException {
        super(client, protocolFactory, transport, resultHandler, false);
        this.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("getAllComputeResourceNames", org.apache.thrift.protocol.TMessageType.CALL, 0));
        getAllComputeResourceNames_args args = new getAllComputeResourceNames_args();
        args.setAuthzToken(authzToken);
        args.write(prot);
        prot.writeMessageEnd();
      }

      public Map<String,String> getResult() throws org.apache.airavata.model.error.InvalidRequestException, org.apache.airavata.model.error.AiravataClientException, org.apache.airavata.model.error.AiravataSystemException, org.apache.airavata.model.error.AuthorizationException, org.apache.thrift.TException {
        if (getState() != org.apache.thrift.async.TAsyncMethodCall.State.RESPONSE_READ) {
          throw new IllegalStateException("Method call not finished!");
        }
        org.apache.thrift.transport.TMemoryInputTransport memoryTransport = new org.apache.thrift.transport.TMemoryInputTransport(getFrameBuffer().array());
        org.apache.thrift.protocol.TProtocol prot = client.getProtocolFactory().getProtocol(memoryTransport);
        return (new Client(prot)).recv_getAllComputeResourceNames();
      }
    }

    public void updateComputeResource(org.apache.airavata.model.security.AuthzToken authzToken, String computeResourceId, org.apache.airavata.model.appcatalog.computeresource.ComputeResourceDescription computeResourceDescription, org.apache.thrift.async.AsyncMethodCallback resultHandler) throws org.apache.thrift.TException {
      checkReady();
      updateComputeResource_call method_call = new updateComputeResource_call(authzToken, computeResourceId, computeResourceDescription, resultHandler, this, ___protocolFactory, ___transport);
      this.___currentMethod = method_call;
      ___manager.call(method_call);
    }

    public static class updateComputeResource_call extends org.apache.thrift.async.TAsyncMethodCall {
      private org.apache.airavata.model.security.AuthzToken authzToken;
      private String computeResourceId;
      private org.apache.airavata.model.appcatalog.computeresource.ComputeResourceDescription computeResourceDescription;
      public updateComputeResource_call(org.apache.airavata.model.security.AuthzToken authzToken, String computeResourceId, org.apache.airavata.model.appcatalog.computeresource.ComputeResourceDescription computeResourceDescription, org.apache.thrift.async.AsyncMethodCallback resultHandler, org.apache.thrift.async.TAsyncClient client, org.apache.thrift.protocol.TProtocolFactory protocolFactory, org.apache.thrift.transport.TNonblockingTransport transport) throws org.apache.thrift.TException {
        super(client, protocolFactory, transport, resultHandler, false);
        this.authzToken = authzToken;
        this.computeResourceId = computeResourceId;
        this.computeResourceDescription = computeResourceDescription;
      }

      public void write_args(org.apache.thrift.protocol.TProtocol prot) throws org.apache.thrift.TException {
        prot.writeMessageBegin(new org.apache.thrift.protocol.TMessage("updateComputeResource", org.apache.thrift.protocol.TMessageType.CALL, 0));
        updateComputeResource_args args = new updateComputeResource_args();
        args.setAuthzToken(authzToken);
        args.setComputeResourceId(computeResourceId);
        args.setComputeResourceDescription(computeResourceDescription);
        args.write(prot);
        prot.writeMessageEnd();
      }

      public boolean getResult() throws org.apache.airavata.model.error.InvalidRequestException, org.apache.airavata.model.error.AiravataClientException, org.apache.airavata.model.error.AiravataSystemException, org.apache.airavata.model.error.AuthorizationException, org.apache.thrift.TException {
        if (getState() != org.apache.thrift.async.TAsyncMethodCall.State.RESPONSE_READ) {
          throw new IllegalStateException("Method call not finished!");
        }
        org.apache.thrift.transport.TMemoryInputTransport memoryTransport = new org.apache.thrift.transport.TMemoryInputTransport(getFrameBuffer().array());
        org.apache.thrift.protocol.TProtocol prot = client.getProtocolFactory().getProtocol(memoryTransport);
        return (new Client(prot)).recv_updateComputeResource();
      }
    }

    public void deleteComputeResource(org.apache.airavata.model.security.AuthzToken authzToken, String computeResourceId, org.apache.thrift.async.AsyncMethodCallback resultHandler) throws org.apache.thrift.TException {
      checkReady();
      deleteComputeResource_call method_call = new deleteComputeResource_call(authzToken, computeResourceId, resultHandler, this, ___protocolFactory, ___transport);
      this.___currentMethod = method_call;
      ___manager.call(method_call);
    }

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

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

      public boolean getResult() throws org.apache.airavata.model.error.InvalidRequestException, org.apache.airavata.model.error.AiravataClientException, org.apache.airavata.model.error.AiravataSystemException, org.apache.airavata.model.error.AuthorizationException, org.apache.thrift.TException {
        if (getState() != org.apache.thrift.async.TAsyncMethodCall.State.RESPONSE_READ) {
          throw new IllegalStateException("Method call not finished!");
        }
        org.apache.thrift.transport.TMemoryInputTransport memoryTransport = new org.apache.thrift.transport.TMemoryInputTransport(getFrameBuffer().array());
        org.apache.thrift.protocol.TProtocol prot = client.getProtocolFactory().getProtocol(memoryTransport);
        return (new Client(prot)).recv_deleteComputeResource();
      }
    }

    public void addLocalSubmissionDetails(org.apache.airavata.model.security.AuthzToken authzToken, String computeResourceId, int priorityOrder, org.apache.airavata.model.appcatalog.computeresource.LOCALSubmission localSubmission, org.apache.thrift.async.AsyncMethodCallback resultHandler) throws org.apache.thrift.TException {
      checkReady();
      addLocalSubmissionDetails_call method_call = new addLocalSubmissionDetails_call(authzToken, computeResourceId, priorityOrder, localSubmission, resultHandler, this, ___protocolFactory, ___transport);
      this.___currentMethod = method_call;
      ___manager.call(method_call);
    }

    public static class addLocalSubmissionDetails_call extends org.apache.thrift.async.TAsyncMethodCall {
      private org.apache.airavata.model.security.AuthzToken authzToken;
      private String computeResourceId;
      private int priorityOrder;
      private org.apache.airavata.model.appcatalog.computeresource.LOCALSubmission localSubmission;
      public addLocalSubmissionDetails_call(org.apache.airavata.model.security.AuthzToken authzToken, String computeResourceId, int priorityOrder, org.apache.airavata.model.appcatalog.computeresource.LOCALSubmission localSubmission, org.apache.thrift.async.AsyncMethodCallback resultHandler, org.apache.thrift.async.TAsyncClient client, org.apache.thrift.protocol.TProtocolFactory protocolFactory, org.apache.thrift.transport.TNonblockingTransport transport) throws org.apache.thrift.TException {
        super(client, protocolFactory, transport, resultHandler, false);
        this.authzToken = authzToken;
        this.computeResourceId = computeResourceId;
        this.priorityOrder = priorityOrder;
        this.localSubmission = localSubmission;
      }

      public void write_args(org.apache.thrift.protocol.TProtocol prot) throws org.apache.thrift.TException {
        prot.writeMessageBegin(new org.apache.thrift.protocol.TMessage("addLocalSubmissionDetails", org.apache.thrift.protocol.TMessageType.CALL, 0));
        addLocalSubmissionDetails_args args = new addLocalSubmissionDetails_args();
        args.setAuthzToken(authzToken);
        args.setComputeResourceId(computeResourceId);
        args.setPriorityOrder(priorityOrder);
        args.setLocalSubmission(localSubmission);
        args.write(prot);
        prot.writeMessageEnd();
      }

      public String getResult() throws org.apache.airavata.model.error.InvalidRequestException, org.apache.airavata.model.error.AiravataClientException, org.apache.airavata.model.error.AiravataSystemException, org.apache.airavata.model.error.AuthorizationException, org.apache.thrift.TException {
        if (getState() != org.apache.thrift.async.TAsyncMethodCall.State.RESPONSE_READ) {
          throw new IllegalStateException("Method call not finished!");
        }
        org.apache.thrift.transport.TMemoryInputTransport memoryTransport = new org.apache.thrift.transport.TMemoryInputTransport(getFrameBuffer().array());
        org.apache.thrift.protocol.TProtocol prot = client.getProtocolFactory().getProtocol(memoryTransport);
        return (new Client(prot)).recv_addLocalSubmissionDetails();
      }
    }

    public void updateLocalSubmissionDetails(org.apache.airavata.model.security.AuthzToken authzToken, String jobSubmissionInterfaceId, org.apache.airavata.model.appcatalog.computeresource.LOCALSubmission localSubmission, org.apache.thrift.async.AsyncMethodCallback resultHandler) throws org.apache.thrift.TException {
      checkReady();
      updateLocalSubmissionDetails_call method_call = new updateLocalSubmissionDetails_call(authzToken, jobSubmissionInterfaceId, localSubmission, resultHandler, this, ___protocolFactory, ___transport);
      this.___currentMethod = method_call;
      ___manager.call(method_call);
    }

    public static class updateLocalSubmissionDetails_call extends org.apache.thrift.async.TAsyncMethodCall {
      private org.apache.airavata.model.security.AuthzToken authzToken;
      private String jobSubmissionInterfaceId;
      private org.apache.airavata.model.appcatalog.computeresource.LOCALSubmission localSubmission;
      public updateLocalSubmissionDetails_call(org.apache.airavata.model.security.AuthzToken authzToken, String jobSubmissionInterfaceId, org.apache.airavata.model.appcatalog.computeresource.LOCALSubmission localSubmission, org.apache.thrift.async.AsyncMethodCallback resultHandler, org.apache.thrift.async.TAsyncClient client, org.apache.thrift.protocol.TProtocolFactory protocolFactory, org.apache.thrift.transport.TNonblockingTransport transport) throws org.apache.thrift.TException {
        super(client, protocolFactory, transport, resultHandler, false);
        this.authzToken = authzToken;
        this.jobSubmissionInterfaceId = jobSubmissionInterfaceId;
        this.localSubmission = localSubmission;
      }

      public void write_args(org.apache.thrift.protocol.TProtocol prot) throws org.apache.thrift.TException {
        prot.writeMessageBegin(new org.apache.thrift.protocol.TMessage("updateLocalSubmissionDetails", org.apache.thrift.protocol.TMessageType.CALL, 0));
        updateLocalSubmissionDetails_args args = new updateLocalSubmissionDetails_args();
        args.setAuthzToken(authzToken);
        args.setJobSubmissionInterfaceId(jobSubmissionInterfaceId);
        args.setLocalSubmission(localSubmission);
        args.write(prot);
        prot.writeMessageEnd();
      }

      public boolean getResult() throws org.apache.airavata.model.error.InvalidRequestException, org.apache.airavata.model.error.AiravataClientException, org.apache.airavata.model.error.AiravataSystemException, org.apache.airavata.model.error.AuthorizationException, org.apache.thrift.TException {
        if (getState() != org.apache.thrift.async.TAsyncMethodCall.State.RESPONSE_READ) {
          throw new IllegalStateException("Method call not finished!");
        }
        org.apache.thrift.transport.TMemoryInputTransport memoryTransport = new org.apache.thrift.transport.TMemoryInputTransport(getFrameBuffer().array());
        org.apache.thrift.protocol.TProtocol prot = client.getProtocolFactory().getProtocol(memoryTransport);
        return (new Client(prot)).recv_updateLocalSubmissionDetails();
      }
    }

    public void getLocalJobSubmission(org.apache.airavata.model.security.AuthzToken authzToken, String jobSubmissionId, org.apache.thrift.async.AsyncMethodCallback resultHandler) throws org.apache.thrift.TException {
      checkReady();
      getLocalJobSubmission_call method_call = new getLocalJobSubmission_call(authzToken, jobSubmissionId, resultHandler, this, ___protocolFactory, ___transport);
      this.___currentMethod = method_call;
      ___manager.call(method_call);
    }

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

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

      public org.apache.airavata.model.appcatalog.computeresource.LOCALSubmission getResult() throws org.apache.airavata.model.error.InvalidRequestException, org.apache.airavata.model.error.AiravataClientException, org.apache.airavata.model.error.AiravataSystemException, org.apache.airavata.model.error.AuthorizationException, org.apache.thrift.TException {
        if (getState() != org.apache.thrift.async.TAsyncMethodCall.State.RESPONSE_READ) {
          throw new IllegalStateException("Method call not finished!");
        }
        org.apache.thrift.transport.TMemoryInputTransport memoryTransport = new org.apache.thrift.transport.TMemoryInputTransport(getFrameBuffer().array());
        org.apache.thrift.protocol.TProtocol prot = client.getProtocolFactory().getProtocol(memoryTransport);
        return (new Client(prot)).recv_getLocalJobSubmission();
      }
    }

    public void addSSHJobSubmissionDetails(org.apache.airavata.model.security.AuthzToken authzToken, String computeResourceId, int priorityOrder, org.apache.airavata.model.appcatalog.computeresource.SSHJobSubmission sshJobSubmission, org.apache.thrift.async.AsyncMethodCallback resultHandler) throws org.apache.thrift.TException {
      checkReady();
      addSSHJobSubmissionDetails_call method_call = new addSSHJobSubmissionDetails_call(authzToken, computeResourceId, priorityOrder, sshJobSubmission, resultHandler, this, ___protocolFactory, ___transport);
      this.___currentMethod = method_call;
      ___manager.call(method_call);
    }

    public static class addSSHJobSubmissionDetails_call extends org.apache.thrift.async.TAsyncMethodCall {
      private org.apache.airavata.model.security.AuthzToken authzToken;
      private String computeResourceId;
      private int priorityOrder;
      private org.apache.airavata.model.appcatalog.computeresource.SSHJobSubmission sshJobSubmission;
      public addSSHJobSubmissionDetails_call(org.apache.airavata.model.security.AuthzToken authzToken, String computeResourceId, int priorityOrder, org.apache.airavata.model.appcatalog.computeresource.SSHJobSubmission sshJobSubmission, org.apache.thrift.async.AsyncMethodCallback resultHandler, org.apache.thrift.async.TAsyncClient client, org.apache.thrift.protocol.TProtocolFactory protocolFactory, org.apache.thrift.transport.TNonblockingTransport transport) throws org.apache.thrift.TException {
        super(client, protocolFactory, transport, resultHandler, false);
        this.authzToken = authzToken;
        this.computeResourceId = computeResourceId;
        this.priorityOrder = priorityOrder;
        this.sshJobSubmission = sshJobSubmission;
      }

      public void write_args(org.apache.thrift.protocol.TProtocol prot) throws org.apache.thrift.TException {
        prot.writeMessageBegin(new org.apache.thrift.protocol.TMessage("addSSHJobSubmissionDetails", org.apache.thrift.protocol.TMessageType.CALL, 0));
        addSSHJobSubmissionDetails_args args = new addSSHJobSubmissionDetails_args();
        args.setAuthzToken(authzToken);
        args.setComputeResourceId(computeResourceId);
        args.setPriorityOrder(priorityOrder);
        args.setSshJobSubmission(sshJobSubmission);
        args.write(prot);
        prot.writeMessageEnd();
      }

      public String getResult() throws org.apache.airavata.model.error.InvalidRequestException, org.apache.airavata.model.error.AiravataClientException, org.apache.airavata.model.error.AiravataSystemException, org.apache.airavata.model.error.AuthorizationException, org.apache.thrift.TException {
        if (getState() != org.apache.thrift.async.TAsyncMethodCall.State.RESPONSE_READ) {
          throw new IllegalStateException("Method call not finished!");
        }
        org.apache.thrift.transport.TMemoryInputTransport memoryTransport = new org.apache.thrift.transport.TMemoryInputTransport(getFrameBuffer().array());
        org.apache.thrift.protocol.TProtocol prot = client.getProtocolFactory().getProtocol(memoryTransport);
        return (new Client(prot)).recv_addSSHJobSubmissionDetails();
      }
    }

    public void addSSHForkJobSubmissionDetails(org.apache.airavata.model.security.AuthzToken authzToken, String computeResourceId, int priorityOrder, org.apache.airavata.model.appcatalog.computeresource.SSHJobSubmission sshJobSubmission, org.apache.thrift.async.AsyncMethodCallback resultHandler) throws org.apache.thrift.TException {
      checkReady();
      addSSHForkJobSubmissionDetails_call method_call = new addSSHForkJobSubmissionDetails_call(authzToken, computeResourceId, priorityOrder, sshJobSubmission, resultHandler, this, ___protocolFactory, ___transport);
      this.___currentMethod = method_call;
      ___manager.call(method_call);
    }

    public static class addSSHForkJobSubmissionDetails_call extends org.apache.thrift.async.TAsyncMethodCall {
      private org.apache.airavata.model.security.AuthzToken authzToken;
      private String computeResourceId;
      private int priorityOrder;
      private org.apache.airavata.model.appcatalog.computeresource.SSHJobSubmission sshJobSubmission;
      public addSSHForkJobSubmissionDetails_call(org.apache.airavata.model.security.AuthzToken authzToken, String computeResourceId, int priorityOrder, org.apache.airavata.model.appcatalog.computeresource.SSHJobSubmission sshJobSubmission, org.apache.thrift.async.AsyncMethodCallback resultHandler, org.apache.thrift.async.TAsyncClient client, org.apache.thrift.protocol.TProtocolFactory protocolFactory, org.apache.thrift.transport.TNonblockingTransport transport) throws org.apache.thrift.TException {
        super(client, protocolFactory, transport, resultHandler, false);
        this.authzToken = authzToken;
        this.computeResourceId = computeResourceId;
        this.priorityOrder = priorityOrder;
        this.sshJobSubmission = sshJobSubmission;
      }

      public void write_args(org.apache.thrift.protocol.TProtocol prot) throws org.apache.thrift.TException {
        prot.writeMessageBegin(new org.apache.thrift.protocol.TMessage("addSSHForkJobSubmissionDetails", org.apache.thrift.protocol.TMessageType.CALL, 0));
        addSSHForkJobSubmissionDetails_args args = new addSSHForkJobSubmissionDetails_args();
        args.setAuthzToken(authzToken);
        args.setComputeResourceId(computeResourceId);
        args.setPriorityOrder(priorityOrder);
        args.setSshJobSubmission(sshJobSubmission);
        args.write(prot);
        prot.writeMessageEnd();
      }

      public String getResult() throws org.apache.airavata.model.error.InvalidRequestException, org.apache.airavata.model.error.AiravataClientException, org.apache.airavata.model.error.AiravataSystemException, org.apache.airavata.model.error.AuthorizationException, org.apache.thrift.TException {
        if (getState() != org.apache.thrift.async.TAsyncMethodCall.State.RESPONSE_READ) {
          throw new IllegalStateException("Method call not finished!");
        }
        org.apache.thrift.transport.TMemoryInputTransport memoryTransport = new org.apache.thrift.transport.TMemoryInputTransport(getFrameBuffer().array());
        org.apache.thrift.protocol.TProtocol prot = client.getProtocolFactory().getProtocol(memoryTransport);
        return (new Client(prot)).recv_addSSHForkJobSubmissionDetails();
      }
    }

    public void getSSHJobSubmission(org.apache.airavata.model.security.AuthzToken authzToken, String jobSubmissionId, org.apache.thrift.async.AsyncMethodCallback resultHandler) throws org.apache.thrift.TException {
      checkReady();
      getSSHJobSubmission_call method_call = new getSSHJobSubmission_call(authzToken, jobSubmissionId, resultHandler, this, ___protocolFactory, ___transport);
      this.___currentMethod = method_call;
      ___manager.call(method_call);
    }

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

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

      public org.apache.airavata.model.appcatalog.computeresource.SSHJobSubmission getResult() throws org.apache.airavata.model.error.InvalidRequestException, org.apache.airavata.model.error.AiravataClientException, org.apache.airavata.model.error.AiravataSystemException, org.apache.airavata.model.error.AuthorizationException, org.apache.thrift.TException {
        if (getState() != org.apache.thrift.async.TAsyncMethodCall.State.RESPONSE_READ) {
          throw new IllegalStateException("Method call not finished!");
        }
        org.apache.thrift.transport.TMemoryInputTransport memoryTransport = new org.apache.thrift.transport.TMemoryInputTransport(getFrameBuffer().array());
        org.apache.thrift.protocol.TProtocol prot = client.getProtocolFactory().getProtocol(memoryTransport);
        return (new Client(prot)).recv_getSSHJobSubmission();
      }
    }

    public void addUNICOREJobSubmissionDetails(org.apache.airavata.model.security.AuthzToken authzToken, String computeResourceId, int priorityOrder, org.apache.airavata.model.appcatalog.computeresource.UnicoreJobSubmission unicoreJobSubmission, org.apache.thrift.async.AsyncMethodCallback resultHandler) throws org.apache.thrift.TException {
      checkReady();
      addUNICOREJobSubmissionDetails_call method_call = new addUNICOREJobSubmissionDetails_call(authzToken, computeResourceId, priorityOrder, unicoreJobSubmission, resultHandler, this, ___protocolFactory, ___transport);
      this.___currentMethod = method_call;
      ___manager.call(method_call);
    }

    public static class addUNICOREJobSubmissionDetails_call extends org.apache.thrift.async.TAsyncMethodCall {
      private org.apache.airavata.model.security.AuthzToken authzToken;
      private String computeResourceId;
      private int priorityOrder;
      private org.apache.airavata.model.appcatalog.computeresource.UnicoreJobSubmission unicoreJobSubmission;
      public addUNICOREJobSubmissionDetails_call(org.apache.airavata.model.security.AuthzToken authzToken, String computeResourceId, int priorityOrder, org.apache.airavata.model.appcatalog.computeresource.UnicoreJobSubmission unicoreJobSubmission, org.apache.thrift.async.AsyncMethodCallback resultHandler, org.apache.thrift.async.TAsyncClient client, org.apache.thrift.protocol.TProtocolFactory protocolFactory, org.apache.thrift.transport.TNonblockingTransport transport) throws org.apache.thrift.TException {
        super(client, protocolFactory, transport, resultHandler, false);
        this.authzToken = authzToken;
        this.computeResourceId = computeResourceId;
        this.priorityOrder = priorityOrder;
        this.unicoreJobSubmission = unicoreJobSubmission;
      }

      public void write_args(org.apache.thrift.protocol.TProtocol prot) throws org.apache.thrift.TException {
        prot.writeMessageBegin(new org.apache.thrift.protocol.TMessage("addUNICOREJobSubmissionDetails", org.apache.thrift.protocol.TMessageType.CALL, 0));
        addUNICOREJobSubmissionDetails_args args = new addUNICOREJobSubmissionDetails_args();
        args.setAuthzToken(authzToken);
        args.setComputeResourceId(computeResourceId);
        args.setPriorityOrder(priorityOrder);
        args.setUnicoreJobSubmission(unicoreJobSubmission);
        args.write(prot);
        prot.writeMessageEnd();
      }

      public String getResult() throws org.apache.airavata.model.error.InvalidRequestException, org.apache.airavata.model.error.AiravataClientException, org.apache.airavata.model.error.AiravataSystemException, org.apache.airavata.model.error.AuthorizationException, org.apache.thrift.TException {
        if (getState() != org.apache.thrift.async.TAsyncMethodCall.State.RESPONSE_READ) {
          throw new IllegalStateException("Method call not finished!");
        }
        org.apache.thrift.transport.TMemoryInputTransport memoryTransport = new org.apache.thrift.transport.TMemoryInputTransport(getFrameBuffer().array());
        org.apache.thrift.protocol.TProtocol prot = client.getProtocolFactory().getProtocol(memoryTransport);
        return (new Client(prot)).recv_addUNICOREJobSubmissionDetails();
      }
    }

    public void getUnicoreJobSubmission(org.apache.airavata.model.security.AuthzToken authzToken, String jobSubmissionId, org.apache.thrift.async.AsyncMethodCallback resultHandler) throws org.apache.thrift.TException {
      checkReady();
      getUnicoreJobSubmission_call method_call = new getUnicoreJobSubmission_call(authzToken, jobSubmissionId, resultHandler, this, ___protocolFactory, ___transport);
      this.___currentMethod = method_call;
      ___manager.call(method_call);
    }

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

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

      public org.apache.airavata.model.appcatalog.computeresource.UnicoreJobSubmission getResult() throws org.apache.airavata.model.error.InvalidRequestException, org.apache.airavata.model.error.AiravataClientException, org.apache.airavata.model.error.AiravataSystemException, org.apache.airavata.model.error.AuthorizationException, org.apache.thrift.TException {
        if (getState() != org.apache.thrift.async.TAsyncMethodCall.State.RESPONSE_READ) {
          throw new IllegalStateException("Method call not finished!");
        }
        org.apache.thrift.transport.TMemoryInputTransport memoryTransport = new org.apache.thrift.transport.TMemoryInputTransport(getFrameBuffer().array());
        org.apache.thrift.protocol.TProtocol prot = client.getProtocolFactory().getProtocol(memoryTransport);
        return (new Client(prot)).recv_getUnicoreJobSubmission();
      }
    }

    public void addCloudJobSubmissionDetails(org.apache.airavata.model.security.AuthzToken authzToken, String computeResourceId, int priorityOrder, org.apache.airavata.model.appcatalog.computeresource.CloudJobSubmission cloudSubmission, org.apache.thrift.async.AsyncMethodCallback resultHandler) throws org.apache.thrift.TException {
      checkReady();
      addCloudJobSubmissionDetails_call method_call = new addCloudJobSubmissionDetails_call(authzToken, computeResourceId, priorityOrder, cloudSubmission, resultHandler, this, ___protocolFactory, ___transport);
      this.___currentMethod = method_call;
      ___manager.call(method_call);
    }

    public static class addCloudJobSubmissionDetails_call extends org.apache.thrift.async.TAsyncMethodCall {
      private org.apache.airavata.model.security.AuthzToken authzToken;
      private String computeResourceId;
      private int priorityOrder;
      private org.apache.airavata.model.appcatalog.computeresource.CloudJobSubmission cloudSubmission;
      public addCloudJobSubmissionDetails_call(org.apache.airavata.model.security.AuthzToken authzToken, String computeResourceId, int priorityOrder, org.apache.airavata.model.appcatalog.computeresource.CloudJobSubmission cloudSubmission, org.apache.thrift.async.AsyncMethodCallback resultHandler, org.apache.thrift.async.TAsyncClient client, org.apache.thrift.protocol.TProtocolFactory protocolFactory, org.apache.thrift.transport.TNonblockingTransport transport) throws org.apache.thrift.TException {
        super(client, protocolFactory, transport, resultHandler, false);
        this.authzToken = authzToken;
        this.computeResourceId = computeResourceId;
        this.priorityOrder = priorityOrder;
        this.cloudSubmission = cloudSubmission;
      }

      public void write_args(org.apache.thrift.protocol.TProtocol prot) throws org.apache.thrift.TException {
        prot.writeMessageBegin(new org.apache.thrift.protocol.TMessage("addCloudJobSubmissionDetails", org.apache.thrift.protocol.TMessageType.CALL, 0));
        addCloudJobSubmissionDetails_args args = new addCloudJobSubmissionDetails_args();
        args.setAuthzToken(authzToken);
        args.setComputeResourceId(computeResourceId);
        args.setPriorityOrder(priorityOrder);
        args.setCloudSubmission(cloudSubmission);
        args.write(prot);
        prot.writeMessageEnd();
      }

      public String getResult() throws org.apache.airavata.model.error.InvalidRequestException, org.apache.airavata.model.error.AiravataClientException, org.apache.airavata.model.error.AiravataSystemException, org.apache.airavata.model.error.AuthorizationException, org.apache.thrift.TException {
        if (getState() != org.apache.thrift.async.TAsyncMethodCall.State.RESPONSE_READ) {
          throw new IllegalStateException("Method call not finished!");
        }
        org.apache.thrift.transport.TMemoryInputTransport memoryTransport = new org.apache.thrift.transport.TMemoryInputTransport(getFrameBuffer().array());
        org.apache.thrift.protocol.TProtocol prot = client.getProtocolFactory().getProtocol(memoryTransport);
        return (new Client(prot)).recv_addCloudJobSubmissionDetails();
      }
    }

    public void getCloudJobSubmission(org.apache.airavata.model.security.AuthzToken authzToken, String jobSubmissionId, org.apache.thrift.async.AsyncMethodCallback resultHandler) throws org.apache.thrift.TException {
      checkReady();
      getCloudJobSubmission_call method_call = new getCloudJobSubmission_call(authzToken, jobSubmissionId, resultHandler, this, ___protocolFactory, ___transport);
      this.___currentMethod = method_call;
      ___manager.call(method_call);
    }

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

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

      public org.apache.airavata.model.appcatalog.computeresource.CloudJobSubmission getResult() throws org.apache.airavata.model.error.InvalidRequestException, org.apache.airavata.model.error.AiravataClientException, org.apache.airavata.model.error.AiravataSystemException, org.apache.airavata.model.error.AuthorizationException, org.apache.thrift.TException {
        if (getState() != org.apache.thrift.async.TAsyncMethodCall.State.RESPONSE_READ) {
          throw new IllegalStateException("Method call not finished!");
        }
        org.apache.thrift.transport.TMemoryInputTransport memoryTransport = new org.apache.thrift.transport.TMemoryInputTransport(getFrameBuffer().array());
        org.apache.thrift.protocol.TProtocol prot = client.getProtocolFactory().getProtocol(memoryTransport);
        return (new Client(prot)).recv_getCloudJobSubmission();
      }
    }

    public void updateSSHJobSubmissionDetails(org.apache.airavata.model.security.AuthzToken authzToken, String jobSubmissionInterfaceId, org.apache.airavata.model.appcatalog.computeresource.SSHJobSubmission sshJobSubmission, org.apache.thrift.async.AsyncMethodCallback resultHandler) throws org.apache.thrift.TException {
      checkReady();
      updateSSHJobSubmissionDetails_call method_call = new updateSSHJobSubmissionDetails_call(authzToken, jobSubmissionInterfaceId, sshJobSubmission, resultHandler, this, ___protocolFactory, ___transport);
      this.___currentMethod = method_call;
      ___manager.call(method_call);
    }

    public static class updateSSHJobSubmissionDetails_call extends org.apache.thrift.async.TAsyncMethodCall {
      private org.apache.airavata.model.security.AuthzToken authzToken;
      private String jobSubmissionInterfaceId;
      private org.apache.airavata.model.appcatalog.computeresource.SSHJobSubmission sshJobSubmission;
      public updateSSHJobSubmissionDetails_call(org.apache.airavata.model.security.AuthzToken authzToken, String jobSubmissionInterfaceId, org.apache.airavata.model.appcatalog.computeresource.SSHJobSubmission sshJobSubmission, org.apache.thrift.async.AsyncMethodCallback resultHandler, org.apache.thrift.async.TAsyncClient client, org.apache.thrift.protocol.TProtocolFactory protocolFactory, org.apache.thrift.transport.TNonblockingTransport transport) throws org.apache.thrift.TException {
        super(client, protocolFactory, transport, resultHandler, false);
        this.authzToken = authzToken;
        this.jobSubmissionInterfaceId = jobSubmissionInterfaceId;
        this.sshJobSubmission = sshJobSubmission;
      }

      public void write_args(org.apache.thrift.protocol.TProtocol prot) throws org.apache.thrift.TException {
        prot.writeMessageBegin(new org.apache.thrift.protocol.TMessage("updateSSHJobSubmissionDetails", org.apache.thrift.protocol.TMessageType.CALL, 0));
        updateSSHJobSubmissionDetails_args args = new updateSSHJobSubmissionDetails_args();
        args.setAuthzToken(authzToken);
        args.setJobSubmissionInterfaceId(jobSubmissionInterfaceId);
        args.setSshJobSubmission(sshJobSubmission);
        args.write(prot);
        prot.writeMessageEnd();
      }

      public boolean getResult() throws org.apache.airavata.model.error.InvalidRequestException, org.apache.airavata.model.error.AiravataClientException, org.apache.airavata.model.error.AiravataSystemException, org.apache.airavata.model.error.AuthorizationException, org.apache.thrift.TException {
        if (getState() != org.apache.thrift.async.TAsyncMethodCall.State.RESPONSE_READ) {
          throw new IllegalStateException("Method call not finished!");
        }
        org.apache.thrift.transport.TMemoryInputTransport memoryTransport = new org.apache.thrift.transport.TMemoryInputTransport(getFrameBuffer().array());
        org.apache.thrift.protocol.TProtocol prot = client.getProtocolFactory().getProtocol(memoryTransport);
        return (new Client(prot)).recv_updateSSHJobSubmissionDetails();
      }
    }

    public void updateCloudJobSubmissionDetails(org.apache.airavata.model.security.AuthzToken authzToken, String jobSubmissionInterfaceId, org.apache.airavata.model.appcatalog.computeresource.CloudJobSubmission sshJobSubmission, org.apache.thrift.async.AsyncMethodCallback resultHandler) throws org.apache.thrift.TException {
      checkReady();
      updateCloudJobSubmissionDetails_call method_call = new updateCloudJobSubmissionDetails_call(authzToken, jobSubmissionInterfaceId, sshJobSubmission, resultHandler, this, ___protocolFactory, ___transport);
      this.___currentMethod = method_call;
      ___manager.call(method_call);
    }

    public static class updateCloudJobSubmissionDetails_call extends org.apache.thrift.async.TAsyncMethodCall {
      private org.apache.airavata.model.security.AuthzToken authzToken;
      private String jobSubmissionInterfaceId;
      private org.apache.airavata.model.appcatalog.computeresource.CloudJobSubmission sshJobSubmission;
      public updateCloudJobSubmissionDetails_call(org.apache.airavata.model.security.AuthzToken authzToken, String jobSubmissionInterfaceId, org.apache.airavata.model.appcatalog.computeresource.CloudJobSubmission sshJobSubmission, org.apache.thrift.async.AsyncMethodCallback resultHandler, org.apache.thrift.async.TAsyncClient client, org.apache.thrift.protocol.TProtocolFactory protocolFactory, org.apache.thrift.transport.TNonblockingTransport transport) throws org.apache.thrift.TException {
        super(client, protocolFactory, transport, resultHandler, false);
        this.authzToken = authzToken;
        this.jobSubmissionInterfaceId = jobSubmissionInterfaceId;
        this.sshJobSubmission = sshJobSubmission;
      }

      public void write_args(org.apache.thrift.protocol.TProtocol prot) throws org.apache.thrift.TException {
        prot.writeMessageBegin(new org.apache.thrift.protocol.TMessage("updateCloudJobSubmissionDetails", org.apache.thrift.protocol.TMessageType.CALL, 0));
        updateCloudJobSubmissionDetails_args args = new updateCloudJobSubmissionDetails_args();
        args.setAuthzToken(authzToken);
        args.setJobSubmissionInterfaceId(jobSubmissionInterfaceId);
        args.setSshJobSubmission(sshJobSubmission);
        args.write(prot);
        prot.writeMessageEnd();
      }

      public boolean getResult() throws org.apache.airavata.model.error.InvalidRequestException, org.apache.airavata.model.error.AiravataClientException, org.apache.airavata.model.error.AiravataSystemException, org.apache.airavata.model.error.AuthorizationException, org.apache.thrift.TException {
        if (getState() != org.apache.thrift.async.TAsyncMethodCall.State.RESPONSE_READ) {
          throw new IllegalStateException("Method call not finished!");
        }
        org.apache.thrift.transport.TMemoryInputTransport memoryTransport = new org.apache.thrift.transport.TMemoryInputTransport(getFrameBuffer().array());
        org.apache.thrift.protocol.TProtocol prot = client.getProtocolFactory().getProtocol(memoryTransport);
        return (new Client(prot)).recv_updateCloudJobSubmissionDetails();
      }
    }

    public void updateUnicoreJobSubmissionDetails(org.apache.airavata.model.security.AuthzToken authzToken, String jobSubmissionInterfaceId, org.apache.airavata.model.appcatalog.computeresource.UnicoreJobSubmission unicoreJobSubmission, org.apache.thrift.async.AsyncMethodCallback resultHandler) throws org.apache.thrift.TException {
      checkReady();
      updateUnicoreJobSubmissionDetails_call method_call = new updateUnicoreJobSubmissionDetails_call(authzToken, jobSubmissionInterfaceId, unicoreJobSubmission, resultHandler, this, ___protocolFactory, ___transport);
      this.___currentMethod = method_call;
      ___manager.call(method_call);
    }

    public static class updateUnicoreJobSubmissionDetails_call extends org.apache.thrift.async.TAsyncMethodCall {
      private org.apache.airavata.model.security.AuthzToken authzToken;
      private String jobSubmissionInterfaceId;
      private org.apache.airavata.model.appcatalog.computeresource.UnicoreJobSubmission unicoreJobSubmission;
      public updateUnicoreJobSubmissionDetails_call(org.apache.airavata.model.security.AuthzToken authzToken, String jobSubmissionInterfaceId, org.apache.airavata.model.appcatalog.computeresource.UnicoreJobSubmission unicoreJobSubmission, org.apache.thrift.async.AsyncMethodCallback resultHandler, org.apache.thrift.async.TAsyncClient client, org.apache.thrift.protocol.TProtocolFactory protocolFactory, org.apache.thrift.transport.TNonblockingTransport transport) throws org.apache.thrift.TException {
        super(client, protocolFactory, transport, resultHandler, false);
        this.authzToken = authzToken;
        this.jobSubmissionInterfaceId = jobSubmissionInterfaceId;
        this.unicoreJobSubmission = unicoreJobSubmission;
      }

      public void write_args(org.apache.thrift.protocol.TProtocol prot) throws org.apache.thrift.TException {
        prot.writeMessageBegin(new org.apache.thrift.protocol.TMessage("updateUnicoreJobSubmissionDetails", org.apache.thrift.protocol.TMessageType.CALL, 0));
        updateUnicoreJobSubmissionDetails_args args = new updateUnicoreJobSubmissionDetails_args();
        args.setAuthzToken(authzToken);
        args.setJobSubmissionInterfaceId(jobSubmissionInterfaceId);
        args.setUnicoreJobSubmission(unicoreJobSubmission);
        args.write(prot);
        prot.writeMessageEnd();
      }

      public boolean getResult() throws org.apache.airavata.model.error.InvalidRequestException, org.apache.airavata.model.error.AiravataClientException, org.apache.airavata.model.error.AiravataSystemException, org.apache.airavata.model.error.AuthorizationException, org.apache.thrift.TException {
        if (getState() != org.apache.thrift.async.TAsyncMethodCall.State.RESPONSE_READ) {
          throw new IllegalStateException("Method call not finished!");
        }
        org.apache.thrift.transport.TMemoryInputTransport memoryTransport = new org.apache.thrift.transport.TMemoryInputTransport(getFrameBuffer().array());
        org.apache.thrift.protocol.TProtocol prot = client.getProtocolFactory().getProtocol(memoryTransport);
        return (new Client(prot)).recv_updateUnicoreJobSubmissionDetails();
      }
    }

    public void addLocalDataMovementDetails(org.apache.airavata.model.security.AuthzToken authzToken, String computeResourceId, int priorityOrder, org.apache.airavata.model.appcatalog.computeresource.LOCALDataMovement localDataMovement, org.apache.thrift.async.AsyncMethodCallback resultHandler) throws org.apache.thrift.TException {
      checkReady();
      addLocalDataMovementDetails_call method_call = new addLocalDataMovementDetails_call(authzToken, computeResourceId, priorityOrder, localDataMovement, resultHandler, this, ___protocolFactory, ___transport);
      this.___currentMethod = method_call;
      ___manager.call(method_call);
    }

    public static class addLocalDataMovementDetails_call extends org.apache.thrift.async.TAsyncMethodCall {
      private org.apache.airavata.model.security.AuthzToken authzToken;
      private String computeResourceId;
      private int priorityOrder;
      private org.apache.airavata.model.appcatalog.computeresource.LOCALDataMovement localDataMovement;
      public addLocalDataMovementDetails_call(org.apache.airavata.model.security.AuthzToken authzToken, String computeResourceId, int priorityOrder, org.apache.airavata.model.appcatalog.computeresource.LOCALDataMovement localDataMovement, org.apache.thrift.async.AsyncMethodCallback resultHandler, org.apache.thrift.async.TAsyncClient client, org.apache.thrift.protocol.TProtocolFactory protocolFactory, org.apache.thrift.transport.TNonblockingTransport transport) throws org.apache.thrift.TException {
        super(client, protocolFactory, transport, resultHandler, false);
        this.authzToken = authzToken;
        this.computeResourceId = computeResourceId;
        this.priorityOrder = priorityOrder;
        this.localDataMovement = localDataMovement;
      }

      public void write_args(org.apache.thrift.protocol.TProtocol prot) throws org.apache.thrift.TException {
        prot.writeMessageBegin(new org.apache.thrift.protocol.TMessage("addLocalDataMovementDetails", org.apache.thrift.protocol.TMessageType.CALL, 0));
        addLocalDataMovementDetails_args args = new addLocalDataMovementDetails_args();
        args.setAuthzToken(authzToken);
        args.setComputeResourceId(computeResourceId);
        args.setPriorityOrder(priorityOrder);
        args.setLocalDataMovement(localDataMovement);
        args.write(prot);
        prot.writeMessageEnd();
      }

      public String getResult() throws org.apache.airavata.model.error.InvalidRequestException, org.apache.airavata.model.error.AiravataClientException, org.apache.airavata.model.error.AiravataSystemException, org.apache.airavata.model.error.AuthorizationException, org.apache.thrift.TException {
        if (getState() != org.apache.thrift.async.TAsyncMethodCall.State.RESPONSE_READ) {
          throw new IllegalStateException("Method call not finished!");
        }
        org.apache.thrift.transport.TMemoryInputTransport memoryTransport = new org.apache.thrift.transport.TMemoryInputTransport(getFrameBuffer().array());
        org.apache.thrift.protocol.TProtocol prot = client.getProtocolFactory().getProtocol(memoryTransport);
        return (new Client(prot)).recv_addLocalDataMovementDetails();
      }
    }

    public void updateLocalDataMovementDetails(org.apache.airavata.model.security.AuthzToken authzToken, String dataMovementInterfaceId, org.apache.airavata.model.appcatalog.computeresource.LOCALDataMovement localDataMovement, org.apache.thrift.async.AsyncMethodCallback resultHandler) throws org.apache.thrift.TException {
      checkReady();
      updateLocalDataMovementDetails_call method_call = new updateLocalDataMovementDetails_call(authzToken, dataMovementInterfaceId, localDataMovement, resultHandler, this, ___protocolFactory, ___transport);
      this.___currentMethod = method_call;
      ___manager.call(method_call);
    }

    public static class updateLocalDataMovementDetails_call extends org.apache.thrift.async.TAsyncMethodCall {
      private org.apache.airavata.model.security.AuthzToken authzToken;
      private String dataMovementInterfaceId;
      private org.apache.airavata.model.appcatalog.computeresource.LOCALDataMovement localDataMovement;
      public updateLocalDataMovementDetails_call(org.apache.airavata.model.security.AuthzToken authzToken, String dataMovementInterfaceId, org.apache.airavata.model.appcatalog.computeresource.LOCALDataMovement localDataMovement, org.apache.thrift.async.AsyncMethodCallback resultHandler, org.apache.thrift.async.TAsyncClient client, org.apache.thrift.protocol.TProtocolFactory protocolFactory, org.apache.thrift.transport.TNonblockingTransport transport) throws org.apache.thrift.TException {
        super(client, protocolFactory, transport, resultHandler, false);
        this.authzToken = authzToken;
        this.dataMovementInterfaceId = dataMovementInterfaceId;
        this.localDataMovement = localDataMovement;
      }

      public void write_args(org.apache.thrift.protocol.TProtocol prot) throws org.apache.thrift.TException {
        prot.writeMessageBegin(new org.apache.thrift.protocol.TMessage("updateLocalDataMovementDetails", org.apache.thrift.protocol.TMessageType.CALL, 0));
        updateLocalDataMovementDetails_args args = new updateLocalDataMovementDetails_args();
        args.setAuthzToken(authzToken);
        args.setDataMovementInterfaceId(dataMovementInterfaceId);
        args.setLocalDataMovement(localDataMovement);
        args.write(prot);
        prot.writeMessageEnd();
      }

      public boolean getResult() throws org.apache.airavata.model.error.InvalidRequestException, org.apache.airavata.model.error.AiravataClientException, org.apache.airavata.model.error.AiravataSystemException, org.apache.airavata.model.error.AuthorizationException, org.apache.thrift.TException {
        if (getState() != org.apache.thrift.async.TAsyncMethodCall.State.RESPONSE_READ) {
          throw new IllegalStateException("Method call not finished!");
        }
        org.apache.thrift.transport.TMemoryInputTransport memoryTransport = new org.apache.thrift.transport.TMemoryInputTransport(getFrameBuffer().array());
        org.apache.thrift.protocol.TProtocol prot = client.getProtocolFactory().getProtocol(memoryTransport);
        return (new Client(prot)).recv_updateLocalDataMovementDetails();
      }
    }

    public void getLocalDataMovement(org.apache.airavata.model.security.AuthzToken authzToken, String dataMovementId, org.apache.thrift.async.AsyncMethodCallback resultHandler) throws org.apache.thrift.TException {
      checkReady();
      getLocalDataMovement_call method_call = new getLocalDataMovement_call(authzToken, dataMovementId, resultHandler, this, ___protocolFactory, ___transport);
      this.___currentMethod = method_call;
      ___manager.call(method_call);
    }

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

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

      public org.apache.airavata.model.appcatalog.computeresource.LOCALDataMovement getResult() throws org.apache.airavata.model.error.InvalidRequestException, org.apache.airavata.model.error.AiravataClientException, org.apache.airavata.model.error.AiravataSystemException, org.apache.airavata.model.error.AuthorizationException, org.apache.thrift.TException {
        if (getState() != org.apache.thrift.async.TAsyncMethodCall.State.RESPONSE_READ) {
          throw new IllegalStateException("Method call not finished!");
        }
        org.apache.thrift.transport.TMemoryInputTransport memoryTransport = new org.apache.thrift.transport.TMemoryInputTransport(getFrameBuffer().array());
        org.apache.thrift.protocol.TProtocol prot = client.getProtocolFactory().getProtocol(memoryTransport);
        return (new Client(prot)).recv_getLocalDataMovement();
      }
    }

    public void addSCPDataMovementDetails(org.apache.airavata.model.security.AuthzToken authzToken, String computeResourceId, int priorityOrder, org.apache.airavata.model.appcatalog.computeresource.SCPDataMovement scpDataMovement, org.apache.thrift.async.AsyncMethodCallback resultHandler) throws org.apache.thrift.TException {
      checkReady();
      addSCPDataMovementDetails_call method_call = new addSCPDataMovementDetails_call(authzToken, computeResourceId, priorityOrder, scpDataMovement, resultHandler, this, ___protocolFactory, ___transport);
      this.___currentMethod = method_call;
      ___manager.call(method_call);
    }

    public static class addSCPDataMovementDetails_call extends org.apache.thrift.async.TAsyncMethodCall {
      private org.apache.airavata.model.security.AuthzToken authzToken;
      private String computeResourceId;
      private int priorityOrder;
      private org.apache.airavata.model.appcatalog.computeresource.SCPDataMovement scpDataMovement;
      public addSCPDataMovementDetails_call(org.apache.airavata.model.security.AuthzToken authzToken, String computeResourceId, int priorityOrder, org.apache.airavata.model.appcatalog.computeresource.SCPDataMovement scpDataMovement, org.apache.thrift.async.AsyncMethodCallback resultHandler, org.apache.thrift.async.TAsyncClient client, org.apache.thrift.protocol.TProtocolFactory protocolFactory, org.apache.thrift.transport.TNonblockingTransport transport) throws org.apache.thrift.TException {
        super(client, protocolFactory, transport, resultHandler, false);
        this.authzToken = authzToken;
        this.computeResourceId = computeResourceId;
        this.priorityOrder = priorityOrder;
        this.scpDataMovement = scpDataMovement;
      }

      public void write_args(org.apache.thrift.protocol.TProtocol prot) throws org.apache.thrift.TException {
        prot.writeMessageBegin(new org.apache.thrift.protocol.TMessage("addSCPDataMovementDetails", org.apache.thrift.protocol.TMessageType.CALL, 0));
        addSCPDataMovementDetails_args args = new addSCPDataMovementDetails_args();
        args.setAuthzToken(authzToken);
        args.setComputeResourceId(computeResourceId);
        args.setPriorityOrder(priorityOrder);
        args.setScpDataMovement(scpDataMovement);
        args.write(prot);
        prot.writeMessageEnd();
      }

      public String getResult() throws org.apache.airavata.model.error.InvalidRequestException, org.apache.airavata.model.error.AiravataClientException, org.apache.airavata.model.error.AiravataSystemException, org.apache.airavata.model.error.AuthorizationException, org.apache.thrift.TException {
        if (getState() != org.apache.thrift.async.TAsyncMethodCall.State.RESPONSE_READ) {
          throw new IllegalStateException("Method call not finished!");
        }
        org.apache.thrift.transport.TMemoryInputTransport memoryTransport = new org.apache.thrift.transport.TMemoryInputTransport(getFrameBuffer().array());
        org.apache.thrift.protocol.TProtocol prot = client.getProtocolFactory().getProtocol(memoryTransport);
        return (new Client(prot)).recv_addSCPDataMovementDetails();
      }
    }

    public void updateSCPDataMovementDetails(org.apache.airavata.model.security.AuthzToken authzToken, String dataMovementInterfaceId, org.apache.airavata.model.appcatalog.computeresource.SCPDataMovement scpDataMovement, org.apache.thrift.async.AsyncMethodCallback resultHandler) throws org.apache.thrift.TException {
      checkReady();
      updateSCPDataMovementDetails_call method_call = new updateSCPDataMovementDetails_call(authzToken, dataMovementInterfaceId, scpDataMovement, resultHandler, this, ___protocolFactory, ___transport);
      this.___currentMethod = method_call;
      ___manager.call(method_call);
    }

    public static class updateSCPDataMovementDetails_call extends org.apache.thrift.async.TAsyncMethodCall {
      private org.apache.airavata.model.security.AuthzToken authzToken;
      private String dataMovementInterfaceId;
      private org.apache.airavata.model.appcatalog.computeresource.SCPDataMovement scpDataMovement;
      public updateSCPDataMovementDetails_call(org.apache.airavata.model.security.AuthzToken authzToken, String dataMovementInterfaceId, org.apache.airavata.model.appcatalog.computeresource.SCPDataMovement scpDataMovement, org.apache.thrift.async.AsyncMethodCallback resultHandler, org.apache.thrift.async.TAsyncClient client, org.apache.thrift.protocol.TProtocolFactory protocolFactory, org.apache.thrift.transport.TNonblockingTransport transport) throws org.apache.thrift.TException {
        super(client, protocolFactory, transport, resultHandler, false);
        this.authzToken = authzToken;
        this.dataMovementInterfaceId = dataMovementInterfaceId;
        this.scpDataMovement = scpDataMovement;
      }

      public void write_args(org.apache.thrift.protocol.TProtocol prot) throws org.apache.thrift.TException {
        prot.writeMessageBegin(new org.apache.thrift.protocol.TMessage("updateSCPDataMovementDetails", org.apache.thrift.protocol.TMessageType.CALL, 0));
        updateSCPDataMovementDetails_args args = new updateSCPDataMovementDetails_args();
        args.setAuthzToken(authzToken);
        args.setDataMovementInterfaceId(dataMovementInterfaceId);
        args.setScpDataMovement(scpDataMovement);
        args.write(prot);
        prot.writeMessageEnd();
      }

      public boolean getResult() throws org.apache.airavata.model.error.InvalidRequestException, org.apache.airavata.model.error.AiravataClientException, org.apache.airavata.model.error.AiravataSystemException, org.apache.airavata.model.error.AuthorizationException, org.apache.thrift.TException {
        if (getState() != org.apache.thrift.async.TAsyncMethodCall.State.RESPONSE_READ) {
          throw new IllegalStateException("Method call not finished!");
        }
        org.apache.thrift.transport.TMemoryInputTransport memoryTransport = new org.apache.thrift.transport.TMemoryInputTransport(getFrameBuffer().array());
        org.apache.thrift.protocol.TProtocol prot = client.getProtocolFactory().getProtocol(memoryTransport);
        return (new Client(prot)).recv_updateSCPDataMovementDetails();
      }
    }

    public void getSCPDataMovement(org.apache.airavata.model.security.AuthzToken authzToken, String dataMovementId, org.apache.thrift.async.AsyncMethodCallback resultHandler) throws org.apache.thrift.TException {
      checkReady();
      getSCPDataMovement_call method_call = new getSCPDataMovement_call(authzToken, dataMovementId, resultHandler, this, ___protocolFactory, ___transport);
      this.___currentMethod = method_call;
      ___manager.call(method_call);
    }

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

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

      public org.apache.airavata.model.appcatalog.computeresource.SCPDataMovement getResult() throws org.apache.airavata.model.error.InvalidRequestException, org.apache.airavata.model.error.AiravataClientException, org.apache.airavata.model.error.AiravataSystemException, org.apache.airavata.model.error.AuthorizationException, org.apache.thrift.TException {
        if (getState() != org.apache.thrift.async.TAsyncMethodCall.State.RESPONSE_READ) {
          throw new IllegalStateException("Method call not finished!");
        }
        org.apache.thrift.transport.TMemoryInputTransport memoryTransport = new org.apache.thrift.transport.TMemoryInputTransport(getFrameBuffer().array());
        org.apache.thrift.protocol.TProtocol prot = client.getProtocolFactory().getProtocol(memoryTransport);
        return (new Client(prot)).recv_getSCPDataMovement();
      }
    }

    public void addUnicoreDataMovementDetails(org.apache.airavata.model.security.AuthzToken authzToken, String computeResourceId, int priorityOrder, org.apache.airavata.model.appcatalog.computeresource.UnicoreDataMovement unicoreDataMovement, org.apache.thrift.async.AsyncMethodCallback resultHandler) throws org.apache.thrift.TException {
      checkReady();
      addUnicoreDataMovementDetails_call method_call = new addUnicoreDataMovementDetails_call(authzToken, computeResourceId, priorityOrder, unicoreDataMovement, resultHandler, this, ___protocolFactory, ___transport);
      this.___currentMethod = method_call;
      ___manager.call(method_call);
    }

    public static class addUnicoreDataMovementDetails_call extends org.apache.thrift.async.TAsyncMethodCall {
      private org.apache.airavata.model.security.AuthzToken authzToken;
      private String computeResourceId;
      private int priorityOrder;
      private org.apache.airavata.model.appcatalog.computeresource.UnicoreDataMovement unicoreDataMovement;
      public addUnicoreDataMovementDetails_call(org.apache.airavata.model.security.AuthzToken authzToken, String computeResourceId, int priorityOrder, org.apache.airavata.model.appcatalog.computeresource.UnicoreDataMovement unicoreDataMovement, org.apache.thrift.async.AsyncMethodCallback resultHandler, org.apache.thrift.async.TAsyncClient client, org.apache.thrift.protocol.TProtocolFactory protocolFactory, org.apache.thrift.transport.TNonblockingTransport transport) throws org.apache.thrift.TException {
        super(client, protocolFactory, transport, resultHandler, false);
        this.authzToken = authzToken;
        this.computeResourceId = computeResourceId;
        this.priorityOrder = priorityOrder;
        this.unicoreDataMovement = unicoreDataMovement;
      }

      public void write_args(org.apache.thrift.protocol.TProtocol prot) throws org.apache.thrift.TException {
        prot.writeMessageBegin(new org.apache.thrift.protocol.TMessage("addUnicoreDataMovementDetails", org.apache.thrift.protocol.TMessageType.CALL, 0));
        addUnicoreDataMovementDetails_args args = new addUnicoreDataMovementDetails_args();
        args.setAuthzToken(authzToken);
        args.setComputeResourceId(computeResourceId);
        args.setPriorityOrder(priorityOrder);
        args.setUnicoreDataMovement(unicoreDataMovement);
        args.write(prot);
        prot.writeMessageEnd();
      }

      public String getResult() throws org.apache.airavata.model.error.InvalidRequestException, org.apache.airavata.model.error.AiravataClientException, org.apache.airavata.model.error.AiravataSystemException, org.apache.airavata.model.error.AuthorizationException, org.apache.thrift.TException {
        if (getState() != org.apache.thrift.async.TAsyncMethodCall.State.RESPONSE_READ) {
          throw new IllegalStateException("Method call not finished!");
        }
        org.apache.thrift.transport.TMemoryInputTransport memoryTransport = new org.apache.thrift.transport.TMemoryInputTransport(getFrameBuffer().array());
        org.apache.thrift.protocol.TProtocol prot = client.getProtocolFactory().getProtocol(memoryTransport);
        return (new Client(prot)).recv_addUnicoreDataMovementDetails();
      }
    }

    public void updateUnicoreDataMovementDetails(org.apache.airavata.model.security.AuthzToken authzToken, String dataMovementInterfaceId, org.apache.airavata.model.appcatalog.computeresource.UnicoreDataMovement unicoreDataMovement, org.apache.thrift.async.AsyncMethodCallback resultHandler) throws org.apache.thrift.TException {
      checkReady();
      updateUnicoreDataMovementDetails_call method_call = new updateUnicoreDataMovementDetails_call(authzToken, dataMovementInterfaceId, unicoreDataMovement, resultHandler, this, ___protocolFactory, ___transport);
      this.___currentMethod = method_call;
      ___manager.call(method_call);
    }

    public static class updateUnicoreDataMovementDetails_call extends org.apache.thrift.async.TAsyncMethodCall {
      private org.apache.airavata.model.security.AuthzToken authzToken;
      private String dataMovementInterfaceId;
      private org.apache.airavata.model.appcatalog.computeresource.UnicoreDataMovement unicoreDataMovement;
      public updateUnicoreDataMovementDetails_call(org.apache.airavata.model.security.AuthzToken authzToken, String dataMovementInterfaceId, org.apache.airavata.model.appcatalog.computeresource.UnicoreDataMovement unicoreDataMovement, org.apache.thrift.async.AsyncMethodCallback resultHandler, org.apache.thrift.async.TAsyncClient client, org.apache.thrift.protocol.TProtocolFactory protocolFactory, org.apache.thrift.transport.TNonblockingTransport transport) throws org.apache.thrift.TException {
        super(client, protocolFactory, transport, resultHandler, false);
        this.authzToken = authzToken;
        this.dataMovementInterfaceId = dataMovementInterfaceId;
        this.unicoreDataMovement = unicoreDataMovement;
      }

      public void write_args(org.apache.thrift.protocol.TProtocol prot) throws org.apache.thrift.TException {
        prot.writeMessageBegin(new org.apache.thrift.protocol.TMessage("updateUnicoreDataMovementDetails", org.apache.thrift.protocol.TMessageType.CALL, 0));
        updateUnicoreDataMovementDetails_args args = new updateUnicoreDataMovementDetails_args();
        args.setAuthzToken(authzToken);
        args.setDataMovementInterfaceId(dataMovementInterfaceId);
        args.setUnicoreDataMovement(unicoreDataMovement);
        args.write(prot);
        prot.writeMessageEnd();
      }

      public boolean getResult() throws org.apache.airavata.model.error.InvalidRequestException, org.apache.airavata.model.error.AiravataClientException, org.apache.airavata.model.error.AiravataSystemException, org.apache.airavata.model.error.AuthorizationException, org.apache.thrift.TException {
        if (getState() != org.apache.thrift.async.TAsyncMethodCall.State.RESPONSE_READ) {
          throw new IllegalStateException("Method call not finished!");
        }
        org.apache.thrift.transport.TMemoryInputTransport memoryTransport = new org.apache.thrift.transport.TMemoryInputTransport(getFrameBuffer().array());
        org.apache.thrift.protocol.TProtocol prot = client.getProtocolFactory().getProtocol(memoryTransport);
        return (new Client(prot)).recv_updateUnicoreDataMovementDetails();
      }
    }

    public void getUnicoreDataMovement(org.apache.airavata.model.security.AuthzToken authzToken, String dataMovementId, org.apache.thrift.async.AsyncMethodCallback resultHandler) throws org.apache.thrift.TException {
      checkReady();
      getUnicoreDataMovement_call method_call = new getUnicoreDataMovement_call(authzToken, dataMovementId, resultHandler, this, ___protocolFactory, ___transport);
      this.___currentMethod = method_call;
      ___manager.call(method_call);
    }

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

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

      public org.apache.airavata.model.appcatalog.computeresource.UnicoreDataMovement getResult() throws org.apache.airavata.model.error.InvalidRequestException, org.apache.airavata.model.error.AiravataClientException, org.apache.airavata.model.error.AiravataSystemException, org.apache.airavata.model.error.AuthorizationException, org.apache.thrift.TException {
        if (getState() != org.apache.thrift.async.TAsyncMethodCall.State.RESPONSE_READ) {
          throw new IllegalStateException("Method call not finished!");
        }
        org.apache.thrift.transport.TMemoryInputTransport memoryTransport = new org.apache.thrift.transport.TMemoryInputTransport(getFrameBuffer().array());
        org.apache.thrift.protocol.TProtocol prot = client.getProtocolFactory().getProtocol(memoryTransport);
        return (new Client(prot)).recv_getUnicoreDataMovement();
      }
    }

    public void addGridFTPDataMovementDetails(org.apache.airavata.model.security.AuthzToken authzToken, String computeResourceId, int priorityOrder, org.apache.airavata.model.appcatalog.computeresource.GridFTPDataMovement gridFTPDataMovement, org.apache.thrift.async.AsyncMethodCallback resultHandler) throws org.apache.thrift.TException {
      checkReady();
      addGridFTPDataMovementDetails_call method_call = new addGridFTPDataMovementDetails_call(authzToken, computeResourceId, priorityOrder, gridFTPDataMovement, resultHandler, this, ___protocolFactory, ___transport);
      this.___currentMethod = method_call;
      ___manager.call(method_call);
    }

    public static class addGridFTPDataMovementDetails_call extends org.apache.thrift.async.TAsyncMethodCall {
      private org.apache.airavata.model.security.AuthzToken authzToken;
      private String computeResourceId;
      private int priorityOrder;
      private org.apache.airavata.model.appcatalog.computeresource.GridFTPDataMovement gridFTPDataMovement;
      public addGridFTPDataMovementDetails_call(org.apache.airavata.model.security.AuthzToken authzToken, String computeResourceId, int priorityOrder, org.apache.airavata.model.appcatalog.computeresource.GridFTPDataMovement gridFTPDataMovement, org.apache.thrift.async.AsyncMethodCallback resultHandler, org.apache.thrift.async.TAsyncClient client, org.apache.thrift.protocol.TProtocolFactory protocolFactory, org.apache.thrift.transport.TNonblockingTransport transport) throws org.apache.thrift.TException {
        super(client, protocolFactory, transport, resultHandler, false);
        this.authzToken = authzToken;
        this.computeResourceId = computeResourceId;
        this.priorityOrder = priorityOrder;
        this.gridFTPDataMovement = gridFTPDataMovement;
      }

      public void write_args(org.apache.thrift.protocol.TProtocol prot) throws org.apache.thrift.TException {
        prot.writeMessageBegin(new org.apache.thrift.protocol.TMessage("addGridFTPDataMovementDetails", org.apache.thrift.protocol.TMessageType.CALL, 0));
        addGridFTPDataMovementDetails_args args = new addGridFTPDataMovementDetails_args();
        args.setAuthzToken(authzToken);
        args.setComputeResourceId(computeResourceId);
        args.setPriorityOrder(priorityOrder);
        args.setGridFTPDataMovement(gridFTPDataMovement);
        args.write(prot);
        prot.writeMessageEnd();
      }

      public String getResult() throws org.apache.airavata.model.error.InvalidRequestException, org.apache.airavata.model.error.AiravataClientException, org.apache.airavata.model.error.AiravataSystemException, org.apache.airavata.model.error.AuthorizationException, org.apache.thrift.TException {
        if (getState() != org.apache.thrift.async.TAsyncMethodCall.State.RESPONSE_READ) {
          throw new IllegalStateException("Method call not finished!");
        }
        org.apache.thrift.transport.TMemoryInputTransport memoryTransport = new org.apache.thrift.transport.TMemoryInputTransport(getFrameBuffer().array());
        org.apache.thrift.protocol.TProtocol prot = client.getProtocolFactory().getProtocol(memoryTransport);
        return (new Client(prot)).recv_addGridFTPDataMovementDetails();
      }
    }

    public void updateGridFTPDataMovementDetails(org.apache.airavata.model.security.AuthzToken authzToken, String dataMovementInterfaceId, org.apache.airavata.model.appcatalog.computeresource.GridFTPDataMovement gridFTPDataMovement, org.apache.thrift.async.AsyncMethodCallback resultHandler) throws org.apache.thrift.TException {
      checkReady();
      updateGridFTPDataMovementDetails_call method_call = new updateGridFTPDataMovementDetails_call(authzToken, dataMovementInterfaceId, gridFTPDataMovement, resultHandler, this, ___protocolFactory, ___transport);
      this.___currentMethod = method_call;
      ___manager.call(method_call);
    }

    public static class updateGridFTPDataMovementDetails_call extends org.apache.thrift.async.TAsyncMethodCall {
      private org.apache.airavata.model.security.AuthzToken authzToken;
      private String dataMovementInterfaceId;
      private org.apache.airavata.model.appcatalog.computeresource.GridFTPDataMovement gridFTPDataMovement;
      public updateGridFTPDataMovementDetails_call(org.apache.airavata.model.security.AuthzToken authzToken, String dataMovementInterfaceId, org.apache.airavata.model.appcatalog.computeresource.GridFTPDataMovement gridFTPDataMovement, org.apache.thrift.async.AsyncMethodCallback resultHandler, org.apache.thrift.async.TAsyncClient client, org.apache.thrift.protocol.TProtocolFactory protocolFactory, org.apache.thrift.transport.TNonblockingTransport transport) throws org.apache.thrift.TException {
        super(client, protocolFactory, transport, resultHandler, false);
        this.authzToken = authzToken;
        this.dataMovementInterfaceId = dataMovementInterfaceId;
        this.gridFTPDataMovement = gridFTPDataMovement;
      }

      public void write_args(org.apache.thrift.protocol.TProtocol prot) throws org.apache.thrift.TException {
        prot.writeMessageBegin(new org.apache.thrift.protocol.TMessage("updateGridFTPDataMovementDetails", org.apache.thrift.protocol.TMessageType.CALL, 0));
        updateGridFTPDataMovementDetails_args args = new updateGridFTPDataMovementDetails_args();
        args.setAuthzToken(authzToken);
        args.setDataMovementInterfaceId(dataMovementInterfaceId);
        args.setGridFTPDataMovement(gridFTPDataMovement);
        args.write(prot);
        prot.writeMessageEnd();
      }

      public boolean getResult() throws org.apache.airavata.model.error.InvalidRequestException, org.apache.airavata.model.error.AiravataClientException, org.apache.airavata.model.error.AiravataSystemException, org.apache.airavata.model.error.AuthorizationException, org.apache.thrift.TException {
        if (getState() != org.apache.thrift.async.TAsyncMethodCall.State.RESPONSE_READ) {
          throw new IllegalStateException("Method call not finished!");
        }
        org.apache.thrift.transport.TMemoryInputTransport memoryTransport = new org.apache.thrift.transport.TMemoryInputTransport(getFrameBuffer().array());
        org.apache.thrift.protocol.TProtocol prot = client.getProtocolFactory().getProtocol(memoryTransport);
        return (new Client(prot)).recv_updateGridFTPDataMovementDetails();
      }
    }

    public void getGridFTPDataMovement(org.apache.airavata.model.security.AuthzToken authzToken, String dataMovementId, org.apache.thrift.async.AsyncMethodCallback resultHandler) throws org.apache.thrift.TException {
      checkReady();
      getGridFTPDataMovement_call method_call = new getGridFTPDataMovement_call(authzToken, dataMovementId, resultHandler, this, ___protocolFactory, ___transport);
      this.___currentMethod = method_call;
      ___manager.call(method_call);
    }

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

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

      public org.apache.airavata.model.appcatalog.computeresource.GridFTPDataMovement getResult() throws org.apache.airavata.model.error.InvalidRequestException, org.apache.airavata.model.error.AiravataClientException, org.apache.airavata.model.error.AiravataSystemException, org.apache.airavata.model.error.AuthorizationException, org.apache.thrift.TException {
        if (getState() != org.apache.thrift.async.TAsyncMethodCall.State.RESPONSE_READ) {
          throw new IllegalStateException("Method call not finished!");
        }
        org.apache.thrift.transport.TMemoryInputTransport memoryTransport = new org.apache.thrift.transport.TMemoryInputTransport(getFrameBuffer().array());
        org.apache.thrift.protocol.TProtocol prot = client.getProtocolFactory().getProtocol(memoryTransport);
        return (new Client(prot)).recv_getGridFTPDataMovement();
      }
    }

    public void changeJobSubmissionPriority(org.apache.airavata.model.security.AuthzToken authzToken, String jobSubmissionInterfaceId, int newPriorityOrder, org.apache.thrift.async.AsyncMethodCallback resultHandler) throws org.apache.thrift.TException {
      checkReady();
      changeJobSubmissionPriority_call method_call = new changeJobSubmissionPriority_call(authzToken, jobSubmissionInterfaceId, newPriorityOrder, resultHandler, this, ___protocolFactory, ___transport);
      this.___currentMethod = method_call;
      ___manager.call(method_call);
    }

    public static class changeJobSubmissionPriority_call extends org.apache.thrift.async.TAsyncMethodCall {
      private org.apache.airavata.model.security.AuthzToken authzToken;
      private String jobSubmissionInterfaceId;
      private int newPriorityOrder;
      public changeJobSubmissionPriority_call(org.apache.airavata.model.security.AuthzToken authzToken, String jobSubmissionInterfaceId, int newPriorityOrder, org.apache.thrift.async.AsyncMethodCallback resultHandler, org.apache.thrift.async.TAsyncClient client, org.apache.thrift.protocol.TProtocolFactory protocolFactory, org.apache.thrift.transport.TNonblockingTransport transport) throws org.apache.thrift.TException {
        super(client, protocolFactory, transport, resultHandler, false);
        this.authzToken = authzToken;
        this.jobSubmissionInterfaceId = jobSubmissionInterfaceId;
        this.newPriorityOrder = newPriorityOrder;
      }

      public void write_args(org.apache.thrift.protocol.TProtocol prot) throws org.apache.thrift.TException {
        prot.writeMessageBegin(new org.apache.thrift.protocol.TMessage("changeJobSubmissionPriority", org.apache.thrift.protocol.TMessageType.CALL, 0));
        changeJobSubmissionPriority_args args = new changeJobSubmissionPriority_args();
        args.setAuthzToken(authzToken);
        args.setJobSubmissionInterfaceId(jobSubmissionInterfaceId);
        args.setNewPriorityOrder(newPriorityOrder);
        args.write(prot);
        prot.writeMessageEnd();
      }

      public boolean getResult() throws org.apache.airavata.model.error.InvalidRequestException, org.apache.airavata.model.error.AiravataClientException, org.apache.airavata.model.error.AiravataSystemException, org.apache.airavata.model.error.AuthorizationException, org.apache.thrift.TException {
        if (getState() != org.apache.thrift.async.TAsyncMethodCall.State.RESPONSE_READ) {
          throw new IllegalStateException("Method call not finished!");
        }
        org.apache.thrift.transport.TMemoryInputTransport memoryTransport = new org.apache.thrift.transport.TMemoryInputTransport(getFrameBuffer().array());
        org.apache.thrift.protocol.TProtocol prot = client.getProtocolFactory().getProtocol(memoryTransport);
        return (new Client(prot)).recv_changeJobSubmissionPriority();
      }
    }

    public void changeDataMovementPriority(org.apache.airavata.model.security.AuthzToken authzToken, String dataMovementInterfaceId, int newPriorityOrder, org.apache.thrift.async.AsyncMethodCallback resultHandler) throws org.apache.thrift.TException {
      checkReady();
      changeDataMovementPriority_call method_call = new changeDataMovementPriority_call(authzToken, dataMovementInterfaceId, newPriorityOrder, resultHandler, this, ___protocolFactory, ___transport);
      this.___currentMethod = method_call;
      ___manager.call(method_call);
    }

    public static class changeDataMovementPriority_call extends org.apache.thrift.async.TAsyncMethodCall {
      private org.apache.airavata.model.security.AuthzToken authzToken;
      private String dataMovementInterfaceId;
      private int newPriorityOrder;
      public changeDataMovementPriority_call(org.apache.airavata.model.security.AuthzToken authzToken, String dataMovementInterfaceId, int newPriorityOrder, org.apache.thrift.async.AsyncMethodCallback resultHandler, org.apache.thrift.async.TAsyncClient client, org.apache.thrift.protocol.TProtocolFactory protocolFactory, org.apache.thrift.transport.TNonblockingTransport transport) throws org.apache.thrift.TException {
        super(client, protocolFactory, transport, resultHandler, false);
        this.authzToken = authzToken;
        this.dataMovementInterfaceId = dataMovementInterfaceId;
        this.newPriorityOrder = newPriorityOrder;
      }

      public void write_args(org.apache.thrift.protocol.TProtocol prot) throws org.apache.thrift.TException {
        prot.writeMessageBegin(new org.apache.thrift.protocol.TMessage("changeDataMovementPriority", org.apache.thrift.protocol.TMessageType.CALL, 0));
        changeDataMovementPriority_args args = new changeDataMovementPriority_args();
        args.setAuthzToken(authzToken);
        args.setDataMovementInterfaceId(dataMovementInterfaceId);
        args.setNewPriorityOrder(newPriorityOrder);
        args.write(prot);
        prot.writeMessageEnd();
      }

      public boolean getResult() throws org.apache.airavata.model.error.InvalidRequestException, org.apache.airavata.model.error.AiravataClientException, org.apache.airavata.model.error.AiravataSystemException, org.apache.airavata.model.error.AuthorizationException, org.apache.thrift.TException {
        if (getState() != org.apache.thrift.async.TAsyncMethodCall.State.RESPONSE_READ) {
          throw new IllegalStateException("Method call not finished!");
        }
        org.apache.thrift.transport.TMemoryInputTransport memoryTransport = new org.apache.thrift.transport.TMemoryInputTransport(getFrameBuffer().array());
        org.apache.thrift.protocol.TProtocol prot = client.getProtocolFactory().getProtocol(memoryTransport);
        return (new Client(prot)).recv_changeDataMovementPriority();
      }
    }

    public void changeJobSubmissionPriorities(org.apache.airavata.model.security.AuthzToken authzToken, Map<String,Integer> jobSubmissionPriorityMap, org.apache.thrift.async.AsyncMethodCallback resultHandler) throws org.apache.thrift.TException {
      checkReady();
      changeJobSubmissionPriorities_call method_call = new changeJobSubmissionPriorities_call(authzToken, jobSubmissionPriorityMap, resultHandler, this, ___protocolFactory, ___transport);
      this.___currentMethod = method_call;
      ___manager.call(method_call);
    }

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

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

      public boolean getResult() throws org.apache.airavata.model.error.InvalidRequestException, org.apache.airavata.model.error.AiravataClientException, org.apache.airavata.model.error.AiravataSystemException, org.apache.airavata.model.error.AuthorizationException, org.apache.thrift.TException {
        if (getState() != org.apache.thrift.async.TAsyncMethodCall.State.RESPONSE_READ) {
          throw new IllegalStateException("Method call not finished!");
        }
        org.apache.thrift.transport.TMemoryInputTransport memoryTransport = new org.apache.thrift.transport.TMemoryInputTransport(getFrameBuffer().array());
        org.apache.thrift.protocol.TProtocol prot = client.getProtocolFactory().getProtocol(memoryTransport);
        return (new Client(prot)).recv_changeJobSubmissionPriorities();
      }
    }

    public void changeDataMovementPriorities(org.apache.airavata.model.security.AuthzToken authzToken, Map<String,Integer> dataMovementPriorityMap, org.apache.thrift.async.AsyncMethodCallback resultHandler) throws org.apache.thrift.TException {
      checkReady();
      changeDataMovementPriorities_call method_call = new changeDataMovementPriorities_call(authzToken, dataMovementPriorityMap, resultHandler, this, ___protocolFactory, ___transport);
      this.___currentMethod = method_call;
      ___manager.call(method_call);
    }

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

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

      public boolean getResult() throws org.apache.airavata.model.error.InvalidRequestException, org.apache.airavata.model.error.AiravataClientException, org.apache.airavata.model.error.AiravataSystemException, org.apache.airavata.model.error.AuthorizationException, org.apache.thrift.TException {
        if (getState() != org.apache.thrift.async.TAsyncMethodCall.State.RESPONSE_READ) {
          throw new IllegalStateException("Method call not finished!");
        }
        org.apache.thrift.transport.TMemoryInputTransport memoryTransport = new org.apache.thrift.transport.TMemoryInputTransport(getFrameBuffer().array());
        org.apache.thrift.protocol.TProtocol prot = client.getProtocolFactory().getProtocol(memoryTransport);
        return (new Client(prot)).recv_changeDataMovementPriorities();
      }
    }

    public void deleteJobSubmissionInterface(org.apache.airavata.model.security.AuthzToken authzToken, String computeResourceId, String jobSubmissionInterfaceId, org.apache.thrift.async.AsyncMethodCallback resultHandler) throws org.apache.thrift.TException {
      checkReady();
      deleteJobSubmissionInterface_call method_call = new deleteJobSubmissionInterface_call(authzToken, computeResourceId, jobSubmissionInterfaceId, resultHandler, this, ___protocolFactory, ___transport);
      this.___currentMethod = method_call;
      ___manager.call(method_call);
    }

    public static class deleteJobSubmissionInterface_call extends org.apache.thrift.async.TAsyncMethodCall {
      private org.apache.airavata.model.security.AuthzToken authzToken;
      private String computeResourceId;
      private String jobSubmissionInterfaceId;
      public deleteJobSubmissionInterface_call(org.apache.airavata.model.security.AuthzToken authzToken, String computeResourceId, String jobSubmissionInterfaceId, org.apache.thrift.async.AsyncMethodCallback resultHandler, org.apache.thrift.async.TAsyncClient client, org.apache.thrift.protocol.TProtocolFactory protocolFactory, org.apache.thrift.transport.TNonblockingTransport transport) throws org.apache.thrift.TException {
        super(client, protocolFactory, transport, resultHandler, false);
        this.authzToken = authzToken;
        this.computeResourceId = computeResourceId;
        this.jobSubmissionInterfaceId = jobSubmissionInterfaceId;
      }

      public void write_args(org.apache.thrift.protocol.TProtocol prot) throws org.apache.thrift.TException {
        prot.writeMessageBegin(new org.apache.thrift.protocol.TMessage("deleteJobSubmissionInterface", org.apache.thrift.protocol.TMessageType.CALL, 0));
        deleteJobSubmissionInterface_args args = new deleteJobSubmissionInterface_args();
        args.setAuthzToken(authzToken);
        args.setComputeResourceId(computeResourceId);
        args.setJobSubmissionInterfaceId(jobSubmissionInterfaceId);
        args.write(prot);
        prot.writeMessageEnd();
      }

      public boolean getResult() throws org.apache.airavata.model.error.InvalidRequestException, org.apache.airavata.model.error.AiravataClientException, org.apache.airavata.model.error.AiravataSystemException, org.apache.airavata.model.error.AuthorizationException, org.apache.thrift.TException {
        if (getState() != org.apache.thrift.async.TAsyncMethodCall.State.RESPONSE_READ) {
          throw new IllegalStateException("Method call not finished!");
        }
        org.apache.thrift.transport.TMemoryInputTransport memoryTransport = new org.apache.thrift.transport.TMemoryInputTransport(getFrameBuffer().array());
        org.apache.thrift.protocol.TProtocol prot = client.getProtocolFactory().getProtocol(memoryTransport);
        return (new Client(prot)).recv_deleteJobSubmissionInterface();
      }
    }

    public void deleteDataMovementInterface(org.apache.airavata.model.security.AuthzToken authzToken, String computeResourceId, String dataMovementInterfaceId, org.apache.thrift.async.AsyncMethodCallback resultHandler) throws org.apache.thrift.TException {
      checkReady();
      deleteDataMovementInterface_call method_call = new deleteDataMovementInterface_call(authzToken, computeResourceId, dataMovementInterfaceId, resultHandler, this, ___protocolFactory, ___transport);
      this.___currentMethod = method_call;
      ___manager.call(method_call);
    }

    public static class deleteDataMovementInterface_call extends org.apache.thrift.async.TAsyncMethodCall {
      private org.apache.airavata.model.security.AuthzToken authzToken;
      private String computeResourceId;
      private String dataMovementInterfaceId;
      public deleteDataMovementInterface_call(org.apache.airavata.model.security.AuthzToken authzToken, String computeResourceId, String dataMovementInterfaceId, org.apache.thrift.async.AsyncMethodCallback resultHandler, org.apache.thrift.async.TAsyncClient client, org.apache.thrift.protocol.TProtocolFactory protocolFactory, org.apache.thrift.transport.TNonblockingTransport transport) throws org.apache.thrift.TException {
        super(client, protocolFactory, transport, resultHandler, false);
        this.authzToken = authzToken;
        this.computeResourceId = computeResourceId;
        this.dataMovementInterfaceId = dataMovementInterfaceId;
      }

      public void write_args(org.apache.thrift.protocol.TProtocol prot) throws org.apache.thrift.TException {
        prot.writeMessageBegin(new org.apache.thrift.protocol.TMessage("deleteDataMovementInterface", org.apache.thrift.protocol.TMessageType.CALL, 0));
        deleteDataMovementInterface_args args = new deleteDataMovementInterface_args();
        args.setAuthzToken(authzToken);
        args.setComputeResourceId(computeResourceId);
        args.setDataMovementInterfaceId(dataMovementInterfaceId);
        args.write(prot);
        prot.writeMessageEnd();
      }

      public boolean getResult() throws org.apache.airavata.model.error.InvalidRequestException, org.apache.airavata.model.error.AiravataClientException, org.apache.airavata.model.error.AiravataSystemException, org.apache.airavata.model.error.AuthorizationException, org.apache.thrift.TException {
        if (getState() != org.apache.thrift.async.TAsyncMethodCall.State.RESPONSE_READ) {
          throw new IllegalStateException("Method call not finished!");
        }
        org.apache.thrift.transport.TMemoryInputTransport memoryTransport = new org.apache.thrift.transport.TMemoryInputTransport(getFrameBuffer().array());
        org.apache.thrift.protocol.TProtocol prot = client.getProtocolFactory().getProtocol(memoryTransport);
        return (new Client(prot)).recv_deleteDataMovementInterface();
      }
    }

    public void registerResourceJobManager(org.apache.airavata.model.security.AuthzToken authzToken, org.apache.airavata.model.appcatalog.computeresource.ResourceJobManager resourceJobManager, org.apache.thrift.async.AsyncMethodCallback resultHandler) throws org.apache.thrift.TException {
      checkReady();
      registerResourceJobManager_call method_call = new registerResourceJobManager_call(authzToken, resourceJobManager, resultHandler, this, ___protocolFactory, ___transport);
      this.___currentMethod = method_call;
      ___manager.call(method_call);
    }

    public static class registerResourceJobManager_call extends org.apache.thrift.async.TAsyncMethodCall {
      private org.apache.airavata.model.security.AuthzToken authzToken;
      private org.apache.airavata.model.appcatalog.computeresource.ResourceJobManager resourceJobManager;
      public registerResourceJobManager_call(org.apache.airavata.model.security.AuthzToken authzToken, org.apache.airavata.model.appcatalog.computeresource.ResourceJobManager resourceJobManager, org.apache.thrift.async.AsyncMethodCallback resultHandler, org.apache.thrift.async.TAsyncClient client, org.apache.thrift.protocol.TProtocolFactory protocolFactory, org.apache.thrift.transport.TNonblockingTransport transport) throws org.apache.thrift.TException {
        super(client, protocolFactory, transport, resultHandler, false);
        this.authzToken = authzToken;
        this.resourceJobManager = resourceJobManager;
      }

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

      public String getResult() throws org.apache.airavata.model.error.InvalidRequestException, org.apache.airavata.model.error.AiravataClientException, org.apache.airavata.model.error.AiravataSystemException, org.apache.airavata.model.error.AuthorizationException, org.apache.thrift.TException {
        if (getState() != org.apache.thrift.async.TAsyncMethodCall.State.RESPONSE_READ) {
          throw new IllegalStateException("Method call not finished!");
        }
        org.apache.thrift.transport.TMemoryInputTransport memoryTransport = new org.apache.thrift.transport.TMemoryInputTransport(getFrameBuffer().array());
        org.apache.thrift.protocol.TProtocol prot = client.getProtocolFactory().getProtocol(memoryTransport);
        return (new Client(prot)).recv_registerResourceJobManager();
      }
    }

    public void updateResourceJobManager(org.apache.airavata.model.security.AuthzToken authzToken, String resourceJobManagerId, org.apache.airavata.model.appcatalog.computeresource.ResourceJobManager updatedResourceJobManager, org.apache.thrift.async.AsyncMethodCallback resultHandler) throws org.apache.thrift.TException {
      checkReady();
      updateResourceJobManager_call method_call = new updateResourceJobManager_call(authzToken, resourceJobManagerId, updatedResourceJobManager, resultHandler, this, ___protocolFactory, ___transport);
      this.___currentMethod = method_call;
      ___manager.call(method_call);
    }

    public static class updateResourceJobManager_call extends org.apache.thrift.async.TAsyncMethodCall {
      private org.apache.airavata.model.security.AuthzToken authzToken;
      private String resourceJobManagerId;
      private org.apache.airavata.model.appcatalog.computeresource.ResourceJobManager updatedResourceJobManager;
      public updateResourceJobManager_call(org.apache.airavata.model.security.AuthzToken authzToken, String resourceJobManagerId, org.apache.airavata.model.appcatalog.computeresource.ResourceJobManager updatedResourceJobManager, org.apache.thrift.async.AsyncMethodCallback resultHandler, org.apache.thrift.async.TAsyncClient client, org.apache.thrift.protocol.TProtocolFactory protocolFactory, org.apache.thrift.transport.TNonblockingTransport transport) throws org.apache.thrift.TException {
        super(client, protocolFactory, transport, resultHandler, false);
        this.authzToken = authzToken;
        this.resourceJobManagerId = resourceJobManagerId;
        this.updatedResourceJobManager = updatedResourceJobManager;
      }

      public void write_args(org.apache.thrift.protocol.TProtocol prot) throws org.apache.thrift.TException {
        prot.writeMessageBegin(new org.apache.thrift.protocol.TMessage("updateResourceJobManager", org.apache.thrift.protocol.TMessageType.CALL, 0));
        updateResourceJobManager_args args = new updateResourceJobManager_args();
        args.setAuthzToken(authzToken);
        args.setResourceJobManagerId(resourceJobManagerId);
        args.setUpdatedResourceJobManager(updatedResourceJobManager);
        args.write(prot);
        prot.writeMessageEnd();
      }

      public boolean getResult() throws org.apache.airavata.model.error.InvalidRequestException, org.apache.airavata.model.error.AiravataClientException, org.apache.airavata.model.error.AiravataSystemException, org.apache.airavata.model.error.AuthorizationException, org.apache.thrift.TException {
        if (getState() != org.apache.thrift.async.TAsyncMethodCall.State.RESPONSE_READ) {
          throw new IllegalStateException("Method call not finished!");
        }
        org.apache.thrift.transport.TMemoryInputTransport memoryTransport = new org.apache.thrift.transport.TMemoryInputTransport(getFrameBuffer().array());
        org.apache.thrift.protocol.TProtocol prot = client.getProtocolFactory().getProtocol(memoryTransport);
        return (new Client(prot)).recv_updateResourceJobManager();
      }
    }

    public void getResourceJobManager(org.apache.airavata.model.security.AuthzToken authzToken, String resourceJobManagerId, org.apache.thrift.async.AsyncMethodCallback resultHandler) throws org.apache.thrift.TException {
      checkReady();
      getResourceJobManager_call method_call = new getResourceJobManager_call(authzToken, resourceJobManagerId, resultHandler, this, ___protocolFactory, ___transport);
      this.___currentMethod = method_call;
      ___manager.call(method_call);
    }

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

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

      public org.apache.airavata.model.appcatalog.computeresource.ResourceJobManager getResult() throws org.apache.airavata.model.error.InvalidRequestException, org.apache.airavata.model.error.AiravataClientException, org.apache.airavata.model.error.AiravataSystemException, org.apache.airavata.model.error.AuthorizationException, org.apache.thrift.TException {
        if (getState() != org.apache.thrift.async.TAsyncMethodCall.State.RESPONSE_READ) {
          throw new IllegalStateException("Method call not finished!");
        }
        org.apache.thrift.transport.TMemoryInputTransport memoryTransport = new org.apache.thrift.transport.TMemoryInputTransport(getFrameBuffer().array());
        org.apache.thrift.protocol.TProtocol prot = client.getProtocolFactory().getProtocol(memoryTransport);
        return (new Client(prot)).recv_getResourceJobManager();
      }
    }

    public void deleteResourceJobManager(org.apache.airavata.model.security.AuthzToken authzToken, String resourceJobManagerId, org.apache.thrift.async.AsyncMethodCallback resultHandler) throws org.apache.thrift.TException {
      checkReady();
      deleteResourceJobManager_call method_call = new deleteResourceJobManager_call(authzToken, resourceJobManagerId, resultHandler, this, ___protocolFactory, ___transport);
      this.___currentMethod = method_call;
      ___manager.call(method_call);
    }

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

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

      public boolean getResult() throws org.apache.airavata.model.error.InvalidRequestException, org.apache.airavata.model.error.AiravataClientException, org.apache.airavata.model.error.AiravataSystemException, org.apache.airavata.model.error.AuthorizationException, org.apache.thrift.TException {
        if (getState() != org.apache.thrift.async.TAsyncMethodCall.State.RESPONSE_READ) {
          throw new IllegalStateException("Method call not finished!");
        }
        org.apache.thrift.transport.TMemoryInputTransport memoryTransport = new org.apache.thrift.transport.TMemoryInputTransport(getFrameBuffer().array());
        org.apache.thrift.protocol.TProtocol prot = client.getProtocolFactory().getProtocol(memoryTransport);
        return (new Client(prot)).recv_deleteResourceJobManager();
      }
    }

    public void deleteBatchQueue(org.apache.airavata.model.security.AuthzToken authzToken, String computeResourceId, String queueName, org.apache.thrift.async.AsyncMethodCallback resultHandler) throws org.apache.thrift.TException {
      checkReady();
      deleteBatchQueue_call method_call = new deleteBatchQueue_call(authzToken, computeResourceId, queueName, resultHandler, this, ___protocolFactory, ___transport);
      this.___currentMethod = method_call;
      ___manager.call(method_call);
    }

    public static class deleteBatchQueue_call extends org.apache.thrift.async.TAsyncMethodCall {
      private org.apache.airavata.model.security.AuthzToken authzToken;
      private String computeResourceId;
      private String queueName;
      public deleteBatchQueue_call(org.apache.airavata.model.security.AuthzToken authzToken, String computeResourceId, String queueName, org.apache.thrift.async.AsyncMethodCallback resultHandler, org.apache.thrift.async.TAsyncClient client, org.apache.thrift.protocol.TProtocolFactory protocolFactory, org.apache.thrift.transport.TNonblockingTransport transport) throws org.apache.thrift.TException {
        super(client, protocolFactory, transport, resultHandler, false);
        this.authzToken = authzToken;
        this.computeResourceId = computeResourceId;
        this.queueName = queueName;
      }

      public void write_args(org.apache.thrift.protocol.TProtocol prot) throws org.apache.thrift.TException {
        prot.writeMessageBegin(new org.apache.thrift.protocol.TMessage("deleteBatchQueue", org.apache.thrift.protocol.TMessageType.CALL, 0));
        deleteBatchQueue_args args = new deleteBatchQueue_args();
        args.setAuthzToken(authzToken);
        args.setComputeResourceId(computeResourceId);
        args.setQueueName(queueName);
        args.write(prot);
        prot.writeMessageEnd();
      }

      public boolean getResult() throws org.apache.airavata.model.error.InvalidRequestException, org.apache.airavata.model.error.AiravataClientException, org.apache.airavata.model.error.AiravataSystemException, org.apache.airavata.model.error.AuthorizationException, org.apache.thrift.TException {
        if (getState() != org.apache.thrift.async.TAsyncMethodCall.State.RESPONSE_READ) {
          throw new IllegalStateException("Method call not finished!");
        }
        org.apache.thrift.transport.TMemoryInputTransport memoryTransport = new org.apache.thrift.transport.TMemoryInputTransport(getFrameBuffer().array());
        org.apache.thrift.protocol.TProtocol prot = client.getProtocolFactory().getProtocol(memoryTransport);
        return (new Client(prot)).recv_deleteBatchQueue();
      }
    }

    public void registerGatewayResourceProfile(org.apache.airavata.model.security.AuthzToken authzToken, org.apache.airavata.model.appcatalog.gatewayprofile.GatewayResourceProfile gatewayResourceProfile, org.apache.thrift.async.AsyncMethodCallback resultHandler) throws org.apache.thrift.TException {
      checkReady();
      registerGatewayResourceProfile_call method_call = new registerGatewayResourceProfile_call(authzToken, gatewayResourceProfile, resultHandler, this, ___protocolFactory, ___transport);
      this.___currentMethod = method_call;
      ___manager.call(method_call);
    }

    public static class registerGatewayResourceProfile_call extends org.apache.thrift.async.TAsyncMethodCall {
      private org.apache.airavata.model.security.AuthzToken authzToken;
      private org.apache.airavata.model.appcatalog.gatewayprofile.GatewayResourceProfile gatewayResourceProfile;
      public registerGatewayResourceProfile_call(org.apache.airavata.model.security.AuthzToken authzToken, org.apache.airavata.model.appcatalog.gatewayprofile.GatewayResourceProfile gatewayResourceProfile, org.apache.thrift.async.AsyncMethodCallback resultHandler, org.apache.thrift.async.TAsyncClient client, org.apache.thrift.protocol.TProtocolFactory protocolFactory, org.apache.thrift.transport.TNonblockingTransport transport) throws org.apache.thrift.TException {
        super(client, protocolFactory, transport, resultHandler, false);
        this.authzToken = authzToken;
        this.gatewayResourceProfile = gatewayResourceProfile;
      }

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

      public String getResult() throws org.apache.airavata.model.error.InvalidRequestException, org.apache.airavata.model.error.AiravataClientException, org.apache.airavata.model.error.AiravataSystemException, org.apache.airavata.model.error.AuthorizationException, org.apache.thrift.TException {
        if (getState() != org.apache.thrift.async.TAsyncMethodCall.State.RESPONSE_READ) {
          throw new IllegalStateException("Method call not finished!");
        }
        org.apache.thrift.transport.TMemoryInputTransport memoryTransport = new org.apache.thrift.transport.TMemoryInputTransport(getFrameBuffer().array());
        org.apache.thrift.protocol.TProtocol prot = client.getProtocolFactory().getProtocol(memoryTransport);
        return (new Client(prot)).recv_registerGatewayResourceProfile();
      }
    }

    public void getGatewayResourceProfile(org.apache.airavata.model.security.AuthzToken authzToken, String gatewayID, org.apache.thrift.async.AsyncMethodCallback resultHandler) throws org.apache.thrift.TException {
      checkReady();
      getGatewayResourceProfile_call method_call = new getGatewayResourceProfile_call(authzToken, gatewayID, resultHandler, this, ___protocolFactory, ___transport);
      this.___currentMethod = method_call;
      ___manager.call(method_call);
    }

    public static class getGatewayResourceProfile_call extends org.apache.thrift.async.TAsyncMethodCall {
      private org.apache.airavata.model.security.AuthzToken authzToken;
      private String gatewayID;
      public getGatewayResourceProfile_call(org.apache.airavata.model.security.AuthzToken authzToken, String gatewayID, org.apache.thrift.async.AsyncMethodCallback resultHandler, org.apache.thrift.async.TAsyncClient client, org.apache.thrift.protocol.TProtocolFactory protocolFactory, org.apache.thrift.transport.TNonblockingTransport transport) throws org.apache.thrift.TException {
        super(client, protocolFactory, transport, resultHandler, false);
        this.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("getGatewayResourceProfile", org.apache.thrift.protocol.TMessageType.CALL, 0));
        getGatewayResourceProfile_args args = new getGatewayResourceProfile_args();
        args.setAuthzToken(authzToken);
        args.setGatewayID(gatewayID);
        args.write(prot);
        prot.writeMessageEnd();
      }

      public org.apache.airavata.model.appcatalog.gatewayprofile.GatewayResourceProfile getResult() throws org.apache.airavata.model.error.InvalidRequestException, org.apache.airavata.model.error.AiravataClientException, org.apache.airavata.model.error.AiravataSystemException, org.apache.airavata.model.error.AuthorizationException, org.apache.thrift.TException {
        if (getState() != org.apache.thrift.async.TAsyncMethodCall.State.RESPONSE_READ) {
          throw new IllegalStateException("Method call not finished!");
        }
        org.apache.thrift.transport.TMemoryInputTransport memoryTransport = new org.apache.thrift.transport.TMemoryInputTransport(getFrameBuffer().array());
        org.apache.thrift.protocol.TProtocol prot = client.getProtocolFactory().getProtocol(memoryTransport);
        return (new Client(prot)).recv_getGatewayResourceProfile();
      }
    }

    public void updateGatewayResourceProfile(org.apache.airavata.model.security.AuthzToken authzToken, String gatewayID, org.apache.airavata.model.appcatalog.gatewayprofile.GatewayResourceProfile gatewayResourceProfile, org.apache.thrift.async.AsyncMethodCallback resultHandler) throws org.apache.thrift.TException {
      checkReady();
      updateGatewayResourceProfile_call method_call = new updateGatewayResourceProfile_call(authzToken, gatewayID, gatewayResourceProfile, resultHandler, this, ___protocolFactory, ___transport);
      this.___currentMethod = method_call;
      ___manager.call(method_call);
    }

    public static class updateGatewayResourceProfile_call extends org.apache.thrift.async.TAsyncMethodCall {
      private org.apache.airavata.model.security.AuthzToken authzToken;
      private String gatewayID;
      private org.apache.airavata.model.appcatalog.gatewayprofile.GatewayResourceProfile gatewayResourceProfile;
      public updateGatewayResourceProfile_call(org.apache.airavata.model.security.AuthzToken authzToken, String gatewayID, org.apache.airavata.model.appcatalog.gatewayprofile.GatewayResourceProfile gatewayResourceProfile, org.apache.thrift.async.AsyncMethodCallback resultHandler, org.apache.thrift.async.TAsyncClient client, org.apache.thrift.protocol.TProtocolFactory protocolFactory, org.apache.thrift.transport.TNonblockingTransport transport) throws org.apache.thrift.TException {
        super(client, protocolFactory, transport, resultHandler, false);
        this.authzToken = authzToken;
        this.gatewayID = gatewayID;
        this.gatewayResourceProfile = gatewayResourceProfile;
      }

      public void write_args(org.apache.thrift.protocol.TProtocol prot) throws org.apache.thrift.TException {
        prot.writeMessageBegin(new org.apache.thrift.protocol.TMessage("updateGatewayResourceProfile", org.apache.thrift.protocol.TMessageType.CALL, 0));
        updateGatewayResourceProfile_args args = new updateGatewayResourceProfile_args();
        args.setAuthzToken(authzToken);
        args.setGatewayID(gatewayID);
        args.setGatewayResourceProfile(gatewayResourceProfile);
        args.write(prot);
        prot.writeMessageEnd();
      }

      public boolean getResult() throws org.apache.airavata.model.error.InvalidRequestException, org.apache.airavata.model.error.AiravataClientException, org.apache.airavata.model.error.AiravataSystemException, org.apache.airavata.model.error.AuthorizationException, org.apache.thrift.TException {
        if (getState() != org.apache.thrift.async.TAsyncMethodCall.State.RESPONSE_READ) {
          throw new IllegalStateException("Method call not finished!");
        }
        org.apache.thrift.transport.TMemoryInputTransport memoryTransport = new org.apache.thrift.transport.TMemoryInputTransport(getFrameBuffer().array());
        org.apache.thrift.protocol.TProtocol prot = client.getProtocolFactory().getProtocol(memoryTransport);
        return (new Client(prot)).recv_updateGatewayResourceProfile();
      }
    }

    public void deleteGatewayResourceProfile(org.apache.airavata.model.security.AuthzToken authzToken, String gatewayID, org.apache.thrift.async.AsyncMethodCallback resultHandler) throws org.apache.thrift.TException {
      checkReady();
      deleteGatewayResourceProfile_call method_call = new deleteGatewayResourceProfile_call(authzToken, gatewayID, resultHandler, this, ___protocolFactory, ___transport);
      this.___currentMethod = method_call;
      ___manager.call(method_call);
    }

    public static class deleteGatewayResourceProfile_call extends org.apache.thrift.async.TAsyncMethodCall {
      private org.apache.airavata.model.security.AuthzToken authzToken;
      private String gatewayID;
      public deleteGatewayResourceProfile_call(org.apache.airavata.model.security.AuthzToken authzToken, String gatewayID, org.apache.thrift.async.AsyncMethodCallback resultHandler, org.apache.thrift.async.TAsyncClient client, org.apache.thrift.protocol.TProtocolFactory protocolFactory, org.apache.thrift.transport.TNonblockingTransport transport) throws org.apache.thrift.TException {
        super(client, protocolFactory, transport, resultHandler, false);
        this.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("deleteGatewayResourceProfile", org.apache.thrift.protocol.TMessageType.CALL, 0));
        deleteGatewayResourceProfile_args args = new deleteGatewayResourceProfile_args();
        args.setAuthzToken(authzToken);
        args.setGatewayID(gatewayID);
        args.write(prot);
        prot.writeMessageEnd();
      }

      public boolean getResult() throws org.apache.airavata.model.error.InvalidRequestException, org.apache.airavata.model.error.AiravataClientException, org.apache.airavata.model.error.AiravataSystemException, org.apache.airavata.model.error.AuthorizationException, org.apache.thrift.TException {
        if (getState() != org.apache.thrift.async.TAsyncMethodCall.State.RESPONSE_READ) {
          throw new IllegalStateException("Method call not finished!");
        }
        org.apache.thrift.transport.TMemoryInputTransport memoryTransport = new org.apache.thrift.transport.TMemoryInputTransport(getFrameBuffer().array());
        org.apache.thrift.protocol.TProtocol prot = client.getProtocolFactory().getProtocol(memoryTransport);
        return (new Client(prot)).recv_deleteGatewayResourceProfile();
      }
    }

    public void addGatewayComputeResourcePreference(org.apache.airavata.model.security.AuthzToken authzToken, String gatewayID, String computeResourceId, org.apache.airavata.model.appcatalog.gatewayprofile.ComputeResourcePreference computeResourcePreference, org.apache.thrift.async.AsyncMethodCallback resultHandler) throws org.apache.thrift.TException {
      checkReady();
      addGatewayComputeResourcePreference_call method_call = new addGatewayComputeResourcePreference_call(authzToken, gatewayID, computeResourceId, computeResourcePreference, resultHandler, this, ___protocolFactory, ___transport);
      this.___currentMethod = method_call;
      ___manager.call(method_call);
    }

    public static class addGatewayComputeResourcePreference_call extends org.apache.thrift.async.TAsyncMethodCall {
      private org.apache.airavata.model.security.AuthzToken authzToken;
      private String gatewayID;
      private String computeResourceId;
      private org.apache.airavata.model.appcatalog.gatewayprofile.ComputeResourcePreference computeResourcePreference;
      public addGatewayComputeResourcePreference_call(org.apache.airavata.model.security.AuthzToken authzToken, String gatewayID, String computeResourceId, org.apache.airavata.model.appcatalog.gatewayprofile.ComputeResourcePreference computeResourcePreference, org.apache.thrift.async.AsyncMethodCallback resultHandler, org.apache.thrift.async.TAsyncClient client, org.apache.thrift.protocol.TProtocolFactory protocolFactory, org.apache.thrift.transport.TNonblockingTransport transport) throws org.apache.thrift.TException {
        super(client, protocolFactory, transport, resultHandler, false);
        this.authzToken = authzToken;
        this.gatewayID = gatewayID;
        this.computeResourceId = computeResourceId;
        this.computeResourcePreference = computeResourcePreference;
      }

      public void write_args(org.apache.thrift.protocol.TProtocol prot) throws org.apache.thrift.TException {
        prot.writeMessageBegin(new org.apache.thrift.protocol.TMessage("addGatewayComputeResourcePreference", org.apache.thrift.protocol.TMessageType.CALL, 0));
        addGatewayComputeResourcePreference_args args = new addGatewayComputeResourcePreference_args();
        args.setAuthzToken(authzToken);
        args.setGatewayID(gatewayID);
        args.setComputeResourceId(computeResourceId);
        args.setComputeResourcePreference(computeResourcePreference);
        args.write(prot);
        prot.writeMessageEnd();
      }

      public boolean getResult() throws org.apache.airavata.model.error.InvalidRequestException, org.apache.airavata.model.error.AiravataClientException, org.apache.airavata.model.error.AiravataSystemException, org.apache.airavata.model.error.AuthorizationException, org.apache.thrift.TException {
        if (getState() != org.apache.thrift.async.TAsyncMethodCall.State.RESPONSE_READ) {
          throw new IllegalStateException("Method call not finished!");
        }
        org.apache.thrift.transport.TMemoryInputTransport memoryTransport = new org.apache.thrift.transport.TMemoryInputTransport(getFrameBuffer().array());
        org.apache.thrift.protocol.TProtocol prot = client.getProtocolFactory().getProtocol(memoryTransport);
        return (new Client(prot)).recv_addGatewayComputeResourcePreference();
      }
    }

    public void addGatewayDataStoragePreference(org.apache.airavata.model.security.AuthzToken authzToken, String gatewayID, String dataMoveId, org.apache.airavata.model.appcatalog.gatewayprofile.DataStoragePreference dataStoragePreference, org.apache.thrift.async.AsyncMethodCallback resultHandler) throws org.apache.thrift.TException {
      checkReady();
      addGatewayDataStoragePreference_call method_call = new addGatewayDataStoragePreference_call(authzToken, gatewayID, dataMoveId, dataStoragePreference, resultHandler, this, ___protocolFactory, ___transport);
      this.___currentMethod = method_call;
      ___manager.call(method_call);
    }

    public static class addGatewayDataStoragePreference_call extends org.apache.thrift.async.TAsyncMethodCall {
      private org.apache.airavata.model.security.AuthzToken authzToken;
      private String gatewayID;
      private String dataMoveId;
      private org.apache.airavata.model.appcatalog.gatewayprofile.DataStoragePreference dataStoragePreference;
      public addGatewayDataStoragePreference_call(org.apache.airavata.model.security.AuthzToken authzToken, String gatewayID, String dataMoveId, org.apache.airavata.model.appcatalog.gatewayprofile.DataStoragePreference dataStoragePreference, org.apache.thrift.async.AsyncMethodCallback resultHandler, org.apache.thrift.async.TAsyncClient client, org.apache.thrift.protocol.TProtocolFactory protocolFactory, org.apache.thrift.transport.TNonblockingTransport transport) throws org.apache.thrift.TException {
        super(client, protocolFactory, transport, resultHandler, false);
        this.authzToken = authzToken;
        this.gatewayID = gatewayID;
        this.dataMoveId = dataMoveId;
        this.dataStoragePreference = dataStoragePreference;
      }

      public void write_args(org.apache.thrift.protocol.TProtocol prot) throws org.apache.thrift.TException {
        prot.writeMessageBegin(new org.apache.thrift.protocol.TMessage("addGatewayDataStoragePreference", org.apache.thrift.protocol.TMessageType.CALL, 0));
        addGatewayDataStoragePreference_args args = new addGatewayDataStoragePreference_args();
        args.setAuthzToken(authzToken);
        args.setGatewayID(gatewayID);
        args.setDataMoveId(dataMoveId);
        args.setDataStoragePreference(dataStoragePreference);
        args.write(prot);
        prot.writeMessageEnd();
      }

      public boolean getResult() throws org.apache.airavata.model.error.InvalidRequestException, org.apache.airavata.model.error.AiravataClientException, org.apache.airavata.model.error.AiravataSystemException, org.apache.airavata.model.error.AuthorizationException, org.apache.thrift.TException {
        if (getState() != org.apache.thrift.async.TAsyncMethodCall.State.RESPONSE_READ) {
          throw new IllegalStateException("Method call not finished!");
        }
        org.apache.thrift.transport.TMemoryInputTransport memoryTransport = new org.apache.thrift.transport.TMemoryInputTransport(getFrameBuffer().array());
        org.apache.thrift.protocol.TProtocol prot = client.getProtocolFactory().getProtocol(memoryTransport);
        return (new Client(prot)).recv_addGatewayDataStoragePreference();
      }
    }

    public void getGatewayComputeResourcePreference(org.apache.airavata.model.security.AuthzToken authzToken, String gatewayID, String computeResourceId, org.apache.thrift.async.AsyncMethodCallback resultHandler) throws org.apache.thrift.TException {
      checkReady();
      getGatewayComputeResourcePreference_call method_call = new getGatewayComputeResourcePreference_call(authzToken, gatewayID, computeResourceId, resultHandler, this, ___protocolFactory, ___transport);
      this.___currentMethod = method_call;
      ___manager.call(method_call);
    }

    public static class getGatewayComputeResourcePreference_call extends org.apache.thrift.async.TAsyncMethodCall {
      private org.apache.airavata.model.security.AuthzToken authzToken;
      private String gatewayID;
      private String computeResourceId;
      public getGatewayComputeResourcePreference_call(org.apache.airavata.model.security.AuthzToken authzToken, String gatewayID, String computeResourceId, org.apache.thrift.async.AsyncMethodCallback resultHandler, org.apache.thrift.async.TAsyncClient client, org.apache.thrift.protocol.TProtocolFactory protocolFactory, org.apache.thrift.transport.TNonblockingTransport transport) throws org.apache.thrift.TException {
        super(client, protocolFactory, transport, resultHandler, false);
        this.authzToken = authzToken;
        this.gatewayID = gatewayID;
        this.computeResourceId = computeResourceId;
      }

      public void write_args(org.apache.thrift.protocol.TProtocol prot) throws org.apache.thrift.TException {
        prot.writeMessageBegin(new org.apache.thrift.protocol.TMessage("getGatewayComputeResourcePreference", org.apache.thrift.protocol.TMessageType.CALL, 0));
        getGatewayComputeResourcePreference_args args = new getGatewayComputeResourcePreference_args();
        args.setAuthzToken(authzToken);
        args.setGatewayID(gatewayID);
        args.setComputeResourceId(computeResourceId);
        args.write(prot);
        prot.writeMessageEnd();
      }

      public org.apache.airavata.model.appcatalog.gatewayprofile.ComputeResourcePreference getResult() throws org.apache.airavata.model.error.InvalidRequestException, org.apache.airavata.model.error.AiravataClientException, org.apache.airavata.model.error.AiravataSystemException, org.apache.airavata.model.error.AuthorizationException, org.apache.thrift.TException {
        if (getState() != org.apache.thrift.async.TAsyncMethodCall.State.RESPONSE_READ) {
          throw new IllegalStateException("Method call not finished!");
        }
        org.apache.thrift.transport.TMemoryInputTransport memoryTransport = new org.apache.thrift.transport.TMemoryInputTransport(getFrameBuffer().array());
        org.apache.thrift.protocol.TProtocol prot = client.getProtocolFactory().getProtocol(memoryTransport);
        return (new Client(prot)).recv_getGatewayComputeResourcePreference();
      }
    }

    public void getGatewayDataStoragePreference(org.apache.airavata.model.security.AuthzToken authzToken, String gatewayID, String dataMoveId, org.apache.thrift.async.AsyncMethodCallback resultHandler) throws org.apache.thrift.TException {
      checkReady();
      getGatewayDataStoragePreference_call method_call = new getGatewayDataStoragePreference_call(authzToken, gatewayID, dataMoveId, resultHandler, this, ___protocolFactory, ___transport);
      this.___currentMethod = method_call;
      ___manager.call(method_call);
    }

    public static class getGatewayDataStoragePreference_call extends org.apache.thrift.async.TAsyncMethodCall {
      private org.apache.airavata.model.security.AuthzToken authzToken;
      private String gatewayID;
      private String dataMoveId;
      public getGatewayDataStoragePreference_call(org.apache.airavata.model.security.AuthzToken authzToken, String gatewayID, String dataMoveId, org.apache.thrift.async.AsyncMethodCallback resultHandler, org.apache.thrift.async.TAsyncClient client, org.apache.thrift.protocol.TProtocolFactory protocolFactory, org.apache.thrift.transport.TNonblockingTransport transport) throws org.apache.thrift.TException {
        super(client, protocolFactory, transport, resultHandler, false);
        this.authzToken = authzToken;
        this.gatewayID = gatewayID;
        this.dataMoveId = dataMoveId;
      }

      public void write_args(org.apache.thrift.protocol.TProtocol prot) throws org.apache.thrift.TException {
        prot.writeMessageBegin(new org.apache.thrift.protocol.TMessage("getGatewayDataStoragePreference", org.apache.thrift.protocol.TMessageType.CALL, 0));
        getGatewayDataStoragePreference_args args = new getGatewayDataStoragePreference_args();
        args.setAuthzToken(authzToken);
        args.setGatewayID(gatewayID);
        args.setDataMoveId(dataMoveId);
        args.write(prot);
        prot.writeMessageEnd();
      }

      public org.apache.airavata.model.appcatalog.gatewayprofile.DataStoragePreference getResult() throws org.apache.airavata.model.error.InvalidRequestException, org.apache.airavata.model.error.AiravataClientException, org.apache.airavata.model.error.AiravataSystemException, org.apache.airavata.model.error.AuthorizationException, org.apache.thrift.TException {
        if (getState() != org.apache.thrift.async.TAsyncMethodCall.State.RESPONSE_READ) {
          throw new IllegalStateException("Method call not finished!");
        }
        org.apache.thrift.transport.TMemoryInputTransport memoryTransport = new org.apache.thrift.transport.TMemoryInputTransport(getFrameBuffer().array());
        org.apache.thrift.protocol.TProtocol prot = client.getProtocolFactory().getProtocol(memoryTransport);
        return (new Client(prot)).recv_getGatewayDataStoragePreference();
      }
    }

    public void getAllGatewayComputeResourcePreferences(org.apache.airavata.model.security.AuthzToken authzToken, String gatewayID, org.apache.thrift.async.AsyncMethodCallback resultHandler) throws org.apache.thrift.TException {
      checkReady();
      getAllGatewayComputeResourcePreferences_call method_call = new getAllGatewayComputeResourcePreferences_call(authzToken, gatewayID, resultHandler, this, ___protocolFactory, ___transport);
      this.___currentMethod = method_call;
      ___manager.call(method_call);
    }

    public static class getAllGatewayComputeResourcePreferences_call extends org.apache.thrift.async.TAsyncMethodCall {
      private org.apache.airavata.model.security.AuthzToken authzToken;
      private String gatewayID;
      public getAllGatewayComputeResourcePreferences_call(org.apache.airavata.model.security.AuthzToken authzToken, String gatewayID, org.apache.thrift.async.AsyncMethodCallback resultHandler, org.apache.thrift.async.TAsyncClient client, org.apache.thrift.protocol.TProtocolFactory protocolFactory, org.apache.thrift.transport.TNonblockingTransport transport) throws org.apache.thrift.TException {
        super(client, protocolFactory, transport, resultHandler, false);
        this.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("getAllGatewayComputeResourcePreferences", org.apache.thrift.protocol.TMessageType.CALL, 0));
        getAllGatewayComputeResourcePreferences_args args = new getAllGatewayComputeResourcePreferences_args();
        args.setAuthzToken(authzToken);
        args.setGatewayID(gatewayID);
        args.write(prot);
        prot.writeMessageEnd();
      }

      public List<org.apache.airavata.model.appcatalog.gatewayprofile.ComputeResourcePreference> getResult() throws org.apache.airavata.model.error.InvalidRequestException, org.apache.airavata.model.error.AiravataClientException, org.apache.airavata.model.error.AiravataSystemException, org.apache.airavata.model.error.AuthorizationException, org.apache.thrift.TException {
        if (getState() != org.apache.thrift.async.TAsyncMethodCall.State.RESPONSE_READ) {
          throw new IllegalStateException("Method call not finished!");
        }
        org.apache.thrift.transport.TMemoryInputTransport memoryTransport = new org.apache.thrift.transport.TMemoryInputTransport(getFrameBuffer().array());
        org.apache.thrift.protocol.TProtocol prot = client.getProtocolFactory().getProtocol(memoryTransport);
        return (new Client(prot)).recv_getAllGatewayComputeResourcePreferences();
      }
    }

    public void getAllGatewayDataStoragePreferences(org.apache.airavata.model.security.AuthzToken authzToken, String gatewayID, org.apache.thrift.async.AsyncMethodCallback resultHandler) throws org.apache.thrift.TException {
      checkReady();
      getAllGatewayDataStoragePreferences_call method_call = new getAllGatewayDataStoragePreferences_call(authzToken, gatewayID, resultHandler, this, ___protocolFactory, ___transport);
      this.___currentMethod = method_call;
      ___manager.call(method_call);
    }

    public static class getAllGatewayDataStoragePreferences_call extends org.apache.thrift.async.TAsyncMethodCall {
      private org.apache.airavata.model.security.AuthzToken authzToken;
      private String gatewayID;
      public getAllGatewayDataStoragePreferences_call(org.apache.airavata.model.security.AuthzToken authzToken, String gatewayID, org.apache.thrift.async.AsyncMethodCallback resultHandler, org.apache.thrift.async.TAsyncClient client, org.apache.thrift.protocol.TProtocolFactory protocolFactory, org.apache.thrift.transport.TNonblockingTransport transport) throws org.apache.thrift.TException {
        super(client, protocolFactory, transport, resultHandler, false);
        this.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("getAllGatewayDataStoragePreferences", org.apache.thrift.protocol.TMessageType.CALL, 0));
        getAllGatewayDataStoragePreferences_args args = new getAllGatewayDataStoragePreferences_args();
        args.setAuthzToken(authzToken);
        args.setGatewayID(gatewayID);
        args.write(prot);
        prot.writeMessageEnd();
      }

      public List<org.apache.airavata.model.appcatalog.gatewayprofile.DataStoragePreference> getResult() throws org.apache.airavata.model.error.InvalidRequestException, org.apache.airavata.model.error.AiravataClientException, org.apache.airavata.model.error.AiravataSystemException, org.apache.airavata.model.error.AuthorizationException, org.apache.thrift.TException {
        if (getState() != org.apache.thrift.async.TAsyncMethodCall.State.RESPONSE_READ) {
          throw new IllegalStateException("Method call not finished!");
        }
        org.apache.thrift.transport.TMemoryInputTransport memoryTransport = new org.apache.thrift.transport.TMemoryInputTransport(getFrameBuffer().array());
        org.apache.thrift.protocol.TProtocol prot = client.getProtocolFactory().getProtocol(memoryTransport);
        return (new Client(prot)).recv_getAllGatewayDataStoragePreferences();
      }
    }

    public void getAllGatewayResourceProfiles(org.apache.airavata.model.security.AuthzToken authzToken, org.apache.thrift.async.AsyncMethodCallback resultHandler) throws org.apache.thrift.TException {
      checkReady();
      getAllGatewayResourceProfiles_call method_call = new getAllGatewayResourceProfiles_call(authzToken, resultHandler, this, ___protocolFactory, ___transport);
      this.___currentMethod = method_call;
      ___manager.call(method_call);
    }

    public static class getAllGatewayResourceProfiles_call extends org.apache.thrift.async.TAsyncMethodCall {
      private org.apache.airavata.model.security.AuthzToken authzToken;
      public getAllGatewayResourceProfiles_call(org.apache.airavata.model.security.AuthzToken authzToken, org.apache.thrift.async.AsyncMethodCallback resultHandler, org.apache.thrift.async.TAsyncClient client, org.apache.thrift.protocol.TProtocolFactory protocolFactory, org.apache.thrift.transport.TNonblockingTransport transport) throws org.apache.thrift.TException {
        super(client, protocolFactory, transport, resultHandler, false);
        this.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("getAllGatewayResourceProfiles", org.apache.thrift.protocol.TMessageType.CALL, 0));
        getAllGatewayResourceProfiles_args args = new getAllGatewayResourceProfiles_args();
        args.setAuthzToken(authzToken);
        args.write(prot);
        prot.writeMessageEnd();
      }

      public List<org.apache.airavata.model.appcatalog.gatewayprofile.GatewayResourceProfile> getResult() throws org.apache.airavata.model.error.InvalidRequestException, org.apache.airavata.model.error.AiravataClientException, org.apache.airavata.model.error.AiravataSystemException, org.apache.airavata.model.error.AuthorizationException, org.apache.thrift.TException {
        if (getState() != org.apache.thrift.async.TAsyncMethodCall.State.RESPONSE_READ) {
          throw new IllegalStateException("Method call not finished!");
        }
        org.apache.thrift.transport.TMemoryInputTransport memoryTransport = new org.apache.thrift.transport.TMemoryInputTransport(getFrameBuffer().array());
        org.apache.thrift.protocol.TProtocol prot = client.getProtocolFactory().getProtocol(memoryTransport);
        return (new Client(prot)).recv_getAllGatewayResourceProfiles();
      }
    }

    public void updateGatewayComputeResourcePreference(org.apache.airavata.model.security.AuthzToken authzToken, String gatewayID, String computeResourceId, org.apache.airavata.model.appcatalog.gatewayprofile.ComputeResourcePreference computeResourcePreference, org.apache.thrift.async.AsyncMethodCallback resultHandler) throws org.apache.thrift.TException {
      checkReady();
      updateGatewayComputeResourcePreference_call method_call = new updateGatewayComputeResourcePreference_call(authzToken, gatewayID, computeResourceId, computeResourcePreference, resultHandler, this, ___protocolFactory, ___transport);
      this.___currentMethod = method_call;
      ___manager.call(method_call);
    }

    public static class updateGatewayComputeResourcePreference_call extends org.apache.thrift.async.TAsyncMethodCall {
      private org.apache.airavata.model.security.AuthzToken authzToken;
      private String gatewayID;
      private String computeResourceId;
      private org.apache.airavata.model.appcatalog.gatewayprofile.ComputeResourcePreference computeResourcePreference;
      public updateGatewayComputeResourcePreference_call(org.apache.airavata.model.security.AuthzToken authzToken, String gatewayID, String computeResourceId, org.apache.airavata.model.appcatalog.gatewayprofile.ComputeResourcePreference computeResourcePreference, org.apache.thrift.async.AsyncMethodCallback resultHandler, org.apache.thrift.async.TAsyncClient client, org.apache.thrift.protocol.TProtocolFactory protocolFactory, org.apache.thrift.transport.TNonblockingTransport transport) throws org.apache.thrift.TException {
        super(client, protocolFactory, transport, resultHandler, false);
        this.authzToken = authzToken;
        this.gatewayID = gatewayID;
        this.computeResourceId = computeResourceId;
        this.computeResourcePreference = computeResourcePreference;
      }

      public void write_args(org.apache.thrift.protocol.TProtocol prot) throws org.apache.thrift.TException {
        prot.writeMessageBegin(new org.apache.thrift.protocol.TMessage("updateGatewayComputeResourcePreference", org.apache.thrift.protocol.TMessageType.CALL, 0));
        updateGatewayComputeResourcePreference_args args = new updateGatewayComputeResourcePreference_args();
        args.setAuthzToken(authzToken);
        args.setGatewayID(gatewayID);
        args.setComputeResourceId(computeResourceId);
        args.setComputeResourcePreference(computeResourcePreference);
        args.write(prot);
        prot.writeMessageEnd();
      }

      public boolean getResult() throws org.apache.airavata.model.error.InvalidRequestException, org.apache.airavata.model.error.AiravataClientException, org.apache.airavata.model.error.AiravataSystemException, org.apache.airavata.model.error.AuthorizationException, org.apache.thrift.TException {
        if (getState() != org.apache.thrift.async.TAsyncMethodCall.State.RESPONSE_READ) {
          throw new IllegalStateException("Method call not finished!");
        }
        org.apache.thrift.transport.TMemoryInputTransport memoryTransport = new org.apache.thrift.transport.TMemoryInputTransport(getFrameBuffer().array());
        org.apache.thrift.protocol.TProtocol prot = client.getProtocolFactory().getProtocol(memoryTransport);
        return (new Client(prot)).recv_updateGatewayComputeResourcePreference();
      }
    }

    public void updateGatewayDataStoragePreference(org.apache.airavata.model.security.AuthzToken authzToken, String gatewayID, String dataMoveId, org.apache.airavata.model.appcatalog.gatewayprofile.DataStoragePreference dataStoragePreference, org.apache.thrift.async.AsyncMethodCallback resultHandler) throws org.apache.thrift.TException {
      checkReady();
      updateGatewayDataStoragePreference_call method_call = new updateGatewayDataStoragePreference_call(authzToken, gatewayID, dataMoveId, dataStoragePreference, resultHandler, this, ___protocolFactory, ___transport);
      this.___currentMethod = method_call;
      ___manager.call(method_call);
    }

    public static class updateGatewayDataStoragePreference_call extends org.apache.thrift.async.TAsyncMethodCall {
      private org.apache.airavata.model.security.AuthzToken authzToken;
      private String gatewayID;
      private String dataMoveId;
      private org.apache.airavata.model.appcatalog.gatewayprofile.DataStoragePreference dataStoragePreference;
      public updateGatewayDataStoragePreference_call(org.apache.airavata.model.security.AuthzToken authzToken, String gatewayID, String dataMoveId, org.apache.airavata.model.appcatalog.gatewayprofile.DataStoragePreference dataStoragePreference, org.apache.thrift.async.AsyncMethodCallback resultHandler, org.apache.thrift.async.TAsyncClient client, org.apache.thrift.protocol.TProtocolFactory protocolFactory, org.apache.thrift.transport.TNonblockingTransport transport) throws org.apache.thrift.TException {
        super(client, protocolFactory, transport, resultHandler, false);
        this.authzToken = authzToken;
        this.gatewayID = gatewayID;
        this.dataMoveId = dataMoveId;
        this.dataStoragePreference = dataStoragePreference;
      }

      public void write_args(org.apache.thrift.protocol.TProtocol prot) throws org.apache.thrift.TException {
        prot.writeMessageBegin(new org.apache.thrift.protocol.TMessage("updateGatewayDataStoragePreference", org.apache.thrift.protocol.TMessageType.CALL, 0));
        updateGatewayDataStoragePreference_args args = new updateGatewayDataStoragePreference_args();
        args.setAuthzToken(authzToken);
        args.setGatewayID(gatewayID);
        args.setDataMoveId(dataMoveId);
        args.setDataStoragePreference(dataStoragePreference);
        args.write(prot);
        prot.writeMessageEnd();
      }

      public boolean getResult() throws org.apache.airavata.model.error.InvalidRequestException, org.apache.airavata.model.error.AiravataClientException, org.apache.airavata.model.error.AiravataSystemException, org.apache.airavata.model.error.AuthorizationException, org.apache.thrift.TException {
        if (getState() != org.apache.thrift.async.TAsyncMethodCall.State.RESPONSE_READ) {
          throw new IllegalStateException("Method call not finished!");
        }
        org.apache.thrift.transport.TMemoryInputTransport memoryTransport = new org.apache.thrift.transport.TMemoryInputTransport(getFrameBuffer().array());
        org.apache.thrift.protocol.TProtocol prot = client.getProtocolFactory().getProtocol(memoryTransport);
        return (new Client(prot)).recv_updateGatewayDataStoragePreference();
      }
    }

    public void deleteGatewayComputeResourcePreference(org.apache.airavata.model.security.AuthzToken authzToken, String gatewayID, String computeResourceId, org.apache.thrift.async.AsyncMethodCallback resultHandler) throws org.apache.thrift.TException {
      checkReady();
      deleteGatewayComputeResourcePreference_call method_call = new deleteGatewayComputeResourcePreference_call(authzToken, gatewayID, computeResourceId, resultHandler, this, ___protocolFactory, ___transport);
      this.___currentMethod = method_call;
      ___manager.call(method_call);
    }

    public static class deleteGatewayComputeResourcePreference_call extends org.apache.thrift.async.TAsyncMethodCall {
      private org.apache.airavata.model.security.AuthzToken authzToken;
      private String gatewayID;
      private String computeResourceId;
      public deleteGatewayComputeResourcePreference_call(org.apache.airavata.model.security.AuthzToken authzToken, String gatewayID, String computeResourceId, org.apache.thrift.async.AsyncMethodCallback resultHandler, org.apache.thrift.async.TAsyncClient client, org.apache.thrift.protocol.TProtocolFactory protocolFactory, org.apache.thrift.transport.TNonblockingTransport transport) throws org.apache.thrift.TException {
        super(client, protocolFactory, transport, resultHandler, false);
        this.authzToken = authzToken;
        this.gatewayID = gatewayID;
        this.computeResourceId = computeResourceId;
      }

      public void write_args(org.apache.thrift.protocol.TProtocol prot) throws org.apache.thrift.TException {
        prot.writeMessageBegin(new org.apache.thrift.protocol.TMessage("deleteGatewayComputeResourcePreference", org.apache.thrift.protocol.TMessageType.CALL, 0));
        deleteGatewayComputeResourcePreference_args args = new deleteGatewayComputeResourcePreference_args();
        args.setAuthzToken(authzToken);
        args.setGatewayID(gatewayID);
        args.setComputeResourceId(computeResourceId);
        args.write(prot);
        prot.writeMessageEnd();
      }

      public boolean getResult() throws org.apache.airavata.model.error.InvalidRequestException, org.apache.airavata.model.error.AiravataClientException, org.apache.airavata.model.error.AiravataSystemException, org.apache.airavata.model.error.AuthorizationException, org.apache.thrift.TException {
        if (getState() != org.apache.thrift.async.TAsyncMethodCall.State.RESPONSE_READ) {
          throw new IllegalStateException("Method call not finished!");
        }
        org.apache.thrift.transport.TMemoryInputTransport memoryTransport = new org.apache.thrift.transport.TMemoryInputTransport(getFrameBuffer().array());
        org.apache.thrift.protocol.TProtocol prot = client.getProtocolFactory().getProtocol(memoryTransport);
        return (new Client(prot)).recv_deleteGatewayComputeResourcePreference();
      }
    }

    public void deleteGatewayDataStoragePreference(org.apache.airavata.model.security.AuthzToken authzToken, String gatewayID, String dataMoveId, org.apache.thrift.async.AsyncMethodCallback resultHandler) throws org.apache.thrift.TException {
      checkReady();
      deleteGatewayDataStoragePreference_call method_call = new deleteGatewayDataStoragePreference_call(authzToken, gatewayID, dataMoveId, resultHandler, this, ___protocolFactory, ___transport);
      this.___currentMethod = method_call;
      ___manager.call(method_call);
    }

    public static class deleteGatewayDataStoragePreference_call extends org.apache.thrift.async.TAsyncMethodCall {
      private org.apache.airavata.model.security.AuthzToken authzToken;
      private String gatewayID;
      private String dataMoveId;
      public deleteGatewayDataStoragePreference_call(org.apache.airavata.model.security.AuthzToken authzToken, String gatewayID, String dataMoveId, org.apache.thrift.async.AsyncMethodCallback resultHandler, org.apache.thrift.async.TAsyncClient client, org.apache.thrift.protocol.TProtocolFactory protocolFactory, org.apache.thrift.transport.TNonblockingTransport transport) throws org.apache.thrift.TException {
        super(client, protocolFactory, transport, resultHandler, false);
        this.authzToken = authzToken;
        this.gatewayID = gatewayID;
        this.dataMoveId = dataMoveId;
      }

      public void write_args(org.apache.thrift.protocol.TProtocol prot) throws org.apache.thrift.TException {
        prot.writeMessageBegin(new org.apache.thrift.protocol.TMessage("deleteGatewayDataStoragePreference", org.apache.thrift.protocol.TMessageType.CALL, 0));
        deleteGatewayDataStoragePreference_args args = new deleteGatewayDataStoragePreference_args();
        args.setAuthzToken(authzToken);
        args.setGatewayID(gatewayID);
        args.setDataMoveId(dataMoveId);
        args.write(prot);
        prot.writeMessageEnd();
      }

      public boolean getResult() throws org.apache.airavata.model.error.InvalidRequestException, org.apache.airavata.model.error.AiravataClientException, org.apache.airavata.model.error.AiravataSystemException, org.apache.airavata.model.error.AuthorizationException, org.apache.thrift.TException {
        if (getState() != org.apache.thrift.async.TAsyncMethodCall.State.RESPONSE_READ) {
          throw new IllegalStateException("Method call not finished!");
        }
        org.apache.thrift.transport.TMemoryInputTransport memoryTransport = new org.apache.thrift.transport.TMemoryInputTransport(getFrameBuffer().array());
        org.apache.thrift.protocol.TProtocol prot = client.getProtocolFactory().getProtocol(memoryTransport);
        return (new Client(prot)).recv_deleteGatewayDataStoragePreference();
      }
    }

    public void getAllWorkflows(org.apache.airavata.model.security.AuthzToken authzToken, String gatewayId, org.apache.thrift.async.AsyncMethodCallback resultHandler) throws org.apache.thrift.TException {
      checkReady();
      getAllWorkflows_call method_call = new getAllWorkflows_call(authzToken, gatewayId, resultHandler, this, ___protocolFactory, ___transport);
      this.___currentMethod = method_call;
      ___manager.call(method_call);
    }

    public static class getAllWorkflows_call extends org.apache.thrift.async.TAsyncMethodCall {
      private org.apache.airavata.model.security.AuthzToken authzToken;
      private String gatewayId;
      public getAllWorkflows_call(org.apache.airavata.model.security.AuthzToken authzToken, String gatewayId, org.apache.thrift.async.AsyncMethodCallback resultHandler, org.apache.thrift.async.TAsyncClient client, org.apache.thrift.protocol.TProtocolFactory protocolFactory, org.apache.thrift.transport.TNonblockingTransport transport) throws org.apache.thrift.TException {
        super(client, protocolFactory, transport, resultHandler, false);
        this.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("getAllWorkflows", org.apache.thrift.protocol.TMessageType.CALL, 0));
        getAllWorkflows_args args = new getAllWorkflows_args();
        args.setAuthzToken(authzToken);
        args.setGatewayId(gatewayId);
        args.write(prot);
        prot.writeMessageEnd();
      }

      public List<String> getResult() throws org.apache.airavata.model.error.InvalidRequestException, org.apache.airavata.model.error.AiravataClientException, org.apache.airavata.model.error.AiravataSystemException, org.apache.airavata.model.error.AuthorizationException, org.apache.thrift.TException {
        if (getState() != org.apache.thrift.async.TAsyncMethodCall.State.RESPONSE_READ) {
          throw new IllegalStateException("Method call not finished!");
        }
        org.apache.thrift.transport.TMemoryInputTransport memoryTransport = new org.apache.thrift.transport.TMemoryInputTransport(getFrameBuffer().array());
        org.apache.thrift.protocol.TProtocol prot = client.getProtocolFactory().getProtocol(memoryTransport);
        return (new Client(prot)).recv_getAllWorkflows();
      }
    }

    public void getWorkflow(org.apache.airavata.model.security.AuthzToken authzToken, String workflowTemplateId, org.apache.thrift.async.AsyncMethodCallback resultHandler) throws org.apache.thrift.TException {
      checkReady();
      getWorkflow_call method_call = new getWorkflow_call(authzToken, workflowTemplateId, resultHandler, this, ___protocolFactory, ___transport);
      this.___currentMethod = method_call;
      ___manager.call(method_call);
    }

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

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

      public org.apache.airavata.model.Workflow getResult() throws org.apache.airavata.model.error.InvalidRequestException, org.apache.airavata.model.error.AiravataClientException, org.apache.airavata.model.error.AiravataSystemException, org.apache.airavata.model.error.AuthorizationException, org.apache.thrift.TException {
        if (getState() != org.apache.thrift.async.TAsyncMethodCall.State.RESPONSE_READ) {
          throw new IllegalStateException("Method call not finished!");
        }
        org.apache.thrift.transport.TMemoryInputTransport memoryTransport = new org.apache.thrift.transport.TMemoryInputTransport(getFrameBuffer().array());
        org.apache.thrift.protocol.TProtocol prot = client.getProtocolFactory().getProtocol(memoryTransport);
        return (new Client(prot)).recv_getWorkflow();
      }
    }

    public void deleteWorkflow(org.apache.airavata.model.security.AuthzToken authzToken, String workflowTemplateId, org.apache.thrift.async.AsyncMethodCallback resultHandler) throws org.apache.thrift.TException {
      checkReady();
      deleteWorkflow_call method_call = new deleteWorkflow_call(authzToken, workflowTemplateId, resultHandler, this, ___protocolFactory, ___transport);
      this.___currentMethod = method_call;
      ___manager.call(method_call);
    }

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

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

      public void getResult() throws org.apache.airavata.model.error.InvalidRequestException, org.apache.airavata.model.error.AiravataClientException, org.apache.airavata.model.error.AiravataSystemException, org.apache.airavata.model.error.AuthorizationException, org.apache.thrift.TException {
        if (getState() != org.apache.thrift.async.TAsyncMethodCall.State.RESPONSE_READ) {
          throw new IllegalStateException("Method call not finished!");
        }
        org.apache.thrift.transport.TMemoryInputTransport memoryTransport = new org.apache.thrift.transport.TMemoryInputTransport(getFrameBuffer().array());
        org.apache.thrift.protocol.TProtocol prot = client.getProtocolFactory().getProtocol(memoryTransport);
        (new Client(prot)).recv_deleteWorkflow();
      }
    }

    public void registerWorkflow(org.apache.airavata.model.security.AuthzToken authzToken, String gatewayId, org.apache.airavata.model.Workflow workflow, org.apache.thrift.async.AsyncMethodCallback resultHandler) throws org.apache.thrift.TException {
      checkReady();
      registerWorkflow_call method_call = new registerWorkflow_call(authzToken, gatewayId, workflow, resultHandler, this, ___protocolFactory, ___transport);
      this.___currentMethod = method_call;
      ___manager.call(method_call);
    }

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

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

      public String getResult() throws org.apache.airavata.model.error.InvalidRequestException, org.apache.airavata.model.error.AiravataClientException, org.apache.airavata.model.error.AiravataSystemException, org.apache.airavata.model.error.AuthorizationException, org.apache.thrift.TException {
        if (getState() != org.apache.thrift.async.TAsyncMethodCall.State.RESPONSE_READ) {
          throw new IllegalStateException("Method call not finished!");
        }
        org.apache.thrift.transport.TMemoryInputTransport memoryTransport = new org.apache.thrift.transport.TMemoryInputTransport(getFrameBuffer().array());
        org.apache.thrift.protocol.TProtocol prot = client.getProtocolFactory().getProtocol(memoryTransport);
        return (new Client(prot)).recv_registerWorkflow();
      }
    }

    public void updateWorkflow(org.apache.airavata.model.security.AuthzToken authzToken, String workflowTemplateId, org.apache.airavata.model.Workflow workflow, org.apache.thrift.async.AsyncMethodCallback resultHandler) throws org.apache.thrift.TException {
      checkReady();
      updateWorkflow_call method_call = new updateWorkflow_call(authzToken, workflowTemplateId, workflow, resultHandler, this, ___protocolFactory, ___transport);
      this.___currentMethod = method_call;
      ___manager.call(method_call);
    }

    public static class updateWorkflow_call extends org.apache.thrift.async.TAsyncMethodCall {
      private org.apache.airavata.model.security.AuthzToken authzToken;
      private String workflowTemplateId;
      private org.apache.airavata.model.Workflow workflow;
      public updateWorkflow_call(org.apache.airavata.model.security.AuthzToken authzToken, String workflowTemplateId, org.apache.airavata.model.Workflow workflow, org.apache.thrift.async.AsyncMethodCallback resultHandler, org.apache.thrift.async.TAsyncClient client, org.apache.thrift.protocol.TProtocolFactory protocolFactory, org.apache.thrift.transport.TNonblockingTransport transport) throws org.apache.thrift.TException {
        super(client, protocolFactory, transport, resultHandler, false);
        this.authzToken = authzToken;
        this.workflowTemplateId = workflowTemplateId;
        this.workflow = workflow;
      }

      public void write_args(org.apache.thrift.protocol.TProtocol prot) throws org.apache.thrift.TException {
        prot.writeMessageBegin(new org.apache.thrift.protocol.TMessage("updateWorkflow", org.apache.thrift.protocol.TMessageType.CALL, 0));
        updateWorkflow_args args = new updateWorkflow_args();
        args.setAuthzToken(authzToken);
        args.setWorkflowTemplateId(workflowTemplateId);
        args.setWorkflow(workflow);
        args.write(prot);
        prot.writeMessageEnd();
      }

      public void getResult() throws org.apache.airavata.model.error.InvalidRequestException, org.apache.airavata.model.error.AiravataClientException, org.apache.airavata.model.error.AiravataSystemException, org.apache.airavata.model.error.AuthorizationException, org.apache.thrift.TException {
        if (getState() != org.apache.thrift.async.TAsyncMethodCall.State.RESPONSE_READ) {
          throw new IllegalStateException("Method call not finished!");
        }
        org.apache.thrift.transport.TMemoryInputTransport memoryTransport = new org.apache.thrift.transport.TMemoryInputTransport(getFrameBuffer().array());
        org.apache.thrift.protocol.TProtocol prot = client.getProtocolFactory().getProtocol(memoryTransport);
        (new Client(prot)).recv_updateWorkflow();
      }
    }

    public void getWorkflowTemplateId(org.apache.airavata.model.security.AuthzToken authzToken, String workflowName, org.apache.thrift.async.AsyncMethodCallback resultHandler) throws org.apache.thrift.TException {
      checkReady();
      getWorkflowTemplateId_call method_call = new getWorkflowTemplateId_call(authzToken, workflowName, resultHandler, this, ___protocolFactory, ___transport);
      this.___currentMethod = method_call;
      ___manager.call(method_call);
    }

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

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

      public String getResult() throws org.apache.airavata.model.error.InvalidRequestException, org.apache.airavata.model.error.AiravataClientException, org.apache.airavata.model.error.AiravataSystemException, org.apache.airavata.model.error.AuthorizationException, org.apache.thrift.TException {
        if (getState() != org.apache.thrift.async.TAsyncMethodCall.State.RESPONSE_READ) {
          throw new IllegalStateException("Method call not finished!");
        }
        org.apache.thrift.transport.TMemoryInputTransport memoryTransport = new org.apache.thrift.transport.TMemoryInputTransport(getFrameBuffer().array());
        org.apache.thrift.protocol.TProtocol prot = client.getProtocolFactory().getProtocol(memoryTransport);
        return (new Client(prot)).recv_getWorkflowTemplateId();
      }
    }

    public void isWorkflowExistWithName(org.apache.airavata.model.security.AuthzToken authzToken, String workflowName, org.apache.thrift.async.AsyncMethodCallback resultHandler) throws org.apache.thrift.TException {
      checkReady();
      isWorkflowExistWithName_call method_call = new isWorkflowExistWithName_call(authzToken, workflowName, resultHandler, this, ___protocolFactory, ___transport);
      this.___currentMethod = method_call;
      ___manager.call(method_call);
    }

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

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

      public boolean getResult() throws org.apache.airavata.model.error.InvalidRequestException, org.apache.airavata.model.error.AiravataClientException, org.apache.airavata.model.error.AiravataSystemException, org.apache.airavata.model.error.AuthorizationException, org.apache.thrift.TException {
        if (getState() != org.apache.thrift.async.TAsyncMethodCall.State.RESPONSE_READ) {
          throw new IllegalStateException("Method call not finished!");
        }
        org.apache.thrift.transport.TMemoryInputTransport memoryTransport = new org.apache.thrift.transport.TMemoryInputTransport(getFrameBuffer().array());
        org.apache.thrift.protocol.TProtocol prot = client.getProtocolFactory().getProtocol(memoryTransport);
        return (new Client(prot)).recv_isWorkflowExistWithName();
      }
    }

  }

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

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

    private static <I extends Iface> Map<String,  org.apache.thrift.ProcessFunction<I, ? extends  org.apache.thrift.TBase>> getProcessMap(Map<String,  org.apache.thrift.ProcessFunction<I, ? extends  org.apache.thrift.TBase>> processMap) {
      processMap.put("getAPIVersion", new getAPIVersion());
      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("generateAndRegisterSSHKeys", new generateAndRegisterSSHKeys());
      processMap.put("getSSHPubKey", new getSSHPubKey());
      processMap.put("getAllUserSSHPubKeys", new getAllUserSSHPubKeys());
      processMap.put("createProject", new createProject());
      processMap.put("updateProject", new updateProject());
      processMap.put("getProject", new getProject());
      processMap.put("deleteProject", new deleteProject());
      processMap.put("getUserProjects", new getUserProjects());
      processMap.put("searchProjectsByProjectName", new searchProjectsByProjectName());
      processMap.put("searchProjectsByProjectDesc", new searchProjectsByProjectDesc());
      processMap.put("searchExperimentsByName", new searchExperimentsByName());
      processMap.put("searchExperimentsByDesc", new searchExperimentsByDesc());
      processMap.put("searchExperimentsByApplication", new searchExperimentsByApplication());
      processMap.put("searchExperimentsByStatus", new searchExperimentsByStatus());
      processMap.put("searchExperimentsByCreationTime", new searchExperimentsByCreationTime());
      processMap.put("searchExperiments", new searchExperiments());
      processMap.put("getExperimentStatistics", new getExperimentStatistics());
      processMap.put("getExperimentsInProject", new getExperimentsInProject());
      processMap.put("getUserExperiments", new getUserExperiments());
      processMap.put("createExperiment", new createExperiment());
      processMap.put("deleteExperiment", new deleteExperiment());
      processMap.put("getExperiment", new getExperiment());
      processMap.put("getDetailedExperimentTree", new getDetailedExperimentTree());
      processMap.put("updateExperiment", new updateExperiment());
      processMap.put("updateExperimentConfiguration", new updateExperimentConfiguration());
      processMap.put("updateResourceScheduleing", new updateResourceScheduleing());
      processMap.put("validateExperiment", new validateExperiment());
      processMap.put("launchExperiment", new launchExperiment());
      processMap.put("getExperimentStatus", new getExperimentStatus());
      processMap.put("getExperimentOutputs", new getExperimentOutputs());
      processMap.put("getIntermediateOutputs", new getIntermediateOutputs());
      processMap.put("getJobStatuses", new getJobStatuses());
      processMap.put("getJobDetails", new getJobDetails());
      processMap.put("cloneExperiment", new cloneExperiment());
      processMap.put("terminateExperiment", new terminateExperiment());
      processMap.put("registerApplicationModule", new registerApplicationModule());
      processMap.put("getApplicationModule", new getApplicationModule());
      processMap.put("updateApplicationModule", new updateApplicationModule());
      processMap.put("getAllAppModules", new getAllAppModules());
      processMap.put("deleteApplicationModule", new deleteApplicationModule());
      processMap.put("registerApplicationDeployment", new registerApplicationDeployment());
      processMap.put("getApplicationDeployment", new getApplicationDeployment());
      processMap.put("updateApplicationDeployment", new updateApplicationDeployment());
      processMap.put("deleteApplicationDeployment", new deleteApplicationDeployment());
      processMap.put("getAllApplicationDeployments", new getAllApplicationDeployments());
      processMap.put("getAppModuleDeployedResources", new getAppModuleDeployedResources());
      processMap.put("registerApplicationInterface", new registerApplicationInterface());
      processMap.put("getApplicationInterface", new getApplicationInterface());
      processMap.put("updateApplicationInterface", new updateApplicationInterface());
      processMap.put("deleteApplicationInterface", new deleteApplicationInterface());
      processMap.put("getAllApplicationInterfaceNames", new getAllApplicationInterfaceNames());
      processMap.put("getAllApplicationInterfaces", new getAllApplicationInterfaces());
      processMap.put("getApplicationInputs", new getApplicationInputs());
      processMap.put("getApplicationOutputs", new getApplicationOutputs());
      processMap.put("getAvailableAppInterfaceComputeResources", new getAvailableAppInterfaceComputeResources());
      processMap.put("registerComputeResource", new registerComputeResource());
      processMap.put("getComputeResource", new getComputeResource());
      processMap.put("getAllComputeResourceNames", new getAllComputeResourceNames());
      processMap.put("updateComputeResource", new updateComputeResource());
      processMap.put("deleteComputeResource", new deleteComputeResource());
      processMap.put("addLocalSubmissionDetails", new addLocalSubmissionDetails());
      processMap.put("updateLocalSubmissionDetails", new updateLocalSubmissionDetails());
      processMap.put("getLocalJobSubmission", new getLocalJobSubmission());
      processMap.put("addSSHJobSubmissionDetails", new addSSHJobSubmissionDetails());
      processMap.put("addSSHForkJobSubmissionDetails", new addSSHForkJobSubmissionDetails());
      processMap.put("getSSHJobSubmission", new getSSHJobSubmission());
      processMap.put("addUNICOREJobSubmissionDetails", new addUNICOREJobSubmissionDetails());
      processMap.put("getUnicoreJobSubmission", new getUnicoreJobSubmission());
      processMap.put("addCloudJobSubmissionDetails", new addCloudJobSubmissionDetails());
      processMap.put("getCloudJobSubmission", new getCloudJobSubmission());
      processMap.put("updateSSHJobSubmissionDetails", new updateSSHJobSubmissionDetails());
      processMap.put("updateCloudJobSubmissionDetails", new updateCloudJobSubmissionDetails());
      processMap.put("updateUnicoreJobSubmissionDetails", new updateUnicoreJobSubmissionDetails());
      processMap.put("addLocalDataMovementDetails", new addLocalDataMovementDetails());
      processMap.put("updateLocalDataMovementDetails", new updateLocalDataMovementDetails());
      processMap.put("getLocalDataMovement", new getLocalDataMovement());
      processMap.put("addSCPDataMovementDetails", new addSCPDataMovementDetails());
      processMap.put("updateSCPDataMovementDetails", new updateSCPDataMovementDetails());
      processMap.put("getSCPDataMovement", new getSCPDataMovement());
      processMap.put("addUnicoreDataMovementDetails", new addUnicoreDataMovementDetails());
      processMap.put("updateUnicoreDataMovementDetails", new updateUnicoreDataMovementDetails());
      processMap.put("getUnicoreDataMovement", new getUnicoreDataMovement());
      processMap.put("addGridFTPDataMovementDetails", new addGridFTPDataMovementDetails());
      processMap.put("updateGridFTPDataMovementDetails", new updateGridFTPDataMovementDetails());
      processMap.put("getGridFTPDataMovement", new getGridFTPDataMovement());
      processMap.put("changeJobSubmissionPriority", new changeJobSubmissionPriority());
      processMap.put("changeDataMovementPriority", new changeDataMovementPriority());
      processMap.put("changeJobSubmissionPriorities", new changeJobSubmissionPriorities());
      processMap.put("changeDataMovementPriorities", new changeDataMovementPriorities());
      processMap.put("deleteJobSubmissionInterface", new deleteJobSubmissionInterface());
      processMap.put("deleteDataMovementInterface", new deleteDataMovementInterface());
      processMap.put("registerResourceJobManager", new registerResourceJobManager());
      processMap.put("updateResourceJobManager", new updateResourceJobManager());
      processMap.put("getResourceJobManager", new getResourceJobManager());
      processMap.put("deleteResourceJobManager", new deleteResourceJobManager());
      processMap.put("deleteBatchQueue", new deleteBatchQueue());
      processMap.put("registerGatewayResourceProfile", new registerGatewayResourceProfile());
      processMap.put("getGatewayResourceProfile", new getGatewayResourceProfile());
      processMap.put("updateGatewayResourceProfile", new updateGatewayResourceProfile());
      processMap.put("deleteGatewayResourceProfile", new deleteGatewayResourceProfile());
      processMap.put("addGatewayComputeResourcePreference", new addGatewayComputeResourcePreference());
      processMap.put("addGatewayDataStoragePreference", new addGatewayDataStoragePreference());
      processMap.put("getGatewayComputeResourcePreference", new getGatewayComputeResourcePreference());
      processMap.put("getGatewayDataStoragePreference", new getGatewayDataStoragePreference());
      processMap.put("getAllGatewayComputeResourcePreferences", new getAllGatewayComputeResourcePreferences());
      processMap.put("getAllGatewayDataStoragePreferences", new getAllGatewayDataStoragePreferences());
      processMap.put("getAllGatewayResourceProfiles", new getAllGatewayResourceProfiles());
      processMap.put("updateGatewayComputeResourcePreference", new updateGatewayComputeResourcePreference());
      processMap.put("updateGatewayDataStoragePreference", new updateGatewayDataStoragePreference());
      processMap.put("deleteGatewayComputeResourcePreference", new deleteGatewayComputeResourcePreference());
      processMap.put("deleteGatewayDataStoragePreference", new deleteGatewayDataStoragePreference());
      processMap.put("getAllWorkflows", new getAllWorkflows());
      processMap.put("getWorkflow", new getWorkflow());
      processMap.put("deleteWorkflow", new deleteWorkflow());
      processMap.put("registerWorkflow", new registerWorkflow());
      processMap.put("updateWorkflow", new updateWorkflow());
      processMap.put("getWorkflowTemplateId", new getWorkflowTemplateId());
      processMap.put("isWorkflowExistWithName", new isWorkflowExistWithName());
      return processMap;
    }

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

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

      protected boolean isOneway() {
        return false;
      }

      public getAPIVersion_result getResult(I iface, getAPIVersion_args args) throws org.apache.thrift.TException {
        getAPIVersion_result result = new getAPIVersion_result();
        try {
          result.success = iface.getAPIVersion(args.authzToken);
        } catch (org.apache.airavata.model.error.InvalidRequestException ire) {
          result.ire = ire;
        } catch (org.apache.airavata.model.error.AiravataClientException ace) {
          result.ace = ace;
        } catch (org.apache.airavata.model.error.AiravataSystemException ase) {
          result.ase = ase;
        } catch (org.apache.airavata.model.error.AuthorizationException ae) {
          result.ae = ae;
        }
        return result;
      }
    }

    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.model.error.InvalidRequestException ire) {
          result.ire = ire;
        } catch (org.apache.airavata.model.error.AiravataClientException ace) {
          result.ace = ace;
        } catch (org.apache.airavata.model.error.AiravataSystemException ase) {
          result.ase = ase;
        } 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 {
          iface.updateGateway(args.authzToken, args.gatewayId, args.updatedGateway);
        } catch (org.apache.airavata.model.error.InvalidRequestException ire) {
          result.ire = ire;
        } catch (org.apache.airavata.model.error.AiravataClientException ace) {
          result.ace = ace;
        } catch (org.apache.airavata.model.error.AiravataSystemException ase) {
          result.ase = ase;
        } 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.gatewayId);
        } catch (org.apache.airavata.model.error.InvalidRequestException ire) {
          result.ire = ire;
        } catch (org.apache.airavata.model.error.AiravataClientException ace) {
          result.ace = ace;
        } catch (org.apache.airavata.model.error.AiravataSystemException ase) {
          result.ase = ase;
        } 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.gatewayId);
          result.setSuccessIsSet(true);
        } catch (org.apache.airavata.model.error.InvalidRequestException ire) {
          result.ire = ire;
        } catch (org.apache.airavata.model.error.AiravataClientException ace) {
          result.ace = ace;
        } catch (org.apache.airavata.model.error.AiravataSystemException ase) {
          result.ase = ase;
        } 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.model.error.InvalidRequestException ire) {
          result.ire = ire;
        } catch (org.apache.airavata.model.error.AiravataClientException ace) {
          result.ace = ace;
        } catch (org.apache.airavata.model.error.AiravataSystemException ase) {
          result.ase = ase;
        } 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.model.error.InvalidRequestException ire) {
          result.ire = ire;
        } catch (org.apache.airavata.model.error.AiravataClientException ace) {
          result.ace = ace;
        } catch (org.apache.airavata.model.error.AiravataSystemException ase) {
          result.ase = ase;
        } catch (org.apache.airavata.model.error.AuthorizationException ae) {
          result.ae = ae;
        }
        return result;
      }
    }

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

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

      protected boolean isOneway() {
        return false;
      }

      public generateAndRegisterSSHKeys_result getResult(I iface, generateAndRegisterSSHKeys_args args) throws org.apache.thrift.TException {
        generateAndRegisterSSHKeys_result result = new generateAndRegisterSSHKeys_result();
        try {
          result.success = iface.generateAndRegisterSSHKeys(args.authzToken, args.gatewayId, args.userName);
        } catch (org.apache.airavata.model.error.InvalidRequestException ire) {
          result.ire = ire;
        } catch (org.apache.airavata.model.error.AiravataClientException ace) {
          result.ace = ace;
        } catch (org.apache.airavata.model.error.AiravataSystemException ase) {
          result.ase = ase;
        }
        return result;
      }
    }

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

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

      protected boolean isOneway() {
        return false;
      }

      public getSSHPubKey_result getResult(I iface, getSSHPubKey_args args) throws org.apache.thrift.TException {
        getSSHPubKey_result result = new getSSHPubKey_result();
        try {
          result.success = iface.getSSHPubKey(args.authzToken, args.airavataCredStoreToken, args.gatewayId);
        } catch (org.apache.airavata.model.error.InvalidRequestException ire) {
          result.ire = ire;
        } catch (org.apache.airavata.model.error.AiravataClientException ace) {
          result.ace = ace;
        } catch (org.apache.airavata.model.error.AiravataSystemException ase) {
          result.ase = ase;
        }
        return result;
      }
    }

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

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

      protected boolean isOneway() {
        return false;
      }

      public getAllUserSSHPubKeys_result getResult(I iface, getAllUserSSHPubKeys_args args) throws org.apache.thrift.TException {
        getAllUserSSHPubKeys_result result = new getAllUserSSHPubKeys_result();
        try {
          result.success = iface.getAllUserSSHPubKeys(args.authzToken, args.userName);
        } catch (org.apache.airavata.model.error.InvalidRequestException ire) {
          result.ire = ire;
        } catch (org.apache.airavata.model.error.AiravataClientException ace) {
          result.ace = ace;
        } catch (org.apache.airavata.model.error.AiravataSystemException ase) {
          result.ase = ase;
        }
        return result;
      }
    }

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

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

      protected boolean isOneway() {
        return false;
      }

      public createProject_result getResult(I iface, createProject_args args) throws org.apache.thrift.TException {
        createProject_result result = new createProject_result();
        try {
          result.success = iface.createProject(args.authzToken, args.gatewayId, args.project);
        } catch (org.apache.airavata.model.error.InvalidRequestException ire) {
          result.ire = ire;
        } catch (org.apache.airavata.model.error.AiravataClientException ace) {
          result.ace = ace;
        } catch (org.apache.airavata.model.error.AiravataSystemException ase) {
          result.ase = ase;
        } catch (org.apache.airavata.model.error.AuthorizationException ae) {
          result.ae = ae;
        }
        return result;
      }
    }

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

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

      protected boolean isOneway() {
        return false;
      }

      public updateProject_result getResult(I iface, updateProject_args args) throws org.apache.thrift.TException {
        updateProject_result result = new updateProject_result();
        try {
          iface.updateProject(args.authzToken, args.projectId, args.updatedProject);
        } catch (org.apache.airavata.model.error.InvalidRequestException ire) {
          result.ire = ire;
        } catch (org.apache.airavata.model.error.AiravataClientException ace) {
          result.ace = ace;
        } catch (org.apache.airavata.model.error.AiravataSystemException ase) {
          result.ase = ase;
        } catch (org.apache.airavata.model.error.ProjectNotFoundException pnfe) {
          result.pnfe = pnfe;
        } catch (org.apache.airavata.model.error.AuthorizationException ae) {
          result.ae = ae;
        }
        return result;
      }
    }

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

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

      protected boolean isOneway() {
        return false;
      }

      public getProject_result getResult(I iface, getProject_args args) throws org.apache.thrift.TException {
        getProject_result result = new getProject_result();
        try {
          result.success = iface.getProject(args.authzToken, args.projectId);
        } catch (org.apache.airavata.model.error.InvalidRequestException ire) {
          result.ire = ire;
        } catch (org.apache.airavata.model.error.AiravataClientException ace) {
          result.ace = ace;
        } catch (org.apache.airavata.model.error.AiravataSystemException ase) {
          result.ase = ase;
        } catch (org.apache.airavata.model.error.ProjectNotFoundException pnfe) {
          result.pnfe = pnfe;
        } catch (org.apache.airavata.model.error.AuthorizationException ae) {
          result.ae = ae;
        }
        return result;
      }
    }

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

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

      protected boolean isOneway() {
        return false;
      }

      public deleteProject_result getResult(I iface, deleteProject_args args) throws org.apache.thrift.TException {
        deleteProject_result result = new deleteProject_result();
        try {
          result.success = iface.deleteProject(args.authzToken, args.projectId);
          result.setSuccessIsSet(true);
        } catch (org.apache.airavata.model.error.InvalidRequestException ire) {
          result.ire = ire;
        } catch (org.apache.airavata.model.error.AiravataClientException ace) {
          result.ace = ace;
        } catch (org.apache.airavata.model.error.AiravataSystemException ase) {
          result.ase = ase;
        } catch (org.apache.airavata.model.error.ProjectNotFoundException pnfe) {
          result.pnfe = pnfe;
        } catch (org.apache.airavata.model.error.AuthorizationException ae) {
          result.ae = ae;
        }
        return result;
      }
    }

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

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

      protected boolean isOneway() {
        return false;
      }

      public getUserProjects_result getResult(I iface, getUserProjects_args args) throws org.apache.thrift.TException {
        getUserProjects_result result = new getUserProjects_result();
        try {
          result.success = iface.getUserProjects(args.authzToken, args.gatewayId, args.userName, args.limit, args.offset);
        } catch (org.apache.airavata.model.error.InvalidRequestException ire) {
          result.ire = ire;
        } catch (org.apache.airavata.model.error.AiravataClientException ace) {
          result.ace = ace;
        } catch (org.apache.airavata.model.error.AiravataSystemException ase) {
          result.ase = ase;
        } catch (org.apache.airavata.model.error.AuthorizationException ae) {
          result.ae = ae;
        }
        return result;
      }
    }

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

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

      protected boolean isOneway() {
        return false;
      }

      public searchProjectsByProjectName_result getResult(I iface, searchProjectsByProjectName_args args) throws org.apache.thrift.TException {
        searchProjectsByProjectName_result result = new searchProjectsByProjectName_result();
        try {
          result.success = iface.searchProjectsByProjectName(args.authzToken, args.gatewayId, args.userName, args.projectName, args.limit, args.offset);
        } catch (org.apache.airavata.model.error.InvalidRequestException ire) {
          result.ire = ire;
        } catch (org.apache.airavata.model.error.AiravataClientException ace) {
          result.ace = ace;
        } catch (org.apache.airavata.model.error.AiravataSystemException ase) {
          result.ase = ase;
        } catch (org.apache.airavata.model.error.AuthorizationException ae) {
          result.ae = ae;
        }
        return result;
      }
    }

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

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

      protected boolean isOneway() {
        return false;
      }

      public searchProjectsByProjectDesc_result getResult(I iface, searchProjectsByProjectDesc_args args) throws org.apache.thrift.TException {
        searchProjectsByProjectDesc_result result = new searchProjectsByProjectDesc_result();
        try {
          result.success = iface.searchProjectsByProjectDesc(args.authzToken, args.gatewayId, args.userName, args.description, args.limit, args.offset);
        } catch (org.apache.airavata.model.error.InvalidRequestException ire) {
          result.ire = ire;
        } catch (org.apache.airavata.model.error.AiravataClientException ace) {
          result.ace = ace;
        } catch (org.apache.airavata.model.error.AiravataSystemException ase) {
          result.ase = ase;
        } catch (org.apache.airavata.model.error.AuthorizationException ae) {
          result.ae = ae;
        }
        return result;
      }
    }

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

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

      protected boolean isOneway() {
        return false;
      }

      public searchExperimentsByName_result getResult(I iface, searchExperimentsByName_args args) throws org.apache.thrift.TException {
        searchExperimentsByName_result result = new searchExperimentsByName_result();
        try {
          result.success = iface.searchExperimentsByName(args.authzToken, args.gatewayId, args.userName, args.expName, args.limit, args.offset);
        } catch (org.apache.airavata.model.error.InvalidRequestException ire) {
          result.ire = ire;
        } catch (org.apache.airavata.model.error.AiravataClientException ace) {
          result.ace = ace;
        } catch (org.apache.airavata.model.error.AiravataSystemException ase) {
          result.ase = ase;
        } catch (org.apache.airavata.model.error.AuthorizationException ae) {
          result.ae = ae;
        }
        return result;
      }
    }

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

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

      protected boolean isOneway() {
        return false;
      }

      public searchExperimentsByDesc_result getResult(I iface, searchExperimentsByDesc_args args) throws org.apache.thrift.TException {
        searchExperimentsByDesc_result result = new searchExperimentsByDesc_result();
        try {
          result.success = iface.searchExperimentsByDesc(args.authzToken, args.gatewayId, args.userName, args.description, args.limit, args.offset);
        } catch (org.apache.airavata.model.error.InvalidRequestException ire) {
          result.ire = ire;
        } catch (org.apache.airavata.model.error.AiravataClientException ace) {
          result.ace = ace;
        } catch (org.apache.airavata.model.error.AiravataSystemException ase) {
          result.ase = ase;
        } catch (org.apache.airavata.model.error.AuthorizationException ae) {
          result.ae = ae;
        }
        return result;
      }
    }

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

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

      protected boolean isOneway() {
        return false;
      }

      public searchExperimentsByApplication_result getResult(I iface, searchExperimentsByApplication_args args) throws org.apache.thrift.TException {
        searchExperimentsByApplication_result result = new searchExperimentsByApplication_result();
        try {
          result.success = iface.searchExperimentsByApplication(args.authzToken, args.gatewayId, args.userName, args.applicationId, args.limit, args.offset);
        } catch (org.apache.airavata.model.error.InvalidRequestException ire) {
          result.ire = ire;
        } catch (org.apache.airavata.model.error.AiravataClientException ace) {
          result.ace = ace;
        } catch (org.apache.airavata.model.error.AiravataSystemException ase) {
          result.ase = ase;
        } catch (org.apache.airavata.model.error.AuthorizationException ae) {
          result.ae = ae;
        }
        return result;
      }
    }

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

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

      protected boolean isOneway() {
        return false;
      }

      public searchExperimentsByStatus_result getResult(I iface, searchExperimentsByStatus_args args) throws org.apache.thrift.TException {
        searchExperimentsByStatus_result result = new searchExperimentsByStatus_result();
        try {
          result.success = iface.searchExperimentsByStatus(args.authzToken, args.gatewayId, args.userName, args.experimentState, args.limit, args.offset);
        } catch (org.apache.airavata.model.error.InvalidRequestException ire) {
          result.ire = ire;
        } catch (org.apache.airavata.model.error.AiravataClientException ace) {
          result.ace = ace;
        } catch (org.apache.airavata.model.error.AiravataSystemException ase) {
          result.ase = ase;
        } catch (org.apache.airavata.model.error.AuthorizationException ae) {
          result.ae = ae;
        }
        return result;
      }
    }

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

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

      protected boolean isOneway() {
        return false;
      }

      public searchExperimentsByCreationTime_result getResult(I iface, searchExperimentsByCreationTime_args args) throws org.apache.thrift.TException {
        searchExperimentsByCreationTime_result result = new searchExperimentsByCreationTime_result();
        try {
          result.success = iface.searchExperimentsByCreationTime(args.authzToken, args.gatewayId, args.userName, args.fromTime, args.toTime, args.limit, args.offset);
        } catch (org.apache.airavata.model.error.InvalidRequestException ire) {
          result.ire = ire;
        } catch (org.apache.airavata.model.error.AiravataClientException ace) {
          result.ace = ace;
        } catch (org.apache.airavata.model.error.AiravataSystemException ase) {
          result.ase = ase;
        } catch (org.apache.airavata.model.error.AuthorizationException ae) {
          result.ae = ae;
        }
        return result;
      }
    }

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

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

      protected boolean isOneway() {
        return false;
      }

      public searchExperiments_result getResult(I iface, searchExperiments_args args) throws org.apache.thrift.TException {
        searchExperiments_result result = new searchExperiments_result();
        try {
          result.success = iface.searchExperiments(args.authzToken, args.gatewayId, args.userName, args.filters, args.limit, args.offset);
        } catch (org.apache.airavata.model.error.InvalidRequestException ire) {
          result.ire = ire;
        } catch (org.apache.airavata.model.error.AiravataClientException ace) {
          result.ace = ace;
        } catch (org.apache.airavata.model.error.AiravataSystemException ase) {
          result.ase = ase;
        } catch (org.apache.airavata.model.error.AuthorizationException ae) {
          result.ae = ae;
        }
        return result;
      }
    }

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

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

      protected boolean isOneway() {
        return false;
      }

      public getExperimentStatistics_result getResult(I iface, getExperimentStatistics_args args) throws org.apache.thrift.TException {
        getExperimentStatistics_result result = new getExperimentStatistics_result();
        try {
          result.success = iface.getExperimentStatistics(args.authzToken, args.gatewayId, args.fromTime, args.toTime);
        } catch (org.apache.airavata.model.error.InvalidRequestException ire) {
          result.ire = ire;
        } catch (org.apache.airavata.model.error.AiravataClientException ace) {
          result.ace = ace;
        } catch (org.apache.airavata.model.error.AiravataSystemException ase) {
          result.ase = ase;
        } catch (org.apache.airavata.model.error.AuthorizationException ae) {
          result.ae = ae;
        }
        return result;
      }
    }

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

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

      protected boolean isOneway() {
        return false;
      }

      public getExperimentsInProject_result getResult(I iface, getExperimentsInProject_args args) throws org.apache.thrift.TException {
        getExperimentsInProject_result result = new getExperimentsInProject_result();
        try {
          result.success = iface.getExperimentsInProject(args.authzToken, args.projectId, args.limit, args.offset);
        } catch (org.apache.airavata.model.error.InvalidRequestException ire) {
          result.ire = ire;
        } catch (org.apache.airavata.model.error.AiravataClientException ace) {
          result.ace = ace;
        } catch (org.apache.airavata.model.error.AiravataSystemException ase) {
          result.ase = ase;
        } catch (org.apache.airavata.model.error.ProjectNotFoundException pnfe) {
          result.pnfe = pnfe;
        } catch (org.apache.airavata.model.error.AuthorizationException ae) {
          result.ae = ae;
        }
        return result;
      }
    }

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

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

      protected boolean isOneway() {
        return false;
      }

      public getUserExperiments_result getResult(I iface, getUserExperiments_args args) throws org.apache.thrift.TException {
        getUserExperiments_result result = new getUserExperiments_result();
        try {
          result.success = iface.getUserExperiments(args.authzToken, args.gatewayId, args.userName, args.limit, args.offset);
        } catch (org.apache.airavata.model.error.InvalidRequestException ire) {
          result.ire = ire;
        } catch (org.apache.airavata.model.error.AiravataClientException ace) {
          result.ace = ace;
        } catch (org.apache.airavata.model.error.AiravataSystemException ase) {
          result.ase = ase;
        } catch (org.apache.airavata.model.error.AuthorizationException ae) {
          result.ae = ae;
        }
        return result;
      }
    }

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

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

      protected boolean isOneway() {
        return false;
      }

      public createExperiment_result getResult(I iface, createExperiment_args args) throws org.apache.thrift.TException {
        createExperiment_result result = new createExperiment_result();
        try {
          result.success = iface.createExperiment(args.authzToken, args.gatewayId, args.experiment);
        } catch (org.apache.airavata.model.error.InvalidRequestException ire) {
          result.ire = ire;
        } catch (org.apache.airavata.model.error.AiravataClientException ace) {
          result.ace = ace;
        } catch (org.apache.airavata.model.error.AiravataSystemException ase) {
          result.ase = ase;
        } catch (org.apache.airavata.model.error.AuthorizationException ae) {
          result.ae = ae;
        }
        return result;
      }
    }

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

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

      protected boolean isOneway() {
        return false;
      }

      public deleteExperiment_result getResult(I iface, deleteExperiment_args args) throws org.apache.thrift.TException {
        deleteExperiment_result result = new deleteExperiment_result();
        try {
          result.success = iface.deleteExperiment(args.authzToken, args.experimentId);
          result.setSuccessIsSet(true);
        } catch (org.apache.airavata.model.error.InvalidRequestException ire) {
          result.ire = ire;
        } catch (org.apache.airavata.model.error.AiravataClientException ace) {
          result.ace = ace;
        } catch (org.apache.airavata.model.error.AiravataSystemException ase) {
          result.ase = ase;
        } catch (org.apache.airavata.model.error.AuthorizationException ae) {
          result.ae = ae;
        }
        return result;
      }
    }

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

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

      protected boolean isOneway() {
        return false;
      }

      public getExperiment_result getResult(I iface, getExperiment_args args) throws org.apache.thrift.TException {
        getExperiment_result result = new getExperiment_result();
        try {
          result.success = iface.getExperiment(args.authzToken, args.airavataExperimentId);
        } catch (org.apache.airavata.model.error.InvalidRequestException ire) {
          result.ire = ire;
        } catch (org.apache.airavata.model.error.ExperimentNotFoundException enf) {
          result.enf = enf;
        } catch (org.apache.airavata.model.error.AiravataClientException ace) {
          result.ace = ace;
        } catch (org.apache.airavata.model.error.AiravataSystemException ase) {
          result.ase = ase;
        } catch (org.apache.airavata.model.error.AuthorizationException ae) {
          result.ae = ae;
        }
        return result;
      }
    }

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

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

      protected boolean isOneway() {
        return false;
      }

      public getDetailedExperimentTree_result getResult(I iface, getDetailedExperimentTree_args args) throws org.apache.thrift.TException {
        getDetailedExperimentTree_result result = new getDetailedExperimentTree_result();
        try {
          result.success = iface.getDetailedExperimentTree(args.authzToken, args.airavataExperimentId);
        } catch (org.apache.airavata.model.error.InvalidRequestException ire) {
          result.ire = ire;
        } catch (org.apache.airavata.model.error.ExperimentNotFoundException enf) {
          result.enf = enf;
        } catch (org.apache.airavata.model.error.AiravataClientException ace) {
          result.ace = ace;
        } catch (org.apache.airavata.model.error.AiravataSystemException ase) {
          result.ase = ase;
        } catch (org.apache.airavata.model.error.AuthorizationException ae) {
          result.ae = ae;
        }
        return result;
      }
    }

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

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

      protected boolean isOneway() {
        return false;
      }

      public updateExperiment_result getResult(I iface, updateExperiment_args args) throws org.apache.thrift.TException {
        updateExperiment_result result = new updateExperiment_result();
        try {
          iface.updateExperiment(args.authzToken, args.airavataExperimentId, args.experiment);
        } catch (org.apache.airavata.model.error.InvalidRequestException ire) {
          result.ire = ire;
        } catch (org.apache.airavata.model.error.ExperimentNotFoundException enf) {
          result.enf = enf;
        } catch (org.apache.airavata.model.error.AiravataClientException ace) {
          result.ace = ace;
        } catch (org.apache.airavata.model.error.AiravataSystemException ase) {
          result.ase = ase;
        } catch (org.apache.airavata.model.error.AuthorizationException ae) {
          result.ae = ae;
        }
        return result;
      }
    }

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

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

      protected boolean isOneway() {
        return false;
      }

      public updateExperimentConfiguration_result getResult(I iface, updateExperimentConfiguration_args args) throws org.apache.thrift.TException {
        updateExperimentConfiguration_result result = new updateExperimentConfiguration_result();
        try {
          iface.updateExperimentConfiguration(args.authzToken, args.airavataExperimentId, args.userConfiguration);
        } catch (org.apache.airavata.model.error.AuthorizationException ae) {
          result.ae = ae;
        }
        return result;
      }
    }

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

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

      protected boolean isOneway() {
        return false;
      }

      public updateResourceScheduleing_result getResult(I iface, updateResourceScheduleing_args args) throws org.apache.thrift.TException {
        updateResourceScheduleing_result result = new updateResourceScheduleing_result();
        try {
          iface.updateResourceScheduleing(args.authzToken, args.airavataExperimentId, args.resourceScheduling);
        } catch (org.apache.airavata.model.error.AuthorizationException ae) {
          result.ae = ae;
        }
        return result;
      }
    }

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

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

      protected boolean isOneway() {
        return false;
      }

      public validateExperiment_result getResult(I iface, validateExperiment_args args) throws org.apache.thrift.TException {
        validateExperiment_result result = new validateExperiment_result();
        try {
          result.success = iface.validateExperiment(args.authzToken, args.airavataExperimentId);
          result.setSuccessIsSet(true);
        } catch (org.apache.airavata.model.error.InvalidRequestException ire) {
          result.ire = ire;
        } catch (org.apache.airavata.model.error.ExperimentNotFoundException enf) {
          result.enf = enf;
        } catch (org.apache.airavata.model.error.AiravataClientException ace) {
          result.ace = ace;
        } catch (org.apache.airavata.model.error.AiravataSystemException ase) {
          result.ase = ase;
        } catch (org.apache.airavata.model.error.AuthorizationException ae) {
          result.ae = ae;
        }
        return result;
      }
    }

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

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

      protected boolean isOneway() {
        return false;
      }

      public launchExperiment_result getResult(I iface, launchExperiment_args args) throws org.apache.thrift.TException {
        launchExperiment_result result = new launchExperiment_result();
        try {
          iface.launchExperiment(args.authzToken, args.airavataExperimentId, args.gatewayId);
        } catch (org.apache.airavata.model.error.InvalidRequestException ire) {
          result.ire = ire;
        } catch (org.apache.airavata.model.error.ExperimentNotFoundException enf) {
          result.enf = enf;
        } catch (org.apache.airavata.model.error.AiravataClientException ace) {
          result.ace = ace;
        } catch (org.apache.airavata.model.error.AiravataSystemException ase) {
          result.ase = ase;
        } catch (org.apache.airavata.model.error.AuthorizationException ae) {
          result.ae = ae;
        }
        return result;
      }
    }

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

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

      protected boolean isOneway() {
        return false;
      }

      public getExperimentStatus_result getResult(I iface, getExperimentStatus_args args) throws org.apache.thrift.TException {
        getExperimentStatus_result result = new getExperimentStatus_result();
        try {
          result.success = iface.getExperimentStatus(args.authzToken, args.airavataExperimentId);
        } catch (org.apache.airavata.model.error.InvalidRequestException ire) {
          result.ire = ire;
        } catch (org.apache.airavata.model.error.ExperimentNotFoundException enf) {
          result.enf = enf;
        } catch (org.apache.airavata.model.error.AiravataClientException ace) {
          result.ace = ace;
        } catch (org.apache.airavata.model.error.AiravataSystemException ase) {
          result.ase = ase;
        } catch (org.apache.airavata.model.error.AuthorizationException ae) {
          result.ae = ae;
        }
        return result;
      }
    }

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

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

      protected boolean isOneway() {
        return false;
      }

      public getExperimentOutputs_result getResult(I iface, getExperimentOutputs_args args) throws org.apache.thrift.TException {
        getExperimentOutputs_result result = new getExperimentOutputs_result();
        try {
          result.success = iface.getExperimentOutputs(args.authzToken, args.airavataExperimentId);
        } catch (org.apache.airavata.model.error.InvalidRequestException ire) {
          result.ire = ire;
        } catch (org.apache.airavata.model.error.ExperimentNotFoundException enf) {
          result.enf = enf;
        } catch (org.apache.airavata.model.error.AiravataClientException ace) {
          result.ace = ace;
        } catch (org.apache.airavata.model.error.AiravataSystemException ase) {
          result.ase = ase;
        } catch (org.apache.airavata.model.error.AuthorizationException ae) {
          result.ae = ae;
        }
        return result;
      }
    }

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

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

      protected boolean isOneway() {
        return false;
      }

      public getIntermediateOutputs_result getResult(I iface, getIntermediateOutputs_args args) throws org.apache.thrift.TException {
        getIntermediateOutputs_result result = new getIntermediateOutputs_result();
        try {
          result.success = iface.getIntermediateOutputs(args.authzToken, args.airavataExperimentId);
        } catch (org.apache.airavata.model.error.InvalidRequestException ire) {
          result.ire = ire;
        } catch (org.apache.airavata.model.error.ExperimentNotFoundException enf) {
          result.enf = enf;
        } catch (org.apache.airavata.model.error.AiravataClientException ace) {
          result.ace = ace;
        } catch (org.apache.airavata.model.error.AiravataSystemException ase) {
          result.ase = ase;
        } catch (org.apache.airavata.model.error.AuthorizationException ae) {
          result.ae = ae;
        }
        return result;
      }
    }

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

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

      protected boolean isOneway() {
        return false;
      }

      public getJobStatuses_result getResult(I iface, getJobStatuses_args args) throws org.apache.thrift.TException {
        getJobStatuses_result result = new getJobStatuses_result();
        try {
          result.success = iface.getJobStatuses(args.authzToken, args.airavataExperimentId);
        } catch (org.apache.airavata.model.error.InvalidRequestException ire) {
          result.ire = ire;
        } catch (org.apache.airavata.model.error.ExperimentNotFoundException enf) {
          result.enf = enf;
        } catch (org.apache.airavata.model.error.AiravataClientException ace) {
          result.ace = ace;
        } catch (org.apache.airavata.model.error.AiravataSystemException ase) {
          result.ase = ase;
        } catch (org.apache.airavata.model.error.AuthorizationException ae) {
          result.ae = ae;
        }
        return result;
      }
    }

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

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

      protected boolean isOneway() {
        return false;
      }

      public getJobDetails_result getResult(I iface, getJobDetails_args args) throws org.apache.thrift.TException {
        getJobDetails_result result = new getJobDetails_result();
        try {
          result.success = iface.getJobDetails(args.authzToken, args.airavataExperimentId);
        } catch (org.apache.airavata.model.error.InvalidRequestException ire) {
          result.ire = ire;
        } catch (org.apache.airavata.model.error.ExperimentNotFoundException enf) {
          result.enf = enf;
        } catch (org.apache.airavata.model.error.AiravataClientException ace) {
          result.ace = ace;
        } catch (org.apache.airavata.model.error.AiravataSystemException ase) {
          result.ase = ase;
        } catch (org.apache.airavata.model.error.AuthorizationException ae) {
          result.ae = ae;
        }
        return result;
      }
    }

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

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

      protected boolean isOneway() {
        return false;
      }

      public cloneExperiment_result getResult(I iface, cloneExperiment_args args) throws org.apache.thrift.TException {
        cloneExperiment_result result = new cloneExperiment_result();
        try {
          result.success = iface.cloneExperiment(args.authzToken, args.existingExperimentID, args.newExperimentName);
        } catch (org.apache.airavata.model.error.InvalidRequestException ire) {
          result.ire = ire;
        } catch (org.apache.airavata.model.error.ExperimentNotFoundException enf) {
          result.enf = enf;
        } catch (org.apache.airavata.model.error.AiravataClientException ace) {
          result.ace = ace;
        } catch (org.apache.airavata.model.error.AiravataSystemException ase) {
          result.ase = ase;
        } catch (org.apache.airavata.model.error.AuthorizationException ae) {
          result.ae = ae;
        }
        return result;
      }
    }

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

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

      protected boolean isOneway() {
        return false;
      }

      public terminateExperiment_result getResult(I iface, terminateExperiment_args args) throws org.apache.thrift.TException {
        terminateExperiment_result result = new terminateExperiment_result();
        try {
          iface.terminateExperiment(args.authzToken, args.airavataExperimentId, args.gatewayId);
        } catch (org.apache.airavata.model.error.InvalidRequestException ire) {
          result.ire = ire;
        } catch (org.apache.airavata.model.error.ExperimentNotFoundException enf) {
          result.enf = enf;
        } catch (org.apache.airavata.model.error.AiravataClientException ace) {
          result.ace = ace;
        } catch (org.apache.airavata.model.error.AiravataSystemException ase) {
          result.ase = ase;
        } catch (org.apache.airavata.model.error.AuthorizationException ae) {
          result.ae = ae;
        }
        return result;
      }
    }

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

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

      protected boolean isOneway() {
        return false;
      }

      public registerApplicationModule_result getResult(I iface, registerApplicationModule_args args) throws org.apache.thrift.TException {
        registerApplicationModule_result result = new registerApplicationModule_result();
        try {
          result.success = iface.registerApplicationModule(args.authzToken, args.gatewayId, args.applicationModule);
        } catch (org.apache.airavata.model.error.InvalidRequestException ire) {
          result.ire = ire;
        } catch (org.apache.airavata.model.error.AiravataClientException ace) {
          result.ace = ace;
        } catch (org.apache.airavata.model.error.AiravataSystemException ase) {
          result.ase = ase;
        } catch (org.apache.airavata.model.error.AuthorizationException ae) {
          result.ae = ae;
        }
        return result;
      }
    }

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

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

      protected boolean isOneway() {
        return false;
      }

      public getApplicationModule_result getResult(I iface, getApplicationModule_args args) throws org.apache.thrift.TException {
        getApplicationModule_result result = new getApplicationModule_result();
        try {
          result.success = iface.getApplicationModule(args.authzToken, args.appModuleId);
        } catch (org.apache.airavata.model.error.InvalidRequestException ire) {
          result.ire = ire;
        } catch (org.apache.airavata.model.error.AiravataClientException ace) {
          result.ace = ace;
        } catch (org.apache.airavata.model.error.AiravataSystemException ase) {
          result.ase = ase;
        } catch (org.apache.airavata.model.error.AuthorizationException ae) {
          result.ae = ae;
        }
        return result;
      }
    }

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

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

      protected boolean isOneway() {
        return false;
      }

      public updateApplicationModule_result getResult(I iface, updateApplicationModule_args args) throws org.apache.thrift.TException {
        updateApplicationModule_result result = new updateApplicationModule_result();
        try {
          result.success = iface.updateApplicationModule(args.authzToken, args.appModuleId, args.applicationModule);
          result.setSuccessIsSet(true);
        } catch (org.apache.airavata.model.error.InvalidRequestException ire) {
          result.ire = ire;
        } catch (org.apache.airavata.model.error.AiravataClientException ace) {
          result.ace = ace;
        } catch (org.apache.airavata.model.error.AiravataSystemException ase) {
          result.ase = ase;
        } catch (org.apache.airavata.model.error.AuthorizationException ae) {
          result.ae = ae;
        }
        return result;
      }
    }

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

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

      protected boolean isOneway() {
        return false;
      }

      public getAllAppModules_result getResult(I iface, getAllAppModules_args args) throws org.apache.thrift.TException {
        getAllAppModules_result result = new getAllAppModules_result();
        try {
          result.success = iface.getAllAppModules(args.authzToken, args.gatewayId);
        } catch (org.apache.airavata.model.error.InvalidRequestException ire) {
          result.ire = ire;
        } catch (org.apache.airavata.model.error.AiravataClientException ace) {
          result.ace = ace;
        } catch (org.apache.airavata.model.error.AiravataSystemException ase) {
          result.ase = ase;
        } catch (org.apache.airavata.model.error.AuthorizationException ae) {
          result.ae = ae;
        }
        return result;
      }
    }

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

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

      protected boolean isOneway() {
        return false;
      }

      public deleteApplicationModule_result getResult(I iface, deleteApplicationModule_args args) throws org.apache.thrift.TException {
        deleteApplicationModule_result result = new deleteApplicationModule_result();
        try {
          result.success = iface.deleteApplicationModule(args.authzToken, args.appModuleId);
          result.setSuccessIsSet(true);
        } catch (org.apache.airavata.model.error.InvalidRequestException ire) {
          result.ire = ire;
        } catch (org.apache.airavata.model.error.AiravataClientException ace) {
          result.ace = ace;
        } catch (org.apache.airavata.model.error.AiravataSystemException ase) {
          result.ase = ase;
        } catch (org.apache.airavata.model.error.AuthorizationException ae) {
          result.ae = ae;
        }
        return result;
      }
    }

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

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

      protected boolean isOneway() {
        return false;
      }

      public registerApplicationDeployment_result getResult(I iface, registerApplicationDeployment_args args) throws org.apache.thrift.TException {
        registerApplicationDeployment_result result = new registerApplicationDeployment_result();
        try {
          result.success = iface.registerApplicationDeployment(args.authzToken, args.gatewayId, args.applicationDeployment);
        } catch (org.apache.airavata.model.error.InvalidRequestException ire) {
          result.ire = ire;
        } catch (org.apache.airavata.model.error.AiravataClientException ace) {
          result.ace = ace;
        } catch (org.apache.airavata.model.error.AiravataSystemException ase) {
          result.ase = ase;
        } catch (org.apache.airavata.model.error.AuthorizationException ae) {
          result.ae = ae;
        }
        return result;
      }
    }

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

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

      protected boolean isOneway() {
        return false;
      }

      public getApplicationDeployment_result getResult(I iface, getApplicationDeployment_args args) throws org.apache.thrift.TException {
        getApplicationDeployment_result result = new getApplicationDeployment_result();
        try {
          result.success = iface.getApplicationDeployment(args.authzToken, args.appDeploymentId);
        } catch (org.apache.airavata.model.error.InvalidRequestException ire) {
          result.ire = ire;
        } catch (org.apache.airavata.model.error.AiravataClientException ace) {
          result.ace = ace;
        } catch (org.apache.airavata.model.error.AiravataSystemException ase) {
          result.ase = ase;
        } catch (org.apache.airavata.model.error.AuthorizationException ae) {
          result.ae = ae;
        }
        return result;
      }
    }

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

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

      protected boolean isOneway() {
        return false;
      }

      public updateApplicationDeployment_result getResult(I iface, updateApplicationDeployment_args args) throws org.apache.thrift.TException {
        updateApplicationDeployment_result result = new updateApplicationDeployment_result();
        try {
          result.success = iface.updateApplicationDeployment(args.authzToken, args.appDeploymentId, args.applicationDeployment);
          result.setSuccessIsSet(true);
        } catch (org.apache.airavata.model.error.InvalidRequestException ire) {
          result.ire = ire;
        } catch (org.apache.airavata.model.error.AiravataClientException ace) {
          result.ace = ace;
        } catch (org.apache.airavata.model.error.AiravataSystemException ase) {
          result.ase = ase;
        } catch (org.apache.airavata.model.error.AuthorizationException ae) {
          result.ae = ae;
        }
        return result;
      }
    }

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

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

      protected boolean isOneway() {
        return false;
      }

      public deleteApplicationDeployment_result getResult(I iface, deleteApplicationDeployment_args args) throws org.apache.thrift.TException {
        deleteApplicationDeployment_result result = new deleteApplicationDeployment_result();
        try {
          result.success = iface.deleteApplicationDeployment(args.authzToken, args.appDeploymentId);
          result.setSuccessIsSet(true);
        } catch (org.apache.airavata.model.error.InvalidRequestException ire) {
          result.ire = ire;
        } catch (org.apache.airavata.model.error.AiravataClientException ace) {
          result.ace = ace;
        } catch (org.apache.airavata.model.error.AiravataSystemException ase) {
          result.ase = ase;
        } catch (org.apache.airavata.model.error.AuthorizationException ae) {
          result.ae = ae;
        }
        return result;
      }
    }

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

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

      protected boolean isOneway() {
        return false;
      }

      public getAllApplicationDeployments_result getResult(I iface, getAllApplicationDeployments_args args) throws org.apache.thrift.TException {
        getAllApplicationDeployments_result result = new getAllApplicationDeployments_result();
        try {
          result.success = iface.getAllApplicationDeployments(args.authzToken, args.gatewayId);
        } catch (org.apache.airavata.model.error.InvalidRequestException ire) {
          result.ire = ire;
        } catch (org.apache.airavata.model.error.AiravataClientException ace) {
          result.ace = ace;
        } catch (org.apache.airavata.model.error.AiravataSystemException ase) {
          result.ase = ase;
        } catch (org.apache.airavata.model.error.AuthorizationException ae) {
          result.ae = ae;
        }
        return result;
      }
    }

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

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

      protected boolean isOneway() {
        return false;
      }

      public getAppModuleDeployedResources_result getResult(I iface, getAppModuleDeployedResources_args args) throws org.apache.thrift.TException {
        getAppModuleDeployedResources_result result = new getAppModuleDeployedResources_result();
        try {
          result.success = iface.getAppModuleDeployedResources(args.authzToken, args.appModuleId);
        } catch (org.apache.airavata.model.error.InvalidRequestException ire) {
          result.ire = ire;
        } catch (org.apache.airavata.model.error.AiravataClientException ace) {
          result.ace = ace;
        } catch (org.apache.airavata.model.error.AiravataSystemException ase) {
          result.ase = ase;
        } catch (org.apache.airavata.model.error.AuthorizationException ae) {
          result.ae = ae;
        }
        return result;
      }
    }

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

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

      protected boolean isOneway() {
        return false;
      }

      public registerApplicationInterface_result getResult(I iface, registerApplicationInterface_args args) throws org.apache.thrift.TException {
        registerApplicationInterface_result result = new registerApplicationInterface_result();
        try {
          result.success = iface.registerApplicationInterface(args.authzToken, args.gatewayId, args.applicationInterface);
        } catch (org.apache.airavata.model.error.InvalidRequestException ire) {
          result.ire = ire;
        } catch (org.apache.airavata.model.error.AiravataClientException ace) {
          result.ace = ace;
        } catch (org.apache.airavata.model.error.AiravataSystemException ase) {
          result.ase = ase;
        } catch (org.apache.airavata.model.error.AuthorizationException ae) {
          result.ae = ae;
        }
        return result;
      }
    }

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

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

      protected boolean isOneway() {
        return false;
      }

      public getApplicationInterface_result getResult(I iface, getApplicationInterface_args args) throws org.apache.thrift.TException {
        getApplicationInterface_result result = new getApplicationInterface_result();
        try {
          result.success = iface.getApplicationInterface(args.authzToken, args.appInterfaceId);
        } catch (org.apache.airavata.model.error.InvalidRequestException ire) {
          result.ire = ire;
        } catch (org.apache.airavata.model.error.AiravataClientException ace) {
          result.ace = ace;
        } catch (org.apache.airavata.model.error.AiravataSystemException ase) {
          result.ase = ase;
        } catch (org.apache.airavata.model.error.AuthorizationException ae) {
          result.ae = ae;
        }
        return result;
      }
    }

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

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

      protected boolean isOneway() {
        return false;
      }

      public updateApplicationInterface_result getResult(I iface, updateApplicationInterface_args args) throws org.apache.thrift.TException {
        updateApplicationInterface_result result = new updateApplicationInterface_result();
        try {
          result.success = iface.updateApplicationInterface(args.authzToken, args.appInterfaceId, args.applicationInterface);
          result.setSuccessIsSet(true);
        } catch (org.apache.airavata.model.error.InvalidRequestException ire) {
          result.ire = ire;
        } catch (org.apache.airavata.model.error.AiravataClientException ace) {
          result.ace = ace;
        } catch (org.apache.airavata.model.error.AiravataSystemException ase) {
          result.ase = ase;
        } catch (org.apache.airavata.model.error.AuthorizationException ae) {
          result.ae = ae;
        }
        return result;
      }
    }

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

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

      protected boolean isOneway() {
        return false;
      }

      public deleteApplicationInterface_result getResult(I iface, deleteApplicationInterface_args args) throws org.apache.thrift.TException {
        deleteApplicationInterface_result result = new deleteApplicationInterface_result();
        try {
          result.success = iface.deleteApplicationInterface(args.authzToken, args.appInterfaceId);
          result.setSuccessIsSet(true);
        } catch (org.apache.airavata.model.error.InvalidRequestException ire) {
          result.ire = ire;
        } catch (org.apache.airavata.model.error.AiravataClientException ace) {
          result.ace = ace;
        } catch (org.apache.airavata.model.error.AiravataSystemException ase) {
          result.ase = ase;
        } catch (org.apache.airavata.model.error.AuthorizationException ae) {
          result.ae = ae;
        }
        return result;
      }
    }

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

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

      protected boolean isOneway() {
        return false;
      }

      public getAllApplicationInterfaceNames_result getResult(I iface, getAllApplicationInterfaceNames_args args) throws org.apache.thrift.TException {
        getAllApplicationInterfaceNames_result result = new getAllApplicationInterfaceNames_result();
        try {
          result.success = iface.getAllApplicationInterfaceNames(args.authzToken, args.gatewayId);
        } catch (org.apache.airavata.model.error.InvalidRequestException ire) {
          result.ire = ire;
        } catch (org.apache.airavata.model.error.AiravataClientException ace) {
          result.ace = ace;
        } catch (org.apache.airavata.model.error.AiravataSystemException ase) {
          result.ase = ase;
        } catch (org.apache.airavata.model.error.AuthorizationException ae) {
          result.ae = ae;
        }
        return result;
      }
    }

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

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

      protected boolean isOneway() {
        return false;
      }

      public getAllApplicationInterfaces_result getResult(I iface, getAllApplicationInterfaces_args args) throws org.apache.thrift.TException {
        getAllApplicationInterfaces_result result = new getAllApplicationInterfaces_result();
        try {
          result.success = iface.getAllApplicationInterfaces(args.authzToken, args.gatewayId);
        } catch (org.apache.airavata.model.error.InvalidRequestException ire) {
          result.ire = ire;
        } catch (org.apache.airavata.model.error.AiravataClientException ace) {
          result.ace = ace;
        } catch (org.apache.airavata.model.error.AiravataSystemException ase) {
          result.ase = ase;
        } catch (org.apache.airavata.model.error.AuthorizationException ae) {
          result.ae = ae;
        }
        return result;
      }
    }

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

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

      protected boolean isOneway() {
        return false;
      }

      public getApplicationInputs_result getResult(I iface, getApplicationInputs_args args) throws org.apache.thrift.TException {
        getApplicationInputs_result result = new getApplicationInputs_result();
        try {
          result.success = iface.getApplicationInputs(args.authzToken, args.appInterfaceId);
        } catch (org.apache.airavata.model.error.InvalidRequestException ire) {
          result.ire = ire;
        } catch (org.apache.airavata.model.error.AiravataClientException ace) {
          result.ace = ace;
        } catch (org.apache.airavata.model.error.AiravataSystemException ase) {
          result.ase = ase;
        } catch (org.apache.airavata.model.error.AuthorizationException ae) {
          result.ae = ae;
        }
        return result;
      }
    }

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

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

      protected boolean isOneway() {
        return false;
      }

      public getApplicationOutputs_result getResult(I iface, getApplicationOutputs_args args) throws org.apache.thrift.TException {
        getApplicationOutputs_result result = new getApplicationOutputs_result();
        try {
          result.success = iface.getApplicationOutputs(args.authzToken, args.appInterfaceId);
        } catch (org.apache.airavata.model.error.InvalidRequestException ire) {
          result.ire = ire;
        } catch (org.apache.airavata.model.error.AiravataClientException ace) {
          result.ace = ace;
        } catch (org.apache.airavata.model.error.AiravataSystemException ase) {
          result.ase = ase;
        } catch (org.apache.airavata.model.error.AuthorizationException ae) {
          result.ae = ae;
        }
        return result;
      }
    }

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

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

      protected boolean isOneway() {
        return false;
      }

      public getAvailableAppInterfaceComputeResources_result getResult(I iface, getAvailableAppInterfaceComputeResources_args args) throws org.apache.thrift.TException {
        getAvailableAppInterfaceComputeResources_result result = new getAvailableAppInterfaceComputeResources_result();
        try {
          result.success = iface.getAvailableAppInterfaceComputeResources(args.authzToken, args.appInterfaceId);
        } catch (org.apache.airavata.model.error.InvalidRequestException ire) {
          result.ire = ire;
        } catch (org.apache.airavata.model.error.AiravataClientException ace) {
          result.ace = ace;
        } catch (org.apache.airavata.model.error.AiravataSystemException ase) {
          result.ase = ase;
        } catch (org.apache.airavata.model.error.AuthorizationException ae) {
          result.ae = ae;
        }
        return result;
      }
    }

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

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

      protected boolean isOneway() {
        return false;
      }

      public registerComputeResource_result getResult(I iface, registerComputeResource_args args) throws org.apache.thrift.TException {
        registerComputeResource_result result = new registerComputeResource_result();
        try {
          result.success = iface.registerComputeResource(args.authzToken, args.computeResourceDescription);
        } catch (org.apache.airavata.model.error.InvalidRequestException ire) {
          result.ire = ire;
        } catch (org.apache.airavata.model.error.AiravataClientException ace) {
          result.ace = ace;
        } catch (org.apache.airavata.model.error.AiravataSystemException ase) {
          result.ase = ase;
        } catch (org.apache.airavata.model.error.AuthorizationException ae) {
          result.ae = ae;
        }
        return result;
      }
    }

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

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

      protected boolean isOneway() {
        return false;
      }

      public getComputeResource_result getResult(I iface, getComputeResource_args args) throws org.apache.thrift.TException {
        getComputeResource_result result = new getComputeResource_result();
        try {
          result.success = iface.getComputeResource(args.authzToken, args.computeResourceId);
        } catch (org.apache.airavata.model.error.InvalidRequestException ire) {
          result.ire = ire;
        } catch (org.apache.airavata.model.error.AiravataClientException ace) {
          result.ace = ace;
        } catch (org.apache.airavata.model.error.AiravataSystemException ase) {
          result.ase = ase;
        } catch (org.apache.airavata.model.error.AuthorizationException ae) {
          result.ae = ae;
        }
        return result;
      }
    }

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

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

      protected boolean isOneway() {
        return false;
      }

      public getAllComputeResourceNames_result getResult(I iface, getAllComputeResourceNames_args args) throws org.apache.thrift.TException {
        getAllComputeResourceNames_result result = new getAllComputeResourceNames_result();
        try {
          result.success = iface.getAllComputeResourceNames(args.authzToken);
        } catch (org.apache.airavata.model.error.InvalidRequestException ire) {
          result.ire = ire;
        } catch (org.apache.airavata.model.error.AiravataClientException ace) {
          result.ace = ace;
        } catch (org.apache.airavata.model.error.AiravataSystemException ase) {
          result.ase = ase;
        } catch (org.apache.airavata.model.error.AuthorizationException ae) {
          result.ae = ae;
        }
        return result;
      }
    }

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

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

      protected boolean isOneway() {
        return false;
      }

      public updateComputeResource_result getResult(I iface, updateComputeResource_args args) throws org.apache.thrift.TException {
        updateComputeResource_result result = new updateComputeResource_result();
        try {
          result.success = iface.updateComputeResource(args.authzToken, args.computeResourceId, args.computeResourceDescription);
          result.setSuccessIsSet(true);
        } catch (org.apache.airavata.model.error.InvalidRequestException ire) {
          result.ire = ire;
        } catch (org.apache.airavata.model.error.AiravataClientException ace) {
          result.ace = ace;
        } catch (org.apache.airavata.model.error.AiravataSystemException ase) {
          result.ase = ase;
        } catch (org.apache.airavata.model.error.AuthorizationException ae) {
          result.ae = ae;
        }
        return result;
      }
    }

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

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

      protected boolean isOneway() {
        return false;
      }

      public deleteComputeResource_result getResult(I iface, deleteComputeResource_args args) throws org.apache.thrift.TException {
        deleteComputeResource_result result = new deleteComputeResource_result();
        try {
          result.success = iface.deleteComputeResource(args.authzToken, args.computeResourceId);
          result.setSuccessIsSet(true);
        } catch (org.apache.airavata.model.error.InvalidRequestException ire) {
          result.ire = ire;
        } catch (org.apache.airavata.model.error.AiravataClientException ace) {
          result.ace = ace;
        } catch (org.apache.airavata.model.error.AiravataSystemException ase) {
          result.ase = ase;
        } catch (org.apache.airavata.model.error.AuthorizationException ae) {
          result.ae = ae;
        }
        return result;
      }
    }

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

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

      protected boolean isOneway() {
        return false;
      }

      public addLocalSubmissionDetails_result getResult(I iface, addLocalSubmissionDetails_args args) throws org.apache.thrift.TException {
        addLocalSubmissionDetails_result result = new addLocalSubmissionDetails_result();
        try {
          result.success = iface.addLocalSubmissionDetails(args.authzToken, args.computeResourceId, args.priorityOrder, args.localSubmission);
        } catch (org.apache.airavata.model.error.InvalidRequestException ire) {
          result.ire = ire;
        } catch (org.apache.airavata.model.error.AiravataClientException ace) {
          result.ace = ace;
        } catch (org.apache.airavata.model.error.AiravataSystemException ase) {
          result.ase = ase;
        } catch (org.apache.airavata.model.error.AuthorizationException ae) {
          result.ae = ae;
        }
        return result;
      }
    }

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

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

      protected boolean isOneway() {
        return false;
      }

      public updateLocalSubmissionDetails_result getResult(I iface, updateLocalSubmissionDetails_args args) throws org.apache.thrift.TException {
        updateLocalSubmissionDetails_result result = new updateLocalSubmissionDetails_result();
        try {
          result.success = iface.updateLocalSubmissionDetails(args.authzToken, args.jobSubmissionInterfaceId, args.localSubmission);
          result.setSuccessIsSet(true);
        } catch (org.apache.airavata.model.error.InvalidRequestException ire) {
          result.ire = ire;
        } catch (org.apache.airavata.model.error.AiravataClientException ace) {
          result.ace = ace;
        } catch (org.apache.airavata.model.error.AiravataSystemException ase) {
          result.ase = ase;
        } catch (org.apache.airavata.model.error.AuthorizationException ae) {
          result.ae = ae;
        }
        return result;
      }
    }

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

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

      protected boolean isOneway() {
        return false;
      }

      public getLocalJobSubmission_result getResult(I iface, getLocalJobSubmission_args args) throws org.apache.thrift.TException {
        getLocalJobSubmission_result result = new getLocalJobSubmission_result();
        try {
          result.success = iface.getLocalJobSubmission(args.authzToken, args.jobSubmissionId);
        } catch (org.apache.airavata.model.error.InvalidRequestException ire) {
          result.ire = ire;
        } catch (org.apache.airavata.model.error.AiravataClientException ace) {
          result.ace = ace;
        } catch (org.apache.airavata.model.error.AiravataSystemException ase) {
          result.ase = ase;
        } catch (org.apache.airavata.model.error.AuthorizationException ae) {
          result.ae = ae;
        }
        return result;
      }
    }

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

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

      protected boolean isOneway() {
        return false;
      }

      public addSSHJobSubmissionDetails_result getResult(I iface, addSSHJobSubmissionDetails_args args) throws org.apache.thrift.TException {
        addSSHJobSubmissionDetails_result result = new addSSHJobSubmissionDetails_result();
        try {
          result.success = iface.addSSHJobSubmissionDetails(args.authzToken, args.computeResourceId, args.priorityOrder, args.sshJobSubmission);
        } catch (org.apache.airavata.model.error.InvalidRequestException ire) {
          result.ire = ire;
        } catch (org.apache.airavata.model.error.AiravataClientException ace) {
          result.ace = ace;
        } catch (org.apache.airavata.model.error.AiravataSystemException ase) {
          result.ase = ase;
        } catch (org.apache.airavata.model.error.AuthorizationException ae) {
          result.ae = ae;
        }
        return result;
      }
    }

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

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

      protected boolean isOneway() {
        return false;
      }

      public addSSHForkJobSubmissionDetails_result getResult(I iface, addSSHForkJobSubmissionDetails_args args) throws org.apache.thrift.TException {
        addSSHForkJobSubmissionDetails_result result = new addSSHForkJobSubmissionDetails_result();
        try {
          result.success = iface.addSSHForkJobSubmissionDetails(args.authzToken, args.computeResourceId, args.priorityOrder, args.sshJobSubmission);
        } catch (org.apache.airavata.model.error.InvalidRequestException ire) {
          result.ire = ire;
        } catch (org.apache.airavata.model.error.AiravataClientException ace) {
          result.ace = ace;
        } catch (org.apache.airavata.model.error.AiravataSystemException ase) {
          result.ase = ase;
        } catch (org.apache.airavata.model.error.AuthorizationException ae) {
          result.ae = ae;
        }
        return result;
      }
    }

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

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

      protected boolean isOneway() {
        return false;
      }

      public getSSHJobSubmission_result getResult(I iface, getSSHJobSubmission_args args) throws org.apache.thrift.TException {
        getSSHJobSubmission_result result = new getSSHJobSubmission_result();
        try {
          result.success = iface.getSSHJobSubmission(args.authzToken, args.jobSubmissionId);
        } catch (org.apache.airavata.model.error.InvalidRequestException ire) {
          result.ire = ire;
        } catch (org.apache.airavata.model.error.AiravataClientException ace) {
          result.ace = ace;
        } catch (org.apache.airavata.model.error.AiravataSystemException ase) {
          result.ase = ase;
        } catch (org.apache.airavata.model.error.AuthorizationException ae) {
          result.ae = ae;
        }
        return result;
      }
    }

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

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

      protected boolean isOneway() {
        return false;
      }

      public addUNICOREJobSubmissionDetails_result getResult(I iface, addUNICOREJobSubmissionDetails_args args) throws org.apache.thrift.TException {
        addUNICOREJobSubmissionDetails_result result = new addUNICOREJobSubmissionDetails_result();
        try {
          result.success = iface.addUNICOREJobSubmissionDetails(args.authzToken, args.computeResourceId, args.priorityOrder, args.unicoreJobSubmission);
        } catch (org.apache.airavata.model.error.InvalidRequestException ire) {
          result.ire = ire;
        } catch (org.apache.airavata.model.error.AiravataClientException ace) {
          result.ace = ace;
        } catch (org.apache.airavata.model.error.AiravataSystemException ase) {
          result.ase = ase;
        } catch (org.apache.airavata.model.error.AuthorizationException ae) {
          result.ae = ae;
        }
        return result;
      }
    }

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

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

      protected boolean isOneway() {
        return false;
      }

      public getUnicoreJobSubmission_result getResult(I iface, getUnicoreJobSubmission_args args) throws org.apache.thrift.TException {
        getUnicoreJobSubmission_result result = new getUnicoreJobSubmission_result();
        try {
          result.success = iface.getUnicoreJobSubmission(args.authzToken, args.jobSubmissionId);
        } catch (org.apache.airavata.model.error.InvalidRequestException ire) {
          result.ire = ire;
        } catch (org.apache.airavata.model.error.AiravataClientException ace) {
          result.ace = ace;
        } catch (org.apache.airavata.model.error.AiravataSystemException ase) {
          result.ase = ase;
        } catch (org.apache.airavata.model.error.AuthorizationException ae) {
          result.ae = ae;
        }
        return result;
      }
    }

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

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

      protected boolean isOneway() {
        return false;
      }

      public addCloudJobSubmissionDetails_result getResult(I iface, addCloudJobSubmissionDetails_args args) throws org.apache.thrift.TException {
        addCloudJobSubmissionDetails_result result = new addCloudJobSubmissionDetails_result();
        try {
          result.success = iface.addCloudJobSubmissionDetails(args.authzToken, args.computeResourceId, args.priorityOrder, args.cloudSubmission);
        } catch (org.apache.airavata.model.error.InvalidRequestException ire) {
          result.ire = ire;
        } catch (org.apache.airavata.model.error.AiravataClientException ace) {
          result.ace = ace;
        } catch (org.apache.airavata.model.error.AiravataSystemException ase) {
          result.ase = ase;
        } catch (org.apache.airavata.model.error.AuthorizationException ae) {
          result.ae = ae;
        }
        return result;
      }
    }

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

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

      protected boolean isOneway() {
        return false;
      }

      public getCloudJobSubmission_result getResult(I iface, getCloudJobSubmission_args args) throws org.apache.thrift.TException {
        getCloudJobSubmission_result result = new getCloudJobSubmission_result();
        try {
          result.success = iface.getCloudJobSubmission(args.authzToken, args.jobSubmissionId);
        } catch (org.apache.airavata.model.error.InvalidRequestException ire) {
          result.ire = ire;
        } catch (org.apache.airavata.model.error.AiravataClientException ace) {
          result.ace = ace;
        } catch (org.apache.airavata.model.error.AiravataSystemException ase) {
          result.ase = ase;
        } catch (org.apache.airavata.model.error.AuthorizationException ae) {
          result.ae = ae;
        }
        return result;
      }
    }

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

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

      protected boolean isOneway() {
        return false;
      }

      public updateSSHJobSubmissionDetails_result getResult(I iface, updateSSHJobSubmissionDetails_args args) throws org.apache.thrift.TException {
        updateSSHJobSubmissionDetails_result result = new updateSSHJobSubmissionDetails_result();
        try {
          result.success = iface.updateSSHJobSubmissionDetails(args.authzToken, args.jobSubmissionInterfaceId, args.sshJobSubmission);
          result.setSuccessIsSet(true);
        } catch (org.apache.airavata.model.error.InvalidRequestException ire) {
          result.ire = ire;
        } catch (org.apache.airavata.model.error.AiravataClientException ace) {
          result.ace = ace;
        } catch (org.apache.airavata.model.error.AiravataSystemException ase) {
          result.ase = ase;
        } catch (org.apache.airavata.model.error.AuthorizationException ae) {
          result.ae = ae;
        }
        return result;
      }
    }

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

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

      protected boolean isOneway() {
        return false;
      }

      public updateCloudJobSubmissionDetails_result getResult(I iface, updateCloudJobSubmissionDetails_args args) throws org.apache.thrift.TException {
        updateCloudJobSubmissionDetails_result result = new updateCloudJobSubmissionDetails_result();
        try {
          result.success = iface.updateCloudJobSubmissionDetails(args.authzToken, args.jobSubmissionInterfaceId, args.sshJobSubmission);
          result.setSuccessIsSet(true);
        } catch (org.apache.airavata.model.error.InvalidRequestException ire) {
          result.ire = ire;
        } catch (org.apache.airavata.model.error.AiravataClientException ace) {
          result.ace = ace;
        } catch (org.apache.airavata.model.error.AiravataSystemException ase) {
          result.ase = ase;
        } catch (org.apache.airavata.model.error.AuthorizationException ae) {
          result.ae = ae;
        }
        return result;
      }
    }

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

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

      protected boolean isOneway() {
        return false;
      }

      public updateUnicoreJobSubmissionDetails_result getResult(I iface, updateUnicoreJobSubmissionDetails_args args) throws org.apache.thrift.TException {
        updateUnicoreJobSubmissionDetails_result result = new updateUnicoreJobSubmissionDetails_result();
        try {
          result.success = iface.updateUnicoreJobSubmissionDetails(args.authzToken, args.jobSubmissionInterfaceId, args.unicoreJobSubmission);
          result.setSuccessIsSet(true);
        } catch (org.apache.airavata.model.error.InvalidRequestException ire) {
          result.ire = ire;
        } catch (org.apache.airavata.model.error.AiravataClientException ace) {
          result.ace = ace;
        } catch (org.apache.airavata.model.error.AiravataSystemException ase) {
          result.ase = ase;
        } catch (org.apache.airavata.model.error.AuthorizationException ae) {
          result.ae = ae;
        }
        return result;
      }
    }

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

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

      protected boolean isOneway() {
        return false;
      }

      public addLocalDataMovementDetails_result getResult(I iface, addLocalDataMovementDetails_args args) throws org.apache.thrift.TException {
        addLocalDataMovementDetails_result result = new addLocalDataMovementDetails_result();
        try {
          result.success = iface.addLocalDataMovementDetails(args.authzToken, args.computeResourceId, args.priorityOrder, args.localDataMovement);
        } catch (org.apache.airavata.model.error.InvalidRequestException ire) {
          result.ire = ire;
        } catch (org.apache.airavata.model.error.AiravataClientException ace) {
          result.ace = ace;
        } catch (org.apache.airavata.model.error.AiravataSystemException ase) {
          result.ase = ase;
        } catch (org.apache.airavata.model.error.AuthorizationException ae) {
          result.ae = ae;
        }
        return result;
      }
    }

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

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

      protected boolean isOneway() {
        return false;
      }

      public updateLocalDataMovementDetails_result getResult(I iface, updateLocalDataMovementDetails_args args) throws org.apache.thrift.TException {
        updateLocalDataMovementDetails_result result = new updateLocalDataMovementDetails_result();
        try {
          result.success = iface.updateLocalDataMovementDetails(args.authzToken, args.dataMovementInterfaceId, args.localDataMovement);
          result.setSuccessIsSet(true);
        } catch (org.apache.airavata.model.error.InvalidRequestException ire) {
          result.ire = ire;
        } catch (org.apache.airavata.model.error.AiravataClientException ace) {
          result.ace = ace;
        } catch (org.apache.airavata.model.error.AiravataSystemException ase) {
          result.ase = ase;
        } catch (org.apache.airavata.model.error.AuthorizationException ae) {
          result.ae = ae;
        }
        return result;
      }
    }

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

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

      protected boolean isOneway() {
        return false;
      }

      public getLocalDataMovement_result getResult(I iface, getLocalDataMovement_args args) throws org.apache.thrift.TException {
        getLocalDataMovement_result result = new getLocalDataMovement_result();
        try {
          result.success = iface.getLocalDataMovement(args.authzToken, args.dataMovementId);
        } catch (org.apache.airavata.model.error.InvalidRequestException ire) {
          result.ire = ire;
        } catch (org.apache.airavata.model.error.AiravataClientException ace) {
          result.ace = ace;
        } catch (org.apache.airavata.model.error.AiravataSystemException ase) {
          result.ase = ase;
        } catch (org.apache.airavata.model.error.AuthorizationException ae) {
          result.ae = ae;
        }
        return result;
      }
    }

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

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

      protected boolean isOneway() {
        return false;
      }

      public addSCPDataMovementDetails_result getResult(I iface, addSCPDataMovementDetails_args args) throws org.apache.thrift.TException {
        addSCPDataMovementDetails_result result = new addSCPDataMovementDetails_result();
        try {
          result.success = iface.addSCPDataMovementDetails(args.authzToken, args.computeResourceId, args.priorityOrder, args.scpDataMovement);
        } catch (org.apache.airavata.model.error.InvalidRequestException ire) {
          result.ire = ire;
        } catch (org.apache.airavata.model.error.AiravataClientException ace) {
          result.ace = ace;
        } catch (org.apache.airavata.model.error.AiravataSystemException ase) {
          result.ase = ase;
        } catch (org.apache.airavata.model.error.AuthorizationException ae) {
          result.ae = ae;
        }
        return result;
      }
    }

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

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

      protected boolean isOneway() {
        return false;
      }

      public updateSCPDataMovementDetails_result getResult(I iface, updateSCPDataMovementDetails_args args) throws org.apache.thrift.TException {
        updateSCPDataMovementDetails_result result = new updateSCPDataMovementDetails_result();
        try {
          result.success = iface.updateSCPDataMovementDetails(args.authzToken, args.dataMovementInterfaceId, args.scpDataMovement);
          result.setSuccessIsSet(true);
        } catch (org.apache.airavata.model.error.InvalidRequestException ire) {
          result.ire = ire;
        } catch (org.apache.airavata.model.error.AiravataClientException ace) {
          result.ace = ace;
        } catch (org.apache.airavata.model.error.AiravataSystemException ase) {
          result.ase = ase;
        } catch (org.apache.airavata.model.error.AuthorizationException ae) {
          result.ae = ae;
        }
        return result;
      }
    }

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

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

      protected boolean isOneway() {
        return false;
      }

      public getSCPDataMovement_result getResult(I iface, getSCPDataMovement_args args) throws org.apache.thrift.TException {
        getSCPDataMovement_result result = new getSCPDataMovement_result();
        try {
          result.success = iface.getSCPDataMovement(args.authzToken, args.dataMovementId);
        } catch (org.apache.airavata.model.error.InvalidRequestException ire) {
          result.ire = ire;
        } catch (org.apache.airavata.model.error.AiravataClientException ace) {
          result.ace = ace;
        } catch (org.apache.airavata.model.error.AiravataSystemException ase) {
          result.ase = ase;
        } catch (org.apache.airavata.model.error.AuthorizationException ae) {
          result.ae = ae;
        }
        return result;
      }
    }

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

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

      protected boolean isOneway() {
        return false;
      }

      public addUnicoreDataMovementDetails_result getResult(I iface, addUnicoreDataMovementDetails_args args) throws org.apache.thrift.TException {
        addUnicoreDataMovementDetails_result result = new addUnicoreDataMovementDetails_result();
        try {
          result.success = iface.addUnicoreDataMovementDetails(args.authzToken, args.computeResourceId, args.priorityOrder, args.unicoreDataMovement);
        } catch (org.apache.airavata.model.error.InvalidRequestException ire) {
          result.ire = ire;
        } catch (org.apache.airavata.model.error.AiravataClientException ace) {
          result.ace = ace;
        } catch (org.apache.airavata.model.error.AiravataSystemException ase) {
          result.ase = ase;
        } catch (org.apache.airavata.model.error.AuthorizationException ae) {
          result.ae = ae;
        }
        return result;
      }
    }

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

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

      protected boolean isOneway() {
        return false;
      }

      public updateUnicoreDataMovementDetails_result getResult(I iface, updateUnicoreDataMovementDetails_args args) throws org.apache.thrift.TException {
        updateUnicoreDataMovementDetails_result result = new updateUnicoreDataMovementDetails_result();
        try {
          result.success = iface.updateUnicoreDataMovementDetails(args.authzToken, args.dataMovementInterfaceId, args.unicoreDataMovement);
          result.setSuccessIsSet(true);
        } catch (org.apache.airavata.model.error.InvalidRequestException ire) {
          result.ire = ire;
        } catch (org.apache.airavata.model.error.AiravataClientException ace) {
          result.ace = ace;
        } catch (org.apache.airavata.model.error.AiravataSystemException ase) {
          result.ase = ase;
        } catch (org.apache.airavata.model.error.AuthorizationException ae) {
          result.ae = ae;
        }
        return result;
      }
    }

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

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

      protected boolean isOneway() {
        return false;
      }

      public getUnicoreDataMovement_result getResult(I iface, getUnicoreDataMovement_args args) throws org.apache.thrift.TException {
        getUnicoreDataMovement_result result = new getUnicoreDataMovement_result();
        try {
          result.success = iface.getUnicoreDataMovement(args.authzToken, args.dataMovementId);
        } catch (org.apache.airavata.model.error.InvalidRequestException ire) {
          result.ire = ire;
        } catch (org.apache.airavata.model.error.AiravataClientException ace) {
          result.ace = ace;
        } catch (org.apache.airavata.model.error.AiravataSystemException ase) {
          result.ase = ase;
        } catch (org.apache.airavata.model.error.AuthorizationException ae) {
          result.ae = ae;
        }
        return result;
      }
    }

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

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

      protected boolean isOneway() {
        return false;
      }

      public addGridFTPDataMovementDetails_result getResult(I iface, addGridFTPDataMovementDetails_args args) throws org.apache.thrift.TException {
        addGridFTPDataMovementDetails_result result = new addGridFTPDataMovementDetails_result();
        try {
          result.success = iface.addGridFTPDataMovementDetails(args.authzToken, args.computeResourceId, args.priorityOrder, args.gridFTPDataMovement);
        } catch (org.apache.airavata.model.error.InvalidRequestException ire) {
          result.ire = ire;
        } catch (org.apache.airavata.model.error.AiravataClientException ace) {
          result.ace = ace;
        } catch (org.apache.airavata.model.error.AiravataSystemException ase) {
          result.ase = ase;
        } catch (org.apache.airavata.model.error.AuthorizationException ae) {
          result.ae = ae;
        }
        return result;
      }
    }

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

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

      protected boolean isOneway() {
        return false;
      }

      public updateGridFTPDataMovementDetails_result getResult(I iface, updateGridFTPDataMovementDetails_args args) throws org.apache.thrift.TException {
        updateGridFTPDataMovementDetails_result result = new updateGridFTPDataMovementDetails_result();
        try {
          result.success = iface.updateGridFTPDataMovementDetails(args.authzToken, args.dataMovementInterfaceId, args.gridFTPDataMovement);
          result.setSuccessIsSet(true);
        } catch (org.apache.airavata.model.error.InvalidRequestException ire) {
          result.ire = ire;
        } catch (org.apache.airavata.model.error.AiravataClientException ace) {
          result.ace = ace;
        } catch (org.apache.airavata.model.error.AiravataSystemException ase) {
          result.ase = ase;
        } catch (org.apache.airavata.model.error.AuthorizationException ae) {
          result.ae = ae;
        }
        return result;
      }
    }

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

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

      protected boolean isOneway() {
        return false;
      }

      public getGridFTPDataMovement_result getResult(I iface, getGridFTPDataMovement_args args) throws org.apache.thrift.TException {
        getGridFTPDataMovement_result result = new getGridFTPDataMovement_result();
        try {
          result.success = iface.getGridFTPDataMovement(args.authzToken, args.dataMovementId);
        } catch (org.apache.airavata.model.error.InvalidRequestException ire) {
          result.ire = ire;
        } catch (org.apache.airavata.model.error.AiravataClientException ace) {
          result.ace = ace;
        } catch (org.apache.airavata.model.error.AiravataSystemException ase) {
          result.ase = ase;
        } catch (org.apache.airavata.model.error.AuthorizationException ae) {
          result.ae = ae;
        }
        return result;
      }
    }

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

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

      protected boolean isOneway() {
        return false;
      }

      public changeJobSubmissionPriority_result getResult(I iface, changeJobSubmissionPriority_args args) throws org.apache.thrift.TException {
        changeJobSubmissionPriority_result result = new changeJobSubmissionPriority_result();
        try {
          result.success = iface.changeJobSubmissionPriority(args.authzToken, args.jobSubmissionInterfaceId, args.newPriorityOrder);
          result.setSuccessIsSet(true);
        } catch (org.apache.airavata.model.error.InvalidRequestException ire) {
          result.ire = ire;
        } catch (org.apache.airavata.model.error.AiravataClientException ace) {
          result.ace = ace;
        } catch (org.apache.airavata.model.error.AiravataSystemException ase) {
          result.ase = ase;
        } catch (org.apache.airavata.model.error.AuthorizationException ae) {
          result.ae = ae;
        }
        return result;
      }
    }

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

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

      protected boolean isOneway() {
        return false;
      }

      public changeDataMovementPriority_result getResult(I iface, changeDataMovementPriority_args args) throws org.apache.thrift.TException {
        changeDataMovementPriority_result result = new changeDataMovementPriority_result();
        try {
          result.success = iface.changeDataMovementPriority(args.authzToken, args.dataMovementInterfaceId, args.newPriorityOrder);
          result.setSuccessIsSet(true);
        } catch (org.apache.airavata.model.error.InvalidRequestException ire) {
          result.ire = ire;
        } catch (org.apache.airavata.model.error.AiravataClientException ace) {
          result.ace = ace;
        } catch (org.apache.airavata.model.error.AiravataSystemException ase) {
          result.ase = ase;
        } catch (org.apache.airavata.model.error.AuthorizationException ae) {
          result.ae = ae;
        }
        return result;
      }
    }

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

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

      protected boolean isOneway() {
        return false;
      }

      public changeJobSubmissionPriorities_result getResult(I iface, changeJobSubmissionPriorities_args args) throws org.apache.thrift.TException {
        changeJobSubmissionPriorities_result result = new changeJobSubmissionPriorities_result();
        try {
          result.success = iface.changeJobSubmissionPriorities(args.authzToken, args.jobSubmissionPriorityMap);
          result.setSuccessIsSet(true);
        } catch (org.apache.airavata.model.error.InvalidRequestException ire) {
          result.ire = ire;
        } catch (org.apache.airavata.model.error.AiravataClientException ace) {
          result.ace = ace;
        } catch (org.apache.airavata.model.error.AiravataSystemException ase) {
          result.ase = ase;
        } catch (org.apache.airavata.model.error.AuthorizationException ae) {
          result.ae = ae;
        }
        return result;
      }
    }

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

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

      protected boolean isOneway() {
        return false;
      }

      public changeDataMovementPriorities_result getResult(I iface, changeDataMovementPriorities_args args) throws org.apache.thrift.TException {
        changeDataMovementPriorities_result result = new changeDataMovementPriorities_result();
        try {
          result.success = iface.changeDataMovementPriorities(args.authzToken, args.dataMovementPriorityMap);
          result.setSuccessIsSet(true);
        } catch (org.apache.airavata.model.error.InvalidRequestException ire) {
          result.ire = ire;
        } catch (org.apache.airavata.model.error.AiravataClientException ace) {
          result.ace = ace;
        } catch (org.apache.airavata.model.error.AiravataSystemException ase) {
          result.ase = ase;
        } catch (org.apache.airavata.model.error.AuthorizationException ae) {
          result.ae = ae;
        }
        return result;
      }
    }

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

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

      protected boolean isOneway() {
        return false;
      }

      public deleteJobSubmissionInterface_result getResult(I iface, deleteJobSubmissionInterface_args args) throws org.apache.thrift.TException {
        deleteJobSubmissionInterface_result result = new deleteJobSubmissionInterface_result();
        try {
          result.success = iface.deleteJobSubmissionInterface(args.authzToken, args.computeResourceId, args.jobSubmissionInterfaceId);
          result.setSuccessIsSet(true);
        } catch (org.apache.airavata.model.error.InvalidRequestException ire) {
          result.ire = ire;
        } catch (org.apache.airavata.model.error.AiravataClientException ace) {
          result.ace = ace;
        } catch (org.apache.airavata.model.error.AiravataSystemException ase) {
          result.ase = ase;
        } catch (org.apache.airavata.model.error.AuthorizationException ae) {
          result.ae = ae;
        }
        return result;
      }
    }

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

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

      protected boolean isOneway() {
        return false;
      }

      public deleteDataMovementInterface_result getResult(I iface, deleteDataMovementInterface_args args) throws org.apache.thrift.TException {
        deleteDataMovementInterface_result result = new deleteDataMovementInterface_result();
        try {
          result.success = iface.deleteDataMovementInterface(args.authzToken, args.computeResourceId, args.dataMovementInterfaceId);
          result.setSuccessIsSet(true);
        } catch (org.apache.airavata.model.error.InvalidRequestException ire) {
          result.ire = ire;
        } catch (org.apache.airavata.model.error.AiravataClientException ace) {
          result.ace = ace;
        } catch (org.apache.airavata.model.error.AiravataSystemException ase) {
          result.ase = ase;
        } catch (org.apache.airavata.model.error.AuthorizationException ae) {
          result.ae = ae;
        }
        return result;
      }
    }

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

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

      protected boolean isOneway() {
        return false;
      }

      public registerResourceJobManager_result getResult(I iface, registerResourceJobManager_args args) throws org.apache.thrift.TException {
        registerResourceJobManager_result result = new registerResourceJobManager_result();
        try {
          result.success = iface.registerResourceJobManager(args.authzToken, args.resourceJobManager);
        } catch (org.apache.airavata.model.error.InvalidRequestException ire) {
          result.ire = ire;
        } catch (org.apache.airavata.model.error.AiravataClientException ace) {
          result.ace = ace;
        } catch (org.apache.airavata.model.error.AiravataSystemException ase) {
          result.ase = ase;
        } catch (org.apache.airavata.model.error.AuthorizationException ae) {
          result.ae = ae;
        }
        return result;
      }
    }

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

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

      protected boolean isOneway() {
        return false;
      }

      public updateResourceJobManager_result getResult(I iface, updateResourceJobManager_args args) throws org.apache.thrift.TException {
        updateResourceJobManager_result result = new updateResourceJobManager_result();
        try {
          result.success = iface.updateResourceJobManager(args.authzToken, args.resourceJobManagerId, args.updatedResourceJobManager);
          result.setSuccessIsSet(true);
        } catch (org.apache.airavata.model.error.InvalidRequestException ire) {
          result.ire = ire;
        } catch (org.apache.airavata.model.error.AiravataClientException ace) {
          result.ace = ace;
        } catch (org.apache.airavata.model.error.AiravataSystemException ase) {
          result.ase = ase;
        } catch (org.apache.airavata.model.error.AuthorizationException ae) {
          result.ae = ae;
        }
        return result;
      }
    }

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

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

      protected boolean isOneway() {
        return false;
      }

      public getResourceJobManager_result getResult(I iface, getResourceJobManager_args args) throws org.apache.thrift.TException {
        getResourceJobManager_result result = new getResourceJobManager_result();
        try {
          result.success = iface.getResourceJobManager(args.authzToken, args.resourceJobManagerId);
        } catch (org.apache.airavata.model.error.InvalidRequestException ire) {
          result.ire = ire;
        } catch (org.apache.airavata.model.error.AiravataClientException ace) {
          result.ace = ace;
        } catch (org.apache.airavata.model.error.AiravataSystemException ase) {
          result.ase = ase;
        } catch (org.apache.airavata.model.error.AuthorizationException ae) {
          result.ae = ae;
        }
        return result;
      }
    }

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

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

      protected boolean isOneway() {
        return false;
      }

      public deleteResourceJobManager_result getResult(I iface, deleteResourceJobManager_args args) throws org.apache.thrift.TException {
        deleteResourceJobManager_result result = new deleteResourceJobManager_result();
        try {
          result.success = iface.deleteResourceJobManager(args.authzToken, args.resourceJobManagerId);
          result.setSuccessIsSet(true);
        } catch (org.apache.airavata.model.error.InvalidRequestException ire) {
          result.ire = ire;
        } catch (org.apache.airavata.model.error.AiravataClientException ace) {
          result.ace = ace;
        } catch (org.apache.airavata.model.error.AiravataSystemException ase) {
          result.ase = ase;
        } catch (org.apache.airavata.model.error.AuthorizationException ae) {
          result.ae = ae;
        }
        return result;
      }
    }

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

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

      protected boolean isOneway() {
        return false;
      }

      public deleteBatchQueue_result getResult(I iface, deleteBatchQueue_args args) throws org.apache.thrift.TException {
        deleteBatchQueue_result result = new deleteBatchQueue_result();
        try {
          result.success = iface.deleteBatchQueue(args.authzToken, args.computeResourceId, args.queueName);
          result.setSuccessIsSet(true);
        } catch (org.apache.airavata.model.error.InvalidRequestException ire) {
          result.ire = ire;
        } catch (org.apache.airavata.model.error.AiravataClientException ace) {
          result.ace = ace;
        } catch (org.apache.airavata.model.error.AiravataSystemException ase) {
          result.ase = ase;
        } catch (org.apache.airavata.model.error.AuthorizationException ae) {
          result.ae = ae;
        }
        return result;
      }
    }

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

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

      protected boolean isOneway() {
        return false;
      }

      public registerGatewayResourceProfile_result getResult(I iface, registerGatewayResourceProfile_args args) throws org.apache.thrift.TException {
        registerGatewayResourceProfile_result result = new registerGatewayResourceProfile_result();
        try {
          result.success = iface.registerGatewayResourceProfile(args.authzToken, args.gatewayResourceProfile);
        } catch (org.apache.airavata.model.error.InvalidRequestException ire) {
          result.ire = ire;
        } catch (org.apache.airavata.model.error.AiravataClientException ace) {
          result.ace = ace;
        } catch (org.apache.airavata.model.error.AiravataSystemException ase) {
          result.ase = ase;
        } catch (org.apache.airavata.model.error.AuthorizationException ae) {
          result.ae = ae;
        }
        return result;
      }
    }

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

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

      protected boolean isOneway() {
        return false;
      }

      public getGatewayResourceProfile_result getResult(I iface, getGatewayResourceProfile_args args) throws org.apache.thrift.TException {
        getGatewayResourceProfile_result result = new getGatewayResourceProfile_result();
        try {
          result.success = iface.getGatewayResourceProfile(args.authzToken, args.gatewayID);
        } catch (org.apache.airavata.model.error.InvalidRequestException ire) {
          result.ire = ire;
        } catch (org.apache.airavata.model.error.AiravataClientException ace) {
          result.ace = ace;
        } catch (org.apache.airavata.model.error.AiravataSystemException ase) {
          result.ase = ase;
        } catch (org.apache.airavata.model.error.AuthorizationException ae) {
          result.ae = ae;
        }
        return result;
      }
    }

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

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

      protected boolean isOneway() {
        return false;
      }

      public updateGatewayResourceProfile_result getResult(I iface, updateGatewayResourceProfile_args args) throws org.apache.thrift.TException {
        updateGatewayResourceProfile_result result = new updateGatewayResourceProfile_result();
        try {
          result.success = iface.updateGatewayResourceProfile(args.authzToken, args.gatewayID, args.gatewayResourceProfile);
          result.setSuccessIsSet(true);
        } catch (org.apache.airavata.model.error.InvalidRequestException ire) {
          result.ire = ire;
        } catch (org.apache.airavata.model.error.AiravataClientException ace) {
          result.ace = ace;
        } catch (org.apache.airavata.model.error.AiravataSystemException ase) {
          result.ase = ase;
        } catch (org.apache.airavata.model.error.AuthorizationException ae) {
          result.ae = ae;
        }
        return result;
      }
    }

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

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

      protected boolean isOneway() {
        return false;
      }

      public deleteGatewayResourceProfile_result getResult(I iface, deleteGatewayResourceProfile_args args) throws org.apache.thrift.TException {
        deleteGatewayResourceProfile_result result = new deleteGatewayResourceProfile_result();
        try {
          result.success = iface.deleteGatewayResourceProfile(args.authzToken, args.gatewayID);
          result.setSuccessIsSet(true);
        } catch (org.apache.airavata.model.error.InvalidRequestException ire) {
          result.ire = ire;
        } catch (org.apache.airavata.model.error.AiravataClientException ace) {
          result.ace = ace;
        } catch (org.apache.airavata.model.error.AiravataSystemException ase) {
          result.ase = ase;
        } catch (org.apache.airavata.model.error.AuthorizationException ae) {
          result.ae = ae;
        }
        return result;
      }
    }

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

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

      protected boolean isOneway() {
        return false;
      }

      public addGatewayComputeResourcePreference_result getResult(I iface, addGatewayComputeResourcePreference_args args) throws org.apache.thrift.TException {
        addGatewayComputeResourcePreference_result result = new addGatewayComputeResourcePreference_result();
        try {
          result.success = iface.addGatewayComputeResourcePreference(args.authzToken, args.gatewayID, args.computeResourceId, args.computeResourcePreference);
          result.setSuccessIsSet(true);
        } catch (org.apache.airavata.model.error.InvalidRequestException ire) {
          result.ire = ire;
        } catch (org.apache.airavata.model.error.AiravataClientException ace) {
          result.ace = ace;
        } catch (org.apache.airavata.model.error.AiravataSystemException ase) {
          result.ase = ase;
        } catch (org.apache.airavata.model.error.AuthorizationException ae) {
          result.ae = ae;
        }
        return result;
      }
    }

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

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

      protected boolean isOneway() {
        return false;
      }

      public addGatewayDataStoragePreference_result getResult(I iface, addGatewayDataStoragePreference_args args) throws org.apache.thrift.TException {
        addGatewayDataStoragePreference_result result = new addGatewayDataStoragePreference_result();
        try {
          result.success = iface.addGatewayDataStoragePreference(args.authzToken, args.gatewayID, args.dataMoveId, args.dataStoragePreference);
          result.setSuccessIsSet(true);
        } catch (org.apache.airavata.model.error.InvalidRequestException ire) {
          result.ire = ire;
        } catch (org.apache.airavata.model.error.AiravataClientException ace) {
          result.ace = ace;
        } catch (org.apache.airavata.model.error.AiravataSystemException ase) {
          result.ase = ase;
        } catch (org.apache.airavata.model.error.AuthorizationException ae) {
          result.ae = ae;
        }
        return result;
      }
    }

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

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

      protected boolean isOneway() {
        return false;
      }

      public getGatewayComputeResourcePreference_result getResult(I iface, getGatewayComputeResourcePreference_args args) throws org.apache.thrift.TException {
        getGatewayComputeResourcePreference_result result = new getGatewayComputeResourcePreference_result();
        try {
          result.success = iface.getGatewayComputeResourcePreference(args.authzToken, args.gatewayID, args.computeResourceId);
        } catch (org.apache.airavata.model.error.InvalidRequestException ire) {
          result.ire = ire;
        } catch (org.apache.airavata.model.error.AiravataClientException ace) {
          result.ace = ace;
        } catch (org.apache.airavata.model.error.AiravataSystemException ase) {
          result.ase = ase;
        } catch (org.apache.airavata.model.error.AuthorizationException ae) {
          result.ae = ae;
        }
        return result;
      }
    }

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

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

      protected boolean isOneway() {
        return false;
      }

      public getGatewayDataStoragePreference_result getResult(I iface, getGatewayDataStoragePreference_args args) throws org.apache.thrift.TException {
        getGatewayDataStoragePreference_result result = new getGatewayDataStoragePreference_result();
        try {
          result.success = iface.getGatewayDataStoragePreference(args.authzToken, args.gatewayID, args.dataMoveId);
        } catch (org.apache.airavata.model.error.InvalidRequestException ire) {
          result.ire = ire;
        } catch (org.apache.airavata.model.error.AiravataClientException ace) {
          result.ace = ace;
        } catch (org.apache.airavata.model.error.AiravataSystemException ase) {
          result.ase = ase;
        } catch (org.apache.airavata.model.error.AuthorizationException ae) {
          result.ae = ae;
        }
        return result;
      }
    }

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

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

      protected boolean isOneway() {
        return false;
      }

      public getAllGatewayComputeResourcePreferences_result getResult(I iface, getAllGatewayComputeResourcePreferences_args args) throws org.apache.thrift.TException {
        getAllGatewayComputeResourcePreferences_result result = new getAllGatewayComputeResourcePreferences_result();
        try {
          result.success = iface.getAllGatewayComputeResourcePreferences(args.authzToken, args.gatewayID);
        } catch (org.apache.airavata.model.error.InvalidRequestException ire) {
          result.ire = ire;
        } catch (org.apache.airavata.model.error.AiravataClientException ace) {
          result.ace = ace;
        } catch (org.apache.airavata.model.error.AiravataSystemException ase) {
          result.ase = ase;
        } catch (org.apache.airavata.model.error.AuthorizationException ae) {
          result.ae = ae;
        }
        return result;
      }
    }

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

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

      protected boolean isOneway() {
        return false;
      }

      public getAllGatewayDataStoragePreferences_result getResult(I iface, getAllGatewayDataStoragePreferences_args args) throws org.apache.thrift.TException {
        getAllGatewayDataStoragePreferences_result result = new getAllGatewayDataStoragePreferences_result();
        try {
          result.success = iface.getAllGatewayDataStoragePreferences(args.authzToken, args.gatewayID);
        } catch (org.apache.airavata.model.error.InvalidRequestException ire) {
          result.ire = ire;
        } catch (org.apache.airavata.model.error.AiravataClientException ace) {
          result.ace = ace;
        } catch (org.apache.airavata.model.error.AiravataSystemException ase) {
          result.ase = ase;
        } catch (org.apache.airavata.model.error.AuthorizationException ae) {
          result.ae = ae;
        }
        return result;
      }
    }

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

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

      protected boolean isOneway() {
        return false;
      }

      public getAllGatewayResourceProfiles_result getResult(I iface, getAllGatewayResourceProfiles_args args) throws org.apache.thrift.TException {
        getAllGatewayResourceProfiles_result result = new getAllGatewayResourceProfiles_result();
        try {
          result.success = iface.getAllGatewayResourceProfiles(args.authzToken);
        } catch (org.apache.airavata.model.error.InvalidRequestException ire) {
          result.ire = ire;
        } catch (org.apache.airavata.model.error.AiravataClientException ace) {
          result.ace = ace;
        } catch (org.apache.airavata.model.error.AiravataSystemException ase) {
          result.ase = ase;
        } catch (org.apache.airavata.model.error.AuthorizationException ae) {
          result.ae = ae;
        }
        return result;
      }
    }

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

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

      protected boolean isOneway() {
        return false;
      }

      public updateGatewayComputeResourcePreference_result getResult(I iface, updateGatewayComputeResourcePreference_args args) throws org.apache.thrift.TException {
        updateGatewayComputeResourcePreference_result result = new updateGatewayComputeResourcePreference_result();
        try {
          result.success = iface.updateGatewayComputeResourcePreference(args.authzToken, args.gatewayID, args.computeResourceId, args.computeResourcePreference);
          result.setSuccessIsSet(true);
        } catch (org.apache.airavata.model.error.InvalidRequestException ire) {
          result.ire = ire;
        } catch (org.apache.airavata.model.error.AiravataClientException ace) {
          result.ace = ace;
        } catch (org.apache.airavata.model.error.AiravataSystemException ase) {
          result.ase = ase;
        } catch (org.apache.airavata.model.error.AuthorizationException ae) {
          result.ae = ae;
        }
        return result;
      }
    }

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

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

      protected boolean isOneway() {
        return false;
      }

      public updateGatewayDataStoragePreference_result getResult(I iface, updateGatewayDataStoragePreference_args args) throws org.apache.thrift.TException {
        updateGatewayDataStoragePreference_result result = new updateGatewayDataStoragePreference_result();
        try {
          result.success = iface.updateGatewayDataStoragePreference(args.authzToken, args.gatewayID, args.dataMoveId, args.dataStoragePreference);
          result.setSuccessIsSet(true);
        } catch (org.apache.airavata.model.error.InvalidRequestException ire) {
          result.ire = ire;
        } catch (org.apache.airavata.model.error.AiravataClientException ace) {
          result.ace = ace;
        } catch (org.apache.airavata.model.error.AiravataSystemException ase) {
          result.ase = ase;
        } catch (org.apache.airavata.model.error.AuthorizationException ae) {
          result.ae = ae;
        }
        return result;
      }
    }

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

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

      protected boolean isOneway() {
        return false;
      }

      public deleteGatewayComputeResourcePreference_result getResult(I iface, deleteGatewayComputeResourcePreference_args args) throws org.apache.thrift.TException {
        deleteGatewayComputeResourcePreference_result result = new deleteGatewayComputeResourcePreference_result();
        try {
          result.success = iface.deleteGatewayComputeResourcePreference(args.authzToken, args.gatewayID, args.computeResourceId);
          result.setSuccessIsSet(true);
        } catch (org.apache.airavata.model.error.InvalidRequestException ire) {
          result.ire = ire;
        } catch (org.apache.airavata.model.error.AiravataClientException ace) {
          result.ace = ace;
        } catch (org.apache.airavata.model.error.AiravataSystemException ase) {
          result.ase = ase;
        } catch (org.apache.airavata.model.error.AuthorizationException ae) {
          result.ae = ae;
        }
        return result;
      }
    }

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

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

      protected boolean isOneway() {
        return false;
      }

      public deleteGatewayDataStoragePreference_result getResult(I iface, deleteGatewayDataStoragePreference_args args) throws org.apache.thrift.TException {
        deleteGatewayDataStoragePreference_result result = new deleteGatewayDataStoragePreference_result();
        try {
          result.success = iface.deleteGatewayDataStoragePreference(args.authzToken, args.gatewayID, args.dataMoveId);
          result.setSuccessIsSet(true);
        } catch (org.apache.airavata.model.error.InvalidRequestException ire) {
          result.ire = ire;
        } catch (org.apache.airavata.model.error.AiravataClientException ace) {
          result.ace = ace;
        } catch (org.apache.airavata.model.error.AiravataSystemException ase) {
          result.ase = ase;
        } catch (org.apache.airavata.model.error.AuthorizationException ae) {
          result.ae = ae;
        }
        return result;
      }
    }

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

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

      protected boolean isOneway() {
        return false;
      }

      public getAllWorkflows_result getResult(I iface, getAllWorkflows_args args) throws org.apache.thrift.TException {
        getAllWorkflows_result result = new getAllWorkflows_result();
        try {
          result.success = iface.getAllWorkflows(args.authzToken, args.gatewayId);
        } catch (org.apache.airavata.model.error.InvalidRequestException ire) {
          result.ire = ire;
        } catch (org.apache.airavata.model.error.AiravataClientException ace) {
          result.ace = ace;
        } catch (org.apache.airavata.model.error.AiravataSystemException ase) {
          result.ase = ase;
        } catch (org.apache.airavata.model.error.AuthorizationException ae) {
          result.ae = ae;
        }
        return result;
      }
    }

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

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

      protected boolean isOneway() {
        return false;
      }

      public getWorkflow_result getResult(I iface, getWorkflow_args args) throws org.apache.thrift.TException {
        getWorkflow_result result = new getWorkflow_result();
        try {
          result.success = iface.getWorkflow(args.authzToken, args.workflowTemplateId);
        } catch (org.apache.airavata.model.error.InvalidRequestException ire) {
          result.ire = ire;
        } catch (org.apache.airavata.model.error.AiravataClientException ace) {
          result.ace = ace;
        } catch (org.apache.airavata.model.error.AiravataSystemException ase) {
          result.ase = ase;
        } catch (org.apache.airavata.model.error.AuthorizationException ae) {
          result.ae = ae;
        }
        return result;
      }
    }

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

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

      protected boolean isOneway() {
        return false;
      }

      public deleteWorkflow_result getResult(I iface, deleteWorkflow_args args) throws org.apache.thrift.TException {
        deleteWorkflow_result result = new deleteWorkflow_result();
        try {
          iface.deleteWorkflow(args.authzToken, args.workflowTemplateId);
        } catch (org.apache.airavata.model.error.InvalidRequestException ire) {
          result.ire = ire;
        } catch (org.apache.airavata.model.error.AiravataClientException ace) {
          result.ace = ace;
        } catch (org.apache.airavata.model.error.AiravataSystemException ase) {
          result.ase = ase;
        } catch (org.apache.airavata.model.error.AuthorizationException ae) {
          result.ae = ae;
        }
        return result;
      }
    }

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

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

      protected boolean isOneway() {
        return false;
      }

      public registerWorkflow_result getResult(I iface, registerWorkflow_args args) throws org.apache.thrift.TException {
        registerWorkflow_result result = new registerWorkflow_result();
        try {
          result.success = iface.registerWorkflow(args.authzToken, args.gatewayId, args.workflow);
        } catch (org.apache.airavata.model.error.InvalidRequestException ire) {
          result.ire = ire;
        } catch (org.apache.airavata.model.error.AiravataClientException ace) {
          result.ace = ace;
        } catch (org.apache.airavata.model.error.AiravataSystemException ase) {
          result.ase = ase;
        } catch (org.apache.airavata.model.error.AuthorizationException ae) {
          result.ae = ae;
        }
        return result;
      }
    }

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

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

      protected boolean isOneway() {
        return false;
      }

      public updateWorkflow_result getResult(I iface, updateWorkflow_args args) throws org.apache.thrift.TException {
        updateWorkflow_result result = new updateWorkflow_result();
        try {
          iface.updateWorkflow(args.authzToken, args.workflowTemplateId, args.workflow);
        } catch (org.apache.airavata.model.error.InvalidRequestException ire) {
          result.ire = ire;
        } catch (org.apache.airavata.model.error.AiravataClientException ace) {
          result.ace = ace;
        } catch (org.apache.airavata.model.error.AiravataSystemException ase) {
          result.ase = ase;
        } catch (org.apache.airavata.model.error.AuthorizationException ae) {
          result.ae = ae;
        }
        return result;
      }
    }

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

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

      protected boolean isOneway() {
        return false;
      }

      public getWorkflowTemplateId_result getResult(I iface, getWorkflowTemplateId_args args) throws org.apache.thrift.TException {
        getWorkflowTemplateId_result result = new getWorkflowTemplateId_result();
        try {
          result.success = iface.getWorkflowTemplateId(args.authzToken, args.workflowName);
        } catch (org.apache.airavata.model.error.InvalidRequestException ire) {
          result.ire = ire;
        } catch (org.apache.airavata.model.error.AiravataClientException ace) {
          result.ace = ace;
        } catch (org.apache.airavata.model.error.AiravataSystemException ase) {
          result.ase = ase;
        } catch (org.apache.airavata.model.error.AuthorizationException ae) {
          result.ae = ae;
        }
        return result;
      }
    }

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

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

      protected boolean isOneway() {
        return false;
      }

      public isWorkflowExistWithName_result getResult(I iface, isWorkflowExistWithName_args args) throws org.apache.thrift.TException {
        isWorkflowExistWithName_result result = new isWorkflowExistWithName_result();
        try {
          result.success = iface.isWorkflowExistWithName(args.authzToken, args.workflowName);
          result.setSuccessIsSet(true);
        } catch (org.apache.airavata.model.error.InvalidRequestException ire) {
          result.ire = ire;
        } catch (org.apache.airavata.model.error.AiravataClientException ace) {
          result.ace = ace;
        } catch (org.apache.airavata.model.error.AiravataSystemException ase) {
          result.ase = ase;
        } catch (org.apache.airavata.model.error.AuthorizationException ae) {
          result.ae = ae;
        }
        return result;
      }
    }

  }

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

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

    private static <I extends AsyncIface> Map<String,  org.apache.thrift.AsyncProcessFunction<I, ? extends  org.apache.thrift.TBase,?>> getProcessMap(Map<String,  org.apache.thrift.AsyncProcessFunction<I, ? extends  org.apache.thrift.TBase, ?>> processMap) {
      processMap.put("getAPIVersion", new getAPIVersion());
      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("generateAndRegisterSSHKeys", new generateAndRegisterSSHKeys());
      processMap.put("getSSHPubKey", new getSSHPubKey());
      processMap.put("getAllUserSSHPubKeys", new getAllUserSSHPubKeys());
      processMap.put("createProject", new createProject());
      processMap.put("updateProject", new updateProject());
      processMap.put("getProject", new getProject());
      processMap.put("deleteProject", new deleteProject());
      processMap.put("getUserProjects", new getUserProjects());
      processMap.put("searchProjectsByProjectName", new searchProjectsByProjectName());
      processMap.put("searchProjectsByProjectDesc", new searchProjectsByProjectDesc());
      processMap.put("searchExperimentsByName", new searchExperimentsByName());
      processMap.put("searchExperimentsByDesc", new searchExperimentsByDesc());
      processMap.put("searchExperimentsByApplication", new searchExperimentsByApplication());
      processMap.put("searchExperimentsByStatus", new searchExperimentsByStatus());
      processMap.put("searchExperimentsByCreationTime", new searchExperimentsByCreationTime());
      processMap.put("searchExperiments", new searchExperiments());
      processMap.put("getExperimentStatistics", new getExperimentStatistics());
      processMap.put("getExperimentsInProject", new getExperimentsInProject());
      processMap.put("getUserExperiments", new getUserExperiments());
      processMap.put("createExperiment", new createExperiment());
      processMap.put("deleteExperiment", new deleteExperiment());
      processMap.put("getExperiment", new getExperiment());
      processMap.put("getDetailedExperimentTree", new getDetailedExperimentTree());
      processMap.put("updateExperiment", new updateExperiment());
      processMap.put("updateExperimentConfiguration", new updateExperimentConfiguration());
      processMap.put("updateResourceScheduleing", new updateResourceScheduleing());
      processMap.put("validateExperiment", new validateExperiment());
      processMap.put("launchExperiment", new launchExperiment());
      processMap.put("getExperimentStatus", new getExperimentStatus());
      processMap.put("getExperimentOutputs", new getExperimentOutputs());
      processMap.put("getIntermediateOutputs", new getIntermediateOutputs());
      processMap.put("getJobStatuses", new getJobStatuses());
      processMap.put("getJobDetails", new getJobDetails());
      processMap.put("cloneExperiment", new cloneExperiment());
      processMap.put("terminateExperiment", new terminateExperiment());
      processMap.put("registerApplicationModule", new registerApplicationModule());
      processMap.put("getApplicationModule", new getApplicationModule());
      processMap.put("updateApplicationModule", new updateApplicationModule());
      processMap.put("getAllAppModules", new getAllAppModules());
      processMap.put("deleteApplicationModule", new deleteApplicationModule());
      processMap.put("registerApplicationDeployment", new registerApplicationDeployment());
      processMap.put("getApplicationDeployment", new getApplicationDeployment());
      processMap.put("updateApplicationDeployment", new updateApplicationDeployment());
      processMap.put("deleteApplicationDeployment", new deleteApplicationDeployment());
      processMap.put("getAllApplicationDeployments", new getAllApplicationDeployments());
      processMap.put("getAppModuleDeployedResources", new getAppModuleDeployedResources());
      processMap.put("registerApplicationInterface", new registerApplicationInterface());
      processMap.put("getApplicationInterface", new getApplicationInterface());
      processMap.put("updateApplicationInterface", new updateApplicationInterface());
      processMap.put("deleteApplicationInterface", new deleteApplicationInterface());
      processMap.put("getAllApplicationInterfaceNames", new getAllApplicationInterfaceNames());
      processMap.put("getAllApplicationInterfaces", new getAllApplicationInterfaces());
      processMap.put("getApplicationInputs", new getApplicationInputs());
      processMap.put("getApplicationOutputs", new getApplicationOutputs());
      processMap.put("getAvailableAppInterfaceComputeResources", new getAvailableAppInterfaceComputeResources());
      processMap.put("registerComputeResource", new registerComputeResource());
      processMap.put("getComputeResource", new getComputeResource());
      processMap.put("getAllComputeResourceNames", new getAllComputeResourceNames());
      processMap.put("updateComputeResource", new updateComputeResource());
      processMap.put("deleteComputeResource", new deleteComputeResource());
      processMap.put("addLocalSubmissionDetails", new addLocalSubmissionDetails());
      processMap.put("updateLocalSubmissionDetails", new updateLocalSubmissionDetails());
      processMap.put("getLocalJobSubmission", new getLocalJobSubmission());
      processMap.put("addSSHJobSubmissionDetails", new addSSHJobSubmissionDetails());
      processMap.put("addSSHForkJobSubmissionDetails", new addSSHForkJobSubmissionDetails());
      processMap.put("getSSHJobSubmission", new getSSHJobSubmission());
      processMap.put("addUNICOREJobSubmissionDetails", new addUNICOREJobSubmissionDetails());
      processMap.put("getUnicoreJobSubmission", new getUnicoreJobSubmission());
      processMap.put("addCloudJobSubmissionDetails", new addCloudJobSubmissionDetails());
      processMap.put("getCloudJobSubmission", new getCloudJobSubmission());
      processMap.put("updateSSHJobSubmissionDetails", new updateSSHJobSubmissionDetails());
      processMap.put("updateCloudJobSubmissionDetails", new updateCloudJobSubmissionDetails());
      processMap.put("updateUnicoreJobSubmissionDetails", new updateUnicoreJobSubmissionDetails());
      processMap.put("addLocalDataMovementDetails", new addLocalDataMovementDetails());
      processMap.put("updateLocalDataMovementDetails", new updateLocalDataMovementDetails());
      processMap.put("getLocalDataMovement", new getLocalDataMovement());
      processMap.put("addSCPDataMovementDetails", new addSCPDataMovementDetails());
      processMap.put("updateSCPDataMovementDetails", new updateSCPDataMovementDetails());
      processMap.put("getSCPDataMovement", new getSCPDataMovement());
      processMap.put("addUnicoreDataMovementDetails", new addUnicoreDataMovementDetails());
      processMap.put("updateUnicoreDataMovementDetails", new updateUnicoreDataMovementDetails());
      processMap.put("getUnicoreDataMovement", new getUnicoreDataMovement());
      processMap.put("addGridFTPDataMovementDetails", new addGridFTPDataMovementDetails());
      processMap.put("updateGridFTPDataMovementDetails", new updateGridFTPDataMovementDetails());
      processMap.put("getGridFTPDataMovement", new getGridFTPDataMovement());
      processMap.put("changeJobSubmissionPriority", new changeJobSubmissionPriority());
      processMap.put("changeDataMovementPriority", new changeDataMovementPriority());
      processMap.put("changeJobSubmissionPriorities", new changeJobSubmissionPriorities());
      processMap.put("changeDataMovementPriorities", new changeDataMovementPriorities());
      processMap.put("deleteJobSubmissionInterface", new deleteJobSubmissionInterface());
      processMap.put("deleteDataMovementInterface", new deleteDataMovementInterface());
      processMap.put("registerResourceJobManager", new registerResourceJobManager());
      processMap.put("updateResourceJobManager", new updateResourceJobManager());
      processMap.put("getResourceJobManager", new getResourceJobManager());
      processMap.put("deleteResourceJobManager", new deleteResourceJobManager());
      processMap.put("deleteBatchQueue", new deleteBatchQueue());
      processMap.put("registerGatewayResourceProfile", new registerGatewayResourceProfile());
      processMap.put("getGatewayResourceProfile", new getGatewayResourceProfile());
      processMap.put("updateGatewayResourceProfile", new updateGatewayResourceProfile());
      processMap.put("deleteGatewayResourceProfile", new deleteGatewayResourceProfile());
      processMap.put("addGatewayComputeResourcePreference", new addGatewayComputeResourcePreference());
      processMap.put("addGatewayDataStoragePreference", new addGatewayDataStoragePreference());
      processMap.put("getGatewayComputeResourcePreference", new getGatewayComputeResourcePreference());
      processMap.put("getGatewayDataStoragePreference", new getGatewayDataStoragePreference());
      processMap.put("getAllGatewayComputeResourcePreferences", new getAllGatewayComputeResourcePreferences());
      processMap.put("getAllGatewayDataStoragePreferences", new getAllGatewayDataStoragePreferences());
      processMap.put("getAllGatewayResourceProfiles", new getAllGatewayResourceProfiles());
      processMap.put("updateGatewayComputeResourcePreference", new updateGatewayComputeResourcePreference());
      processMap.put("updateGatewayDataStoragePreference", new updateGatewayDataStoragePreference());
      processMap.put("deleteGatewayComputeResourcePreference", new deleteGatewayComputeResourcePreference());
      processMap.put("deleteGatewayDataStoragePreference", new deleteGatewayDataStoragePreference());
      processMap.put("getAllWorkflows", new getAllWorkflows());
      processMap.put("getWorkflow", new getWorkflow());
      processMap.put("deleteWorkflow", new deleteWorkflow());
      processMap.put("registerWorkflow", new registerWorkflow());
      processMap.put("updateWorkflow", new updateWorkflow());
      processMap.put("getWorkflowTemplateId", new getWorkflowTemplateId());
      processMap.put("isWorkflowExistWithName", new isWorkflowExistWithName());
      return processMap;
    }

    public static class getAPIVersion<I extends AsyncIface> extends org.apache.thrift.AsyncProcessFunction<I, getAPIVersion_args, String> {
      public getAPIVersion() {
        super("getAPIVersion");
      }

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

      public AsyncMethodCallback<String> getResultHandler(final AsyncFrameBuffer fb, final int seqid) {
        final org.apache.thrift.AsyncProcessFunction fcall = this;
        return new AsyncMethodCallback<String>() { 
          public void onComplete(String o) {
            getAPIVersion_result result = new getAPIVersion_result();
            result.success = o;
            try {
              fcall.sendResponse(fb,result, org.apache.thrift.protocol.TMessageType.REPLY,seqid);
              return;
            } catch (Exception e) {
              LOGGER.error("Exception writing to internal frame buffer", e);
            }
            fb.close();
          }
          public void onError(Exception e) {
            byte msgType = org.apache.thrift.protocol.TMessageType.REPLY;
            org.apache.thrift.TBase msg;
            getAPIVersion_result result = new getAPIVersion_result();
            if (e instanceof org.apache.airavata.model.error.InvalidRequestException) {
                        result.ire = (org.apache.airavata.model.error.InvalidRequestException) e;
                        result.setIreIsSet(true);
                        msg = result;
            }
            else             if (e instanceof org.apache.airavata.model.error.AiravataClientException) {
                        result.ace = (org.apache.airavata.model.error.AiravataClientException) e;
                        result.setAceIsSet(true);
                        msg = result;
            }
            else             if (e instanceof org.apache.airavata.model.error.AiravataSystemException) {
                        result.ase = (org.apache.airavata.model.error.AiravataSystemException) e;
                        result.setAseIsSet(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 
            {
              msgType = org.apache.thrift.protocol.TMessageType.EXCEPTION;
              msg = (org.apache.thrift.TBase)new org.apache.thrift.TApplicationException(org.apache.thrift.TApplicationException.INTERNAL_ERROR, e.getMessage());
            }
            try {
              fcall.sendResponse(fb,msg,msgType,seqid);
              return;
            } catch (Exception ex) {
              LOGGER.error("Exception writing to internal frame buffer", ex);
            }
            fb.close();
          }
        };
      }

      protected boolean isOneway() {
        return false;
      }

      public void start(I iface, getAPIVersion_args args, org.apache.thrift.async.AsyncMethodCallback<String> resultHandler) throws TException {
        iface.getAPIVersion(args.authzToken,resultHandler);
      }
    }

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

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

      public AsyncMethodCallback<String> getResultHandler(final AsyncFrameBuffer fb, final int seqid) {
        final org.apache.thrift.AsyncProcessFunction fcall = this;
        return new AsyncMethodCallback<String>() { 
          public void onComplete(String o) {
            addGateway_result result = new addGateway_result();
            result.success = o;
            try {
              fcall.sendResponse(fb,result, org.apache.thrift.protocol.TMessageType.REPLY,seqid);
              return;
            } catch (Exception e) {
              LOGGER.error("Exception writing to internal frame buffer", e);
            }
            fb.close();
          }
          public void onError(Exception e) {
            byte msgType = org.apache.thrift.protocol.TMessageType.REPLY;
            org.apache.thrift.TBase msg;
            addGateway_result result = new addGateway_result();
            if (e instanceof org.apache.airavata.model.error.InvalidRequestException) {
                        result.ire = (org.apache.airavata.model.error.InvalidRequestException) e;
                        result.setIreIsSet(true);
                        msg = result;
            }
            else             if (e instanceof org.apache.airavata.model.error.AiravataClientException) {
                        result.ace = (org.apache.airavata.model.error.AiravataClientException) e;
                        result.setAceIsSet(true);
                        msg = result;
            }
            else             if (e instanceof org.apache.airavata.model.error.AiravataSystemException) {
                        result.ase = (org.apache.airavata.model.error.AiravataSystemException) e;
                        result.setAseIsSet(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 
            {
              msgType = org.apache.thrift.protocol.TMessageType.EXCEPTION;
              msg = (org.apache.thrift.TBase)new org.apache.thrift.TApplicationException(org.apache.thrift.TApplicationException.INTERNAL_ERROR, e.getMessage());
            }
            try {
              fcall.sendResponse(fb,msg,msgType,seqid);
              return;
            } catch (Exception ex) {
              LOGGER.error("Exception writing to internal frame buffer", ex);
            }
            fb.close();
          }
        };
      }

      protected boolean isOneway() {
        return false;
      }

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

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

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

      public AsyncMethodCallback<Void> getResultHandler(final AsyncFrameBuffer fb, final int seqid) {
        final org.apache.thrift.AsyncProcessFunction fcall = this;
        return new AsyncMethodCallback<Void>() { 
          public void onComplete(Void o) {
            updateGateway_result result = new updateGateway_result();
            try {
              fcall.sendResponse(fb,result, org.apache.thrift.protocol.TMessageType.REPLY,seqid);
              return;
            } catch (Exception e) {
              LOGGER.error("Exception writing to internal frame buffer", e);
            }
            fb.close();
          }
          public void onError(Exception e) {
            byte msgType = org.apache.thrift.protocol.TMessageType.REPLY;
            org.apache.thrift.TBase msg;
            updateGateway_result result = new updateGateway_result();
            if (e instanceof org.apache.airavata.model.error.InvalidRequestException) {
                        result.ire = (org.apache.airavata.model.error.InvalidRequestException) e;
                        result.setIreIsSet(true);
                        msg = result;
            }
            else             if (e instanceof org.apache.airavata.model.error.AiravataClientException) {
                        result.ace = (org.apache.airavata.model.error.AiravataClientException) e;
                        result.setAceIsSet(true);
                        msg = result;
            }
            else             if (e instanceof org.apache.airavata.model.error.AiravataSystemException) {
                        result.ase = (org.apache.airavata.model.error.AiravataSystemException) e;
                        result.setAseIsSet(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 
            {
              msgType = org.apache.thrift.protocol.TMessageType.EXCEPTION;
              msg = (org.apache.thrift.TBase)new org.apache.thrift.TApplicationException(org.apache.thrift.TApplicationException.INTERNAL_ERROR, e.getMessage());
            }
            try {
              fcall.sendResponse(fb,msg,msgType,seqid);
              return;
            } catch (Exception ex) {
              LOGGER.error("Exception writing to internal frame buffer", ex);
            }
            fb.close();
          }
        };
      }

      protected boolean isOneway() {
        return false;
      }

      public void start(I iface, updateGateway_args args, org.apache.thrift.async.AsyncMethodCallback<Void> resultHandler) throws TException {
        iface.updateGateway(args.authzToken, args.gatewayId, 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 AsyncMethodCallback<org.apache.airavata.model.workspace.Gateway> getResultHandler(final AsyncFrameBuffer fb, final int seqid) {
        final org.apache.thrift.AsyncProcessFunction fcall = this;
        return new 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);
              return;
            } catch (Exception e) {
              LOGGER.error("Exception writing to internal frame buffer", e);
            }
            fb.close();
          }
          public void onError(Exception e) {
            byte msgType = org.apache.thrift.protocol.TMessageType.REPLY;
            org.apache.thrift.TBase msg;
            getGateway_result result = new getGateway_result();
            if (e instanceof org.apache.airavata.model.error.InvalidRequestException) {
                        result.ire = (org.apache.airavata.model.error.InvalidRequestException) e;
                        result.setIreIsSet(true);
                        msg = result;
            }
            else             if (e instanceof org.apache.airavata.model.error.AiravataClientException) {
                        result.ace = (org.apache.airavata.model.error.AiravataClientException) e;
                        result.setAceIsSet(true);
                        msg = result;
            }
            else             if (e instanceof org.apache.airavata.model.error.AiravataSystemException) {
                        result.ase = (org.apache.airavata.model.error.AiravataSystemException) e;
                        result.setAseIsSet(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 
            {
              msgType = org.apache.thrift.protocol.TMessageType.EXCEPTION;
              msg = (org.apache.thrift.TBase)new org.apache.thrift.TApplicationException(org.apache.thrift.TApplicationException.INTERNAL_ERROR, e.getMessage());
            }
            try {
              fcall.sendResponse(fb,msg,msgType,seqid);
              return;
            } catch (Exception ex) {
              LOGGER.error("Exception writing to internal frame buffer", ex);
            }
            fb.close();
          }
        };
      }

      protected boolean isOneway() {
        return false;
      }

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

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

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

      public AsyncMethodCallback<Boolean> getResultHandler(final AsyncFrameBuffer fb, final int seqid) {
        final org.apache.thrift.AsyncProcessFunction fcall = this;
        return new AsyncMethodCallback<Boolean>() { 
          public void onComplete(Boolean o) {
            deleteGateway_result result = new deleteGateway_result();
            result.success = o;
            result.setSuccessIsSet(true);
            try {
              fcall.sendResponse(fb,result, org.apache.thrift.protocol.TMessageType.REPLY,seqid);
              return;
            } catch (Exception e) {
              LOGGER.error("Exception writing to internal frame buffer", e);
            }
            fb.close();
          }
          public void onError(Exception e) {
            byte msgType = org.apache.thrift.protocol.TMessageType.REPLY;
            org.apache.thrift.TBase msg;
            deleteGateway_result result = new deleteGateway_result();
            if (e instanceof org.apache.airavata.model.error.InvalidRequestException) {
                        result.ire = (org.apache.airavata.model.error.InvalidRequestException) e;
                        result.setIreIsSet(true);
                        msg = result;
            }
            else             if (e instanceof org.apache.airavata.model.error.AiravataClientException) {
                        result.ace = (org.apache.airavata.model.error.AiravataClientException) e;
                        result.setAceIsSet(true);
                        msg = result;
            }
            else             if (e instanceof org.apache.airavata.model.error.AiravataSystemException) {
                        result.ase = (org.apache.airavata.model.error.AiravataSystemException) e;
                        result.setAseIsSet(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 
            {
              msgType = org.apache.thrift.protocol.TMessageType.EXCEPTION;
              msg = (org.apache.thrift.TBase)new org.apache.thrift.TApplicationException(org.apache.thrift.TApplicationException.INTERNAL_ERROR, e.getMessage());
            }
            try {
              fcall.sendResponse(fb,msg,msgType,seqid);
              return;
            } catch (Exception ex) {
              LOGGER.error("Exception writing to internal frame buffer", ex);
            }
            fb.close();
          }
        };
      }

      protected boolean isOneway() {
        return false;
      }

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

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

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

      public AsyncMethodCallback<List<org.apache.airavata.model.workspace.Gateway>> getResultHandler(final AsyncFrameBuffer fb, final int seqid) {
        final org.apache.thrift.AsyncProcessFunction fcall = this;
        return new AsyncMethodCallback<List<org.apache.airavata.model.workspace.Gateway>>() { 
          public void onComplete(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);
              return;
            } catch (Exception e) {
              LOGGER.error("Exception writing to internal frame buffer", e);
            }
            fb.close();
          }
          public void onError(Exception e) {
            byte msgType = org.apache.thrift.protocol.TMessageType.REPLY;
            org.apache.thrift.TBase msg;
            getAllGateways_result result = new getAllGateways_result();
            if (e instanceof org.apache.airavata.model.error.InvalidRequestException) {
                        result.ire = (org.apache.airavata.model.error.InvalidRequestException) e;
                        result.setIreIsSet(true);
                        msg = result;
            }
            else             if (e instanceof org.apache.airavata.model.error.AiravataClientException) {
                        result.ace = (org.apache.airavata.model.error.AiravataClientException) e;
                        result.setAceIsSet(true);
                        msg = result;
            }
            else             if (e instanceof org.apache.airavata.model.error.AiravataSystemException) {
                        result.ase = (org.apache.airavata.model.error.AiravataSystemException) e;
                        result.setAseIsSet(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 
            {
              msgType = org.apache.thrift.protocol.TMessageType.EXCEPTION;
              msg = (org.apache.thrift.TBase)new org.apache.thrift.TApplicationException(org.apache.thrift.TApplicationException.INTERNAL_ERROR, e.getMessage());
            }
            try {
              fcall.sendResponse(fb,msg,msgType,seqid);
              return;
            } catch (Exception ex) {
              LOGGER.error("Exception writing to internal frame buffer", ex);
            }
            fb.close();
          }
        };
      }

      protected boolean isOneway() {
        return false;
      }

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

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

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

      public AsyncMethodCallback<Boolean> getResultHandler(final AsyncFrameBuffer fb, final int seqid) {
        final org.apache.thrift.AsyncProcessFunction fcall = this;
        return new AsyncMethodCallback<Boolean>() { 
          public void onComplete(Boolean o) {
            isGatewayExist_result result = new isGatewayExist_result();
            result.success = o;
            result.setSuccessIsSet(true);
            try {
              fcall.sendResponse(fb,result, org.apache.thrift.protocol.TMessageType.REPLY,seqid);
              return;
            } catch (Exception e) {
              LOGGER.error("Exception writing to internal frame buffer", e);
            }
            fb.close();
          }
          public void onError(Exception e) {
            byte msgType = org.apache.thrift.protocol.TMessageType.REPLY;
            org.apache.thrift.TBase msg;
            isGatewayExist_result result = new isGatewayExist_result();
            if (e instanceof org.apache.airavata.model.error.InvalidRequestException) {
                        result.ire = (org.apache.airavata.model.error.InvalidRequestException) e;
                        result.setIreIsSet(true);
                        msg = result;
            }
            else             if (e instanceof org.apache.airavata.model.error.AiravataClientException) {
                        result.ace = (org.apache.airavata.model.error.AiravataClientException) e;
                        result.setAceIsSet(true);
                        msg = result;
            }
            else             if (e instanceof org.apache.airavata.model.error.AiravataSystemException) {
                        result.ase = (org.apache.airavata.model.error.AiravataSystemException) e;
                        result.setAseIsSet(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 
            {
              msgType = org.apache.thrift.protocol.TMessageType.EXCEPTION;
              msg = (org.apache.thrift.TBase)new org.apache.thrift.TApplicationException(org.apache.thrift.TApplicationException.INTERNAL_ERROR, e.getMessage());
            }
            try {
              fcall.sendResponse(fb,msg,msgType,seqid);
              return;
            } catch (Exception ex) {
              LOGGER.error("Exception writing to internal frame buffer", ex);
            }
            fb.close();
          }
        };
      }

      protected boolean isOneway() {
        return false;
      }

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

    public static class generateAndRegisterSSHKeys<I extends AsyncIface> extends org.apache.thrift.AsyncProcessFunction<I, generateAndRegisterSSHKeys_args, String> {
      public generateAndRegisterSSHKeys() {
        super("generateAndRegisterSSHKeys");
      }

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

      public AsyncMethodCallback<String> getResultHandler(final AsyncFrameBuffer fb, final int seqid) {
        final org.apache.thrift.AsyncProcessFunction fcall = this;
        return new AsyncMethodCallback<String>() { 
          public void onComplete(String o) {
            generateAndRegisterSSHKeys_result result = new generateAndRegisterSSHKeys_result();
            result.success = o;
            try {
              fcall.sendResponse(fb,result, org.apache.thrift.protocol.TMessageType.REPLY,seqid);
              return;
            } catch (Exception e) {
              LOGGER.error("Exception writing to internal frame buffer", e);
            }
            fb.close();
          }
          public void onError(Exception e) {
            byte msgType = org.apache.thrift.protocol.TMessageType.REPLY;
            org.apache.thrift.TBase msg;
            generateAndRegisterSSHKeys_result result = new generateAndRegisterSSHKeys_result();
            if (e instanceof org.apache.airavata.model.error.InvalidRequestException) {
                        result.ire = (org.apache.airavata.model.error.InvalidRequestException) e;
                        result.setIreIsSet(true);
                        msg = result;
            }
            else             if (e instanceof org.apache.airavata.model.error.AiravataClientException) {
                        result.ace = (org.apache.airavata.model.error.AiravataClientException) e;
                        result.setAceIsSet(true);
                        msg = result;
            }
            else             if (e instanceof org.apache.airavata.model.error.AiravataSystemException) {
                        result.ase = (org.apache.airavata.model.error.AiravataSystemException) e;
                        result.setAseIsSet(true);
                        msg = result;
            }
             else 
            {
              msgType = org.apache.thrift.protocol.TMessageType.EXCEPTION;
              msg = (org.apache.thrift.TBase)new org.apache.thrift.TApplicationException(org.apache.thrift.TApplicationException.INTERNAL_ERROR, e.getMessage());
            }
            try {
              fcall.sendResponse(fb,msg,msgType,seqid);
              return;
            } catch (Exception ex) {
              LOGGER.error("Exception writing to internal frame buffer", ex);
            }
            fb.close();
          }
        };
      }

      protected boolean isOneway() {
        return false;
      }

      public void start(I iface, generateAndRegisterSSHKeys_args args, org.apache.thrift.async.AsyncMethodCallback<String> resultHandler) throws TException {
        iface.generateAndRegisterSSHKeys(args.authzToken, args.gatewayId, args.userName,resultHandler);
      }
    }

    public static class getSSHPubKey<I extends AsyncIface> extends org.apache.thrift.AsyncProcessFunction<I, getSSHPubKey_args, String> {
      public getSSHPubKey() {
        super("getSSHPubKey");
      }

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

      public AsyncMethodCallback<String> getResultHandler(final AsyncFrameBuffer fb, final int seqid) {
        final org.apache.thrift.AsyncProcessFunction fcall = this;
        return new AsyncMethodCallback<String>() { 
          public void onComplete(String o) {
            getSSHPubKey_result result = new getSSHPubKey_result();
            result.success = o;
            try {
              fcall.sendResponse(fb,result, org.apache.thrift.protocol.TMessageType.REPLY,seqid);
              return;
            } catch (Exception e) {
              LOGGER.error("Exception writing to internal frame buffer", e);
            }
            fb.close();
          }
          public void onError(Exception e) {
            byte msgType = org.apache.thrift.protocol.TMessageType.REPLY;
            org.apache.thrift.TBase msg;
            getSSHPubKey_result result = new getSSHPubKey_result();
            if (e instanceof org.apache.airavata.model.error.InvalidRequestException) {
                        result.ire = (org.apache.airavata.model.error.InvalidRequestException) e;
                        result.setIreIsSet(true);
                        msg = result;
            }
            else             if (e instanceof org.apache.airavata.model.error.AiravataClientException) {
                        result.ace = (org.apache.airavata.model.error.AiravataClientException) e;
                        result.setAceIsSet(true);
                        msg = result;
            }
            else             if (e instanceof org.apache.airavata.model.error.AiravataSystemException) {
                        result.ase = (org.apache.airavata.model.error.AiravataSystemException) e;
                        result.setAseIsSet(true);
                        msg = result;
            }
             else 
            {
              msgType = org.apache.thrift.protocol.TMessageType.EXCEPTION;
              msg = (org.apache.thrift.TBase)new org.apache.thrift.TApplicationException(org.apache.thrift.TApplicationException.INTERNAL_ERROR, e.getMessage());
            }
            try {
              fcall.sendResponse(fb,msg,msgType,seqid);
              return;
            } catch (Exception ex) {
              LOGGER.error("Exception writing to internal frame buffer", ex);
            }
            fb.close();
          }
        };
      }

      protected boolean isOneway() {
        return false;
      }

      public void start(I iface, getSSHPubKey_args args, org.apache.thrift.async.AsyncMethodCallback<String> resultHandler) throws TException {
        iface.getSSHPubKey(args.authzToken, args.airavataCredStoreToken, args.gatewayId,resultHandler);
      }
    }

    public static class getAllUserSSHPubKeys<I extends AsyncIface> extends org.apache.thrift.AsyncProcessFunction<I, getAllUserSSHPubKeys_args, Map<String,String>> {
      public getAllUserSSHPubKeys() {
        super("getAllUserSSHPubKeys");
      }

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

      public AsyncMethodCallback<Map<String,String>> getResultHandler(final AsyncFrameBuffer fb, final int seqid) {
        final org.apache.thrift.AsyncProcessFunction fcall = this;
        return new AsyncMethodCallback<Map<String,String>>() { 
          public void onComplete(Map<String,String> o) {
            getAllUserSSHPubKeys_result result = new getAllUserSSHPubKeys_result();
            result.success = o;
            try {
              fcall.sendResponse(fb,result, org.apache.thrift.protocol.TMessageType.REPLY,seqid);
              return;
            } catch (Exception e) {
              LOGGER.error("Exception writing to internal frame buffer", e);
            }
            fb.close();
          }
          public void onError(Exception e) {
            byte msgType = org.apache.thrift.protocol.TMessageType.REPLY;
            org.apache.thrift.TBase msg;
            getAllUserSSHPubKeys_result result = new getAllUserSSHPubKeys_result();
            if (e instanceof org.apache.airavata.model.error.InvalidRequestException) {
                        result.ire = (org.apache.airavata.model.error.InvalidRequestException) e;
                        result.setIreIsSet(true);
                        msg = result;
            }
            else             if (e instanceof org.apache.airavata.model.error.AiravataClientException) {
                        result.ace = (org.apache.airavata.model.error.AiravataClientException) e;
                        result.setAceIsSet(true);
                        msg = result;
            }
            else             if (e instanceof org.apache.airavata.model.error.AiravataSystemException) {
                        result.ase = (org.apache.airavata.model.error.AiravataSystemException) e;
                        result.setAseIsSet(true);
                        msg = result;
            }
             else 
            {
              msgType = org.apache.thrift.protocol.TMessageType.EXCEPTION;
              msg = (org.apache.thrift.TBase)new org.apache.thrift.TApplicationException(org.apache.thrift.TApplicationException.INTERNAL_ERROR, e.getMessage());
            }
            try {
              fcall.sendResponse(fb,msg,msgType,seqid);
              return;
            } catch (Exception ex) {
              LOGGER.error("Exception writing to internal frame buffer", ex);
            }
            fb.close();
          }
        };
      }

      protected boolean isOneway() {
        return false;
      }

      public void start(I iface, getAllUserSSHPubKeys_args args, org.apache.thrift.async.AsyncMethodCallback<Map<String,String>> resultHandler) throws TException {
        iface.getAllUserSSHPubKeys(args.authzToken, args.userName,resultHandler);
      }
    }

    public static class createProject<I extends AsyncIface> extends org.apache.thrift.AsyncProcessFunction<I, createProject_args, String> {
      public createProject() {
        super("createProject");
      }

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

      public AsyncMethodCallback<String> getResultHandler(final AsyncFrameBuffer fb, final int seqid) {
        final org.apache.thrift.AsyncProcessFunction fcall = this;
        return new AsyncMethodCallback<String>() { 
          public void onComplete(String o) {
            createProject_result result = new createProject_result();
            result.success = o;
            try {
              fcall.sendResponse(fb,result, org.apache.thrift.protocol.TMessageType.REPLY,seqid);
              return;
            } catch (Exception e) {
              LOGGER.error("Exception writing to internal frame buffer", e);
            }
            fb.close();
          }
          public void onError(Exception e) {
            byte msgType = org.apache.thrift.protocol.TMessageType.REPLY;
            org.apache.thrift.TBase msg;
            createProject_result result = new createProject_result();
            if (e instanceof org.apache.airavata.model.error.InvalidRequestException) {
                        result.ire = (org.apache.airavata.model.error.InvalidRequestException) e;
                        result.setIreIsSet(true);
                        msg = result;
            }
            else             if (e instanceof org.apache.airavata.model.error.AiravataClientException) {
                        result.ace = (org.apache.airavata.model.error.AiravataClientException) e;
                        result.setAceIsSet(true);
                        msg = result;
            }
            else             if (e instanceof org.apache.airavata.model.error.AiravataSystemException) {
                        result.ase = (org.apache.airavata.model.error.AiravataSystemException) e;
                        result.setAseIsSet(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 
            {
              msgType = org.apache.thrift.protocol.TMessageType.EXCEPTION;
              msg = (org.apache.thrift.TBase)new org.apache.thrift.TApplicationException(org.apache.thrift.TApplicationException.INTERNAL_ERROR, e.getMessage());
            }
            try {
              fcall.sendResponse(fb,msg,msgType,seqid);
              return;
            } catch (Exception ex) {
              LOGGER.error("Exception writing to internal frame buffer", ex);
            }
            fb.close();
          }
        };
      }

      protected boolean isOneway() {
        return false;
      }

      public void start(I iface, createProject_args args, org.apache.thrift.async.AsyncMethodCallback<String> resultHandler) throws TException {
        iface.createProject(args.authzToken, args.gatewayId, args.project,resultHandler);
      }
    }

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

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

      public AsyncMethodCallback<Void> getResultHandler(final AsyncFrameBuffer fb, final int seqid) {
        final org.apache.thrift.AsyncProcessFunction fcall = this;
        return new AsyncMethodCallback<Void>() { 
          public void onComplete(Void o) {
            updateProject_result result = new updateProject_result();
            try {
              fcall.sendResponse(fb,result, org.apache.thrift.protocol.TMessageType.REPLY,seqid);
              return;
            } catch (Exception e) {
              LOGGER.error("Exception writing to internal frame buffer", e);
            }
            fb.close();
          }
          public void onError(Exception e) {
            byte msgType = org.apache.thrift.protocol.TMessageType.REPLY;
            org.apache.thrift.TBase msg;
            updateProject_result result = new updateProject_result();
            if (e instanceof org.apache.airavata.model.error.InvalidRequestException) {
                        result.ire = (org.apache.airavata.model.error.InvalidRequestException) e;
                        result.setIreIsSet(true);
                        msg = result;
            }
            else             if (e instanceof org.apache.airavata.model.error.AiravataClientException) {
                        result.ace = (org.apache.airavata.model.error.AiravataClientException) e;
                        result.setAceIsSet(true);
                        msg = result;
            }
            else             if (e instanceof org.apache.airavata.model.error.AiravataSystemException) {
                        result.ase = (org.apache.airavata.model.error.AiravataSystemException) e;
                        result.setAseIsSet(true);
                        msg = result;
            }
            else             if (e instanceof org.apache.airavata.model.error.ProjectNotFoundException) {
                        result.pnfe = (org.apache.airavata.model.error.ProjectNotFoundException) e;
                        result.setPnfeIsSet(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 
            {
              msgType = org.apache.thrift.protocol.TMessageType.EXCEPTION;
              msg = (org.apache.thrift.TBase)new org.apache.thrift.TApplicationException(org.apache.thrift.TApplicationException.INTERNAL_ERROR, e.getMessage());
            }
            try {
              fcall.sendResponse(fb,msg,msgType,seqid);
              return;
            } catch (Exception ex) {
              LOGGER.error("Exception writing to internal frame buffer", ex);
            }
            fb.close();
          }
        };
      }

      protected boolean isOneway() {
        return false;
      }

      public void start(I iface, updateProject_args args, org.apache.thrift.async.AsyncMethodCallback<Void> resultHandler) throws TException {
        iface.updateProject(args.authzToken, args.projectId, args.updatedProject,resultHandler);
      }
    }

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

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

      public AsyncMethodCallback<org.apache.airavata.model.workspace.Project> getResultHandler(final AsyncFrameBuffer fb, final int seqid) {
        final org.apache.thrift.AsyncProcessFunction fcall = this;
        return new AsyncMethodCallback<org.apache.airavata.model.workspace.Project>() { 
          public void onComplete(org.apache.airavata.model.workspace.Project o) {
            getProject_result result = new getProject_result();
            result.success = o;
            try {
              fcall.sendResponse(fb,result, org.apache.thrift.protocol.TMessageType.REPLY,seqid);
              return;
            } catch (Exception e) {
              LOGGER.error("Exception writing to internal frame buffer", e);
            }
            fb.close();
          }
          public void onError(Exception e) {
            byte msgType = org.apache.thrift.protocol.TMessageType.REPLY;
            org.apache.thrift.TBase msg;
            getProject_result result = new getProject_result();
            if (e instanceof org.apache.airavata.model.error.InvalidRequestException) {
                        result.ire = (org.apache.airavata.model.error.InvalidRequestException) e;
                        result.setIreIsSet(true);
                        msg = result;
            }
            else             if (e instanceof org.apache.airavata.model.error.AiravataClientException) {
                        result.ace = (org.apache.airavata.model.error.AiravataClientException) e;
                        result.setAceIsSet(true);
                        msg = result;
            }
            else             if (e instanceof org.apache.airavata.model.error.AiravataSystemException) {
                        result.ase = (org.apache.airavata.model.error.AiravataSystemException) e;
                        result.setAseIsSet(true);
                        msg = result;
            }
            else             if (e instanceof org.apache.airavata.model.error.ProjectNotFoundException) {
                        result.pnfe = (org.apache.airavata.model.error.ProjectNotFoundException) e;
                        result.setPnfeIsSet(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 
            {
              msgType = org.apache.thrift.protocol.TMessageType.EXCEPTION;
              msg = (org.apache.thrift.TBase)new org.apache.thrift.TApplicationException(org.apache.thrift.TApplicationException.INTERNAL_ERROR, e.getMessage());
            }
            try {
              fcall.sendResponse(fb,msg,msgType,seqid);
              return;
            } catch (Exception ex) {
              LOGGER.error("Exception writing to internal frame buffer", ex);
            }
            fb.close();
          }
        };
      }

      protected boolean isOneway() {
        return false;
      }

      public void start(I iface, getProject_args args, org.apache.thrift.async.AsyncMethodCallback<org.apache.airavata.model.workspace.Project> resultHandler) throws TException {
        iface.getProject(args.authzToken, args.projectId,resultHandler);
      }
    }

    public static class deleteProject<I extends AsyncIface> extends org.apache.thrift.AsyncProcessFunction<I, deleteProject_args, Boolean> {
      public deleteProject() {
        super("deleteProject");
      }

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

      public AsyncMethodCallback<Boolean> getResultHandler(final AsyncFrameBuffer fb, final int seqid) {
        final org.apache.thrift.AsyncProcessFunction fcall = this;
        return new AsyncMethodCallback<Boolean>() { 
          public void onComplete(Boolean o) {
            deleteProject_result result = new deleteProject_result();
            result.success = o;
            result.setSuccessIsSet(true);
            try {
              fcall.sendResponse(fb,result, org.apache.thrift.protocol.TMessageType.REPLY,seqid);
              return;
            } catch (Exception e) {
              LOGGER.error("Exception writing to internal frame buffer", e);
            }
            fb.close();
          }
          public void onError(Exception e) {
            byte msgType = org.apache.thrift.protocol.TMessageType.REPLY;
            org.apache.thrift.TBase msg;
            deleteProject_result result = new deleteProject_result();
            if (e instanceof org.apache.airavata.model.error.InvalidRequestException) {
                        result.ire = (org.apache.airavata.model.error.InvalidRequestException) e;
                        result.setIreIsSet(true);
                        msg = result;
            }
            else             if (e instanceof org.apache.airavata.model.error.AiravataClientException) {
                        result.ace = (org.apache.airavata.model.error.AiravataClientException) e;
                        result.setAceIsSet(true);
                        msg = result;
            }
            else             if (e instanceof org.apache.airavata.model.error.AiravataSystemException) {
                        result.ase = (org.apache.airavata.model.error.AiravataSystemException) e;
                        result.setAseIsSet(true);
                        msg = result;
            }
            else             if (e instanceof org.apache.airavata.model.error.ProjectNotFoundException) {
                        result.pnfe = (org.apache.airavata.model.error.ProjectNotFoundException) e;
                        result.setPnfeIsSet(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 
            {
              msgType = org.apache.thrift.protocol.TMessageType.EXCEPTION;
              msg = (org.apache.thrift.TBase)new org.apache.thrift.TApplicationException(org.apache.thrift.TApplicationException.INTERNAL_ERROR, e.getMessage());
            }
            try {
              fcall.sendResponse(fb,msg,msgType,seqid);
              return;
            } catch (Exception ex) {
              LOGGER.error("Exception writing to internal frame buffer", ex);
            }
            fb.close();
          }
        };
      }

      protected boolean isOneway() {
        return false;
      }

      public void start(I iface, deleteProject_args args, org.apache.thrift.async.AsyncMethodCallback<Boolean> resultHandler) throws TException {
        iface.deleteProject(args.authzToken, args.projectId,resultHandler);
      }
    }

    public static class getUserProjects<I extends AsyncIface> extends org.apache.thrift.AsyncProcessFunction<I, getUserProjects_args, List<org.apache.airavata.model.workspace.Project>> {
      public getUserProjects() {
        super("getUserProjects");
      }

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

      public AsyncMethodCallback<List<org.apache.airavata.model.workspace.Project>> getResultHandler(final AsyncFrameBuffer fb, final int seqid) {
        final org.apache.thrift.AsyncProcessFunction fcall = this;
        return new AsyncMethodCallback<List<org.apache.airavata.model.workspace.Project>>() { 
          public void onComplete(List<org.apache.airavata.model.workspace.Project> o) {
            getUserProjects_result result = new getUserProjects_result();
            result.success = o;
            try {
              fcall.sendResponse(fb,result, org.apache.thrift.protocol.TMessageType.REPLY,seqid);
              return;
            } catch (Exception e) {
              LOGGER.error("Exception writing to internal frame buffer", e);
            }
            fb.close();
          }
          public void onError(Exception e) {
            byte msgType = org.apache.thrift.protocol.TMessageType.REPLY;
            org.apache.thrift.TBase msg;
            getUserProjects_result result = new getUserProjects_result();
            if (e instanceof org.apache.airavata.model.error.InvalidRequestException) {
                        result.ire = (org.apache.airavata.model.error.InvalidRequestException) e;
                        result.setIreIsSet(true);
                        msg = result;
            }
            else             if (e instanceof org.apache.airavata.model.error.AiravataClientException) {
                        result.ace = (org.apache.airavata.model.error.AiravataClientException) e;
                        result.setAceIsSet(true);
                        msg = result;
            }
            else             if (e instanceof org.apache.airavata.model.error.AiravataSystemException) {
                        result.ase = (org.apache.airavata.model.error.AiravataSystemException) e;
                        result.setAseIsSet(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 
            {
              msgType = org.apache.thrift.protocol.TMessageType.EXCEPTION;
              msg = (org.apache.thrift.TBase)new org.apache.thrift.TApplicationException(org.apache.thrift.TApplicationException.INTERNAL_ERROR, e.getMessage());
            }
            try {
              fcall.sendResponse(fb,msg,msgType,seqid);
              return;
            } catch (Exception ex) {
              LOGGER.error("Exception writing to internal frame buffer", ex);
            }
            fb.close();
          }
        };
      }

      protected boolean isOneway() {
        return false;
      }

      public void start(I iface, getUserProjects_args args, org.apache.thrift.async.AsyncMethodCallback<List<org.apache.airavata.model.workspace.Project>> resultHandler) throws TException {
        iface.getUserProjects(args.authzToken, args.gatewayId, args.userName, args.limit, args.offset,resultHandler);
      }
    }

    public static class searchProjectsByProjectName<I extends AsyncIface> extends org.apache.thrift.AsyncProcessFunction<I, searchProjectsByProjectName_args, List<org.apache.airavata.model.workspace.Project>> {
      public searchProjectsByProjectName() {
        super("searchProjectsByProjectName");
      }

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

      public AsyncMethodCallback<List<org.apache.airavata.model.workspace.Project>> getResultHandler(final AsyncFrameBuffer fb, final int seqid) {
        final org.apache.thrift.AsyncProcessFunction fcall = this;
        return new AsyncMethodCallback<List<org.apache.airavata.model.workspace.Project>>() { 
          public void onComplete(List<org.apache.airavata.model.workspace.Project> o) {
            searchProjectsByProjectName_result result = new searchProjectsByProjectName_result();
            result.success = o;
            try {
              fcall.sendResponse(fb,result, org.apache.thrift.protocol.TMessageType.REPLY,seqid);
              return;
            } catch (Exception e) {
              LOGGER.error("Exception writing to internal frame buffer", e);
            }
            fb.close();
          }
          public void onError(Exception e) {
            byte msgType = org.apache.thrift.protocol.TMessageType.REPLY;
            org.apache.thrift.TBase msg;
            searchProjectsByProjectName_result result = new searchProjectsByProjectName_result();
            if (e instanceof org.apache.airavata.model.error.InvalidRequestException) {
                        result.ire = (org.apache.airavata.model.error.InvalidRequestException) e;
                        result.setIreIsSet(true);
                        msg = result;
            }
            else             if (e instanceof org.apache.airavata.model.error.AiravataClientException) {
                        result.ace = (org.apache.airavata.model.error.AiravataClientException) e;
                        result.setAceIsSet(true);
                        msg = result;
            }
            else             if (e instanceof org.apache.airavata.model.error.AiravataSystemException) {
                        result.ase = (org.apache.airavata.model.error.AiravataSystemException) e;
                        result.setAseIsSet(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 
            {
              msgType = org.apache.thrift.protocol.TMessageType.EXCEPTION;
              msg = (org.apache.thrift.TBase)new org.apache.thrift.TApplicationException(org.apache.thrift.TApplicationException.INTERNAL_ERROR, e.getMessage());
            }
            try {
              fcall.sendResponse(fb,msg,msgType,seqid);
              return;
            } catch (Exception ex) {
              LOGGER.error("Exception writing to internal frame buffer", ex);
            }
            fb.close();
          }
        };
      }

      protected boolean isOneway() {
        return false;
      }

      public void start(I iface, searchProjectsByProjectName_args args, org.apache.thrift.async.AsyncMethodCallback<List<org.apache.airavata.model.workspace.Project>> resultHandler) throws TException {
        iface.searchProjectsByProjectName(args.authzToken, args.gatewayId, args.userName, args.projectName, args.limit, args.offset,resultHandler);
      }
    }

    public static class searchProjectsByProjectDesc<I extends AsyncIface> extends org.apache.thrift.AsyncProcessFunction<I, searchProjectsByProjectDesc_args, List<org.apache.airavata.model.workspace.Project>> {
      public searchProjectsByProjectDesc() {
        super("searchProjectsByProjectDesc");
      }

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

      public AsyncMethodCallback<List<org.apache.airavata.model.workspace.Project>> getResultHandler(final AsyncFrameBuffer fb, final int seqid) {
        final org.apache.thrift.AsyncProcessFunction fcall = this;
        return new AsyncMethodCallback<List<org.apache.airavata.model.workspace.Project>>() { 
          public void onComplete(List<org.apache.airavata.model.workspace.Project> o) {
            searchProjectsByProjectDesc_result result = new searchProjectsByProjectDesc_result();
            result.success = o;
            try {
              fcall.sendResponse(fb,result, org.apache.thrift.protocol.TMessageType.REPLY,seqid);
              return;
            } catch (Exception e) {
              LOGGER.error("Exception writing to internal frame buffer", e);
            }
            fb.close();
          }
          public void onError(Exception e) {
            byte msgType = org.apache.thrift.protocol.TMessageType.REPLY;
            org.apache.thrift.TBase msg;
            searchProjectsByProjectDesc_result result = new searchProjectsByProjectDesc_result();
            if (e instanceof org.apache.airavata.model.error.InvalidRequestException) {
                        result.ire = (org.apache.airavata.model.error.InvalidRequestException) e;
                        result.setIreIsSet(true);
                        msg = result;
            }
            else             if (e instanceof org.apache.airavata.model.error.AiravataClientException) {
                        result.ace = (org.apache.airavata.model.error.AiravataClientException) e;
                        result.setAceIsSet(true);
                        msg = result;
            }
            else             if (e instanceof org.apache.airavata.model.error.AiravataSystemException) {
                        result.ase = (org.apache.airavata.model.error.AiravataSystemException) e;
                        result.setAseIsSet(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 
            {
              msgType = org.apache.thrift.protocol.TMessageType.EXCEPTION;
              msg = (org.apache.thrift.TBase)new org.apache.thrift.TApplicationException(org.apache.thrift.TApplicationException.INTERNAL_ERROR, e.getMessage());
            }
            try {
              fcall.sendResponse(fb,msg,msgType,seqid);
              return;
            } catch (Exception ex) {
              LOGGER.error("Exception writing to internal frame buffer", ex);
            }
            fb.close();
          }
        };
      }

      protected boolean isOneway() {
        return false;
      }

      public void start(I iface, searchProjectsByProjectDesc_args args, org.apache.thrift.async.AsyncMethodCallback<List<org.apache.airavata.model.workspace.Project>> resultHandler) throws TException {
        iface.searchProjectsByProjectDesc(args.authzToken, args.gatewayId, args.userName, args.description, args.limit, args.offset,resultHandler);
      }
    }

    public static class searchExperimentsByName<I extends AsyncIface> extends org.apache.thrift.AsyncProcessFunction<I, searchExperimentsByName_args, List<org.apache.airavata.model.experiment.ExperimentSummaryModel>> {
      public searchExperimentsByName() {
        super("searchExperimentsByName");
      }

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

      public AsyncMethodCallback<List<org.apache.airavata.model.experiment.ExperimentSummaryModel>> getResultHandler(final AsyncFrameBuffer fb, final int seqid) {
        final org.apache.thrift.AsyncProcessFunction fcall = this;
        return new AsyncMethodCallback<List<org.apache.airavata.model.experiment.ExperimentSummaryModel>>() { 
          public void onComplete(List<org.apache.airavata.model.experiment.ExperimentSummaryModel> o) {
            searchExperimentsByName_result result = new searchExperimentsByName_result();
            result.success = o;
            try {
              fcall.sendResponse(fb,result, org.apache.thrift.protocol.TMessageType.REPLY,seqid);
              return;
            } catch (Exception e) {
              LOGGER.error("Exception writing to internal frame buffer", e);
            }
            fb.close();
          }
          public void onError(Exception e) {
            byte msgType = org.apache.thrift.protocol.TMessageType.REPLY;
            org.apache.thrift.TBase msg;
            searchExperimentsByName_result result = new searchExperimentsByName_result();
            if (e instanceof org.apache.airavata.model.error.InvalidRequestException) {
                        result.ire = (org.apache.airavata.model.error.InvalidRequestException) e;
                        result.setIreIsSet(true);
                        msg = result;
            }
            else             if (e instanceof org.apache.airavata.model.error.AiravataClientException) {
                        result.ace = (org.apache.airavata.model.error.AiravataClientException) e;
                        result.setAceIsSet(true);
                        msg = result;
            }
            else             if (e instanceof org.apache.airavata.model.error.AiravataSystemException) {
                        result.ase = (org.apache.airavata.model.error.AiravataSystemException) e;
                        result.setAseIsSet(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 
            {
              msgType = org.apache.thrift.protocol.TMessageType.EXCEPTION;
              msg = (org.apache.thrift.TBase)new org.apache.thrift.TApplicationException(org.apache.thrift.TApplicationException.INTERNAL_ERROR, e.getMessage());
            }
            try {
              fcall.sendResponse(fb,msg,msgType,seqid);
              return;
            } catch (Exception ex) {
              LOGGER.error("Exception writing to internal frame buffer", ex);
            }
            fb.close();
          }
        };
      }

      protected boolean isOneway() {
        return false;
      }

      public void start(I iface, searchExperimentsByName_args args, org.apache.thrift.async.AsyncMethodCallback<List<org.apache.airavata.model.experiment.ExperimentSummaryModel>> resultHandler) throws TException {
        iface.searchExperimentsByName(args.authzToken, args.gatewayId, args.userName, args.expName, args.limit, args.offset,resultHandler);
      }
    }

    public static class searchExperimentsByDesc<I extends AsyncIface> extends org.apache.thrift.AsyncProcessFunction<I, searchExperimentsByDesc_args, List<org.apache.airavata.model.experiment.ExperimentSummaryModel>> {
      public searchExperimentsByDesc() {
        super("searchExperimentsByDesc");
      }

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

      public AsyncMethodCallback<List<org.apache.airavata.model.experiment.ExperimentSummaryModel>> getResultHandler(final AsyncFrameBuffer fb, final int seqid) {
        final org.apache.thrift.AsyncProcessFunction fcall = this;
        return new AsyncMethodCallback<List<org.apache.airavata.model.experiment.ExperimentSummaryModel>>() { 
          public void onComplete(List<org.apache.airavata.model.experiment.ExperimentSummaryModel> o) {
            searchExperimentsByDesc_result result = new searchExperimentsByDesc_result();
            result.success = o;
            try {
              fcall.sendResponse(fb,result, org.apache.thrift.protocol.TMessageType.REPLY,seqid);
              return;
            } catch (Exception e) {
              LOGGER.error("Exception writing to internal frame buffer", e);
            }
            fb.close();
          }
          public void onError(Exception e) {
            byte msgType = org.apache.thrift.protocol.TMessageType.REPLY;
            org.apache.thrift.TBase msg;
            searchExperimentsByDesc_result result = new searchExperimentsByDesc_result();
            if (e instanceof org.apache.airavata.model.error.InvalidRequestException) {
                        result.ire = (org.apache.airavata.model.error.InvalidRequestException) e;
                        result.setIreIsSet(true);
                        msg = result;
            }
            else             if (e instanceof org.apache.airavata.model.error.AiravataClientException) {
                        result.ace = (org.apache.airavata.model.error.AiravataClientException) e;
                        result.setAceIsSet(true);
                        msg = result;
            }
            else             if (e instanceof org.apache.airavata.model.error.AiravataSystemException) {
                        result.ase = (org.apache.airavata.model.error.AiravataSystemException) e;
                        result.setAseIsSet(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 
            {
              msgType = org.apache.thrift.protocol.TMessageType.EXCEPTION;
              msg = (org.apache.thrift.TBase)new org.apache.thrift.TApplicationException(org.apache.thrift.TApplicationException.INTERNAL_ERROR, e.getMessage());
            }
            try {
              fcall.sendResponse(fb,msg,msgType,seqid);
              return;
            } catch (Exception ex) {
              LOGGER.error("Exception writing to internal frame buffer", ex);
            }
            fb.close();
          }
        };
      }

      protected boolean isOneway() {
        return false;
      }

      public void start(I iface, searchExperimentsByDesc_args args, org.apache.thrift.async.AsyncMethodCallback<List<org.apache.airavata.model.experiment.ExperimentSummaryModel>> resultHandler) throws TException {
        iface.searchExperimentsByDesc(args.authzToken, args.gatewayId, args.userName, args.description, args.limit, args.offset,resultHandler);
      }
    }

    public static class searchExperimentsByApplication<I extends AsyncIface> extends org.apache.thrift.AsyncProcessFunction<I, searchExperimentsByApplication_args, List<org.apache.airavata.model.experiment.ExperimentSummaryModel>> {
      public searchExperimentsByApplication() {
        super("searchExperimentsByApplication");
      }

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

      public AsyncMethodCallback<List<org.apache.airavata.model.experiment.ExperimentSummaryModel>> getResultHandler(final AsyncFrameBuffer fb, final int seqid) {
        final org.apache.thrift.AsyncProcessFunction fcall = this;
        return new AsyncMethodCallback<List<org.apache.airavata.model.experiment.ExperimentSummaryModel>>() { 
          public void onComplete(List<org.apache.airavata.model.experiment.ExperimentSummaryModel> o) {
            searchExperimentsByApplication_result result = new searchExperimentsByApplication_result();
            result.success = o;
            try {
              fcall.sendResponse(fb,result, org.apache.thrift.protocol.TMessageType.REPLY,seqid);
              return;
            } catch (Exception e) {
              LOGGER.error("Exception writing to internal frame buffer", e);
            }
            fb.close();
          }
          public void onError(Exception e) {
            byte msgType = org.apache.thrift.protocol.TMessageType.REPLY;
            org.apache.thrift.TBase msg;
            searchExperimentsByApplication_result result = new searchExperimentsByApplication_result();
            if (e instanceof org.apache.airavata.model.error.InvalidRequestException) {
                        result.ire = (org.apache.airavata.model.error.InvalidRequestException) e;
                        result.setIreIsSet(true);
                        msg = result;
            }
            else             if (e instanceof org.apache.airavata.model.error.AiravataClientException) {
                        result.ace = (org.apache.airavata.model.error.AiravataClientException) e;
                        result.setAceIsSet(true);
                        msg = result;
            }
            else             if (e instanceof org.apache.airavata.model.error.AiravataSystemException) {
                        result.ase = (org.apache.airavata.model.error.AiravataSystemException) e;
                        result.setAseIsSet(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 
            {
              msgType = org.apache.thrift.protocol.TMessageType.EXCEPTION;
              msg = (org.apache.thrift.TBase)new org.apache.thrift.TApplicationException(org.apache.thrift.TApplicationException.INTERNAL_ERROR, e.getMessage());
            }
            try {
              fcall.sendResponse(fb,msg,msgType,seqid);
              return;
            } catch (Exception ex) {
              LOGGER.error("Exception writing to internal frame buffer", ex);
            }
            fb.close();
          }
        };
      }

      protected boolean isOneway() {
        return false;
      }

      public void start(I iface, searchExperimentsByApplication_args args, org.apache.thrift.async.AsyncMethodCallback<List<org.apache.airavata.model.experiment.ExperimentSummaryModel>> resultHandler) throws TException {
        iface.searchExperimentsByApplication(args.authzToken, args.gatewayId, args.userName, args.applicationId, args.limit, args.offset,resultHandler);
      }
    }

    public static class searchExperimentsByStatus<I extends AsyncIface> extends org.apache.thrift.AsyncProcessFunction<I, searchExperimentsByStatus_args, List<org.apache.airavata.model.experiment.ExperimentSummaryModel>> {
      public searchExperimentsByStatus() {
        super("searchExperimentsByStatus");
      }

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

      public AsyncMethodCallback<List<org.apache.airavata.model.experiment.ExperimentSummaryModel>> getResultHandler(final AsyncFrameBuffer fb, final int seqid) {
        final org.apache.thrift.AsyncProcessFunction fcall = this;
        return new AsyncMethodCallback<List<org.apache.airavata.model.experiment.ExperimentSummaryModel>>() { 
          public void onComplete(List<org.apache.airavata.model.experiment.ExperimentSummaryModel> o) {
            searchExperimentsByStatus_result result = new searchExperimentsByStatus_result();
            result.success = o;
            try {
              fcall.sendResponse(fb,result, org.apache.thrift.protocol.TMessageType.REPLY,seqid);
              return;
            } catch (Exception e) {
              LOGGER.error("Exception writing to internal frame buffer", e);
            }
            fb.close();
          }
          public void onError(Exception e) {
            byte msgType = org.apache.thrift.protocol.TMessageType.REPLY;
            org.apache.thrift.TBase msg;
            searchExperimentsByStatus_result result = new searchExperimentsByStatus_result();
            if (e instanceof org.apache.airavata.model.error.InvalidRequestException) {
                        result.ire = (org.apache.airavata.model.error.InvalidRequestException) e;
                        result.setIreIsSet(true);
                        msg = result;
            }
            else             if (e instanceof org.apache.airavata.model.error.AiravataClientException) {
                        result.ace = (org.apache.airavata.model.error.AiravataClientException) e;
                        result.setAceIsSet(true);
                        msg = result;
            }
            else             if (e instanceof org.apache.airavata.model.error.AiravataSystemException) {
                        result.ase = (org.apache.airavata.model.error.AiravataSystemException) e;
                        result.setAseIsSet(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 
            {
              msgType = org.apache.thrift.protocol.TMessageType.EXCEPTION;
              msg = (org.apache.thrift.TBase)new org.apache.thrift.TApplicationException(org.apache.thrift.TApplicationException.INTERNAL_ERROR, e.getMessage());
            }
            try {
              fcall.sendResponse(fb,msg,msgType,seqid);
              return;
            } catch (Exception ex) {
              LOGGER.error("Exception writing to internal frame buffer", ex);
            }
            fb.close();
          }
        };
      }

      protected boolean isOneway() {
        return false;
      }

      public void start(I iface, searchExperimentsByStatus_args args, org.apache.thrift.async.AsyncMethodCallback<List<org.apache.airavata.model.experiment.ExperimentSummaryModel>> resultHandler) throws TException {
        iface.searchExperimentsByStatus(args.authzToken, args.gatewayId, args.userName, args.experimentState, args.limit, args.offset,resultHandler);
      }
    }

    public static class searchExperimentsByCreationTime<I extends AsyncIface> extends org.apache.thrift.AsyncProcessFunction<I, searchExperimentsByCreationTime_args, List<org.apache.airavata.model.experiment.ExperimentSummaryModel>> {
      public searchExperimentsByCreationTime() {
        super("searchExperimentsByCreationTime");
      }

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

      public AsyncMethodCallback<List<org.apache.airavata.model.experiment.ExperimentSummaryModel>> getResultHandler(final AsyncFrameBuffer fb, final int seqid) {
        final org.apache.thrift.AsyncProcessFunction fcall = this;
        return new AsyncMethodCallback<List<org.apache.airavata.model.experiment.ExperimentSummaryModel>>() { 
          public void onComplete(List<org.apache.airavata.model.experiment.ExperimentSummaryModel> o) {
            searchExperimentsByCreationTime_result result = new searchExperimentsByCreationTime_result();
            result.success = o;
            try {
              fcall.sendResponse(fb,result, org.apache.thrift.protocol.TMessageType.REPLY,seqid);
              return;
            } catch (Exception e) {
              LOGGER.error("Exception writing to internal frame buffer", e);
            }
            fb.close();
          }
          public void onError(Exception e) {
            byte msgType = org.apache.thrift.protocol.TMessageType.REPLY;
            org.apache.thrift.TBase msg;
            searchExperimentsByCreationTime_result result = new searchExperimentsByCreationTime_result();
            if (e instanceof org.apache.airavata.model.error.InvalidRequestException) {
                        result.ire = (org.apache.airavata.model.error.InvalidRequestException) e;
                        result.setIreIsSet(true);
                        msg = result;
            }
            else             if (e instanceof org.apache.airavata.model.error.AiravataClientException) {
                        result.ace = (org.apache.airavata.model.error.AiravataClientException) e;
                        result.setAceIsSet(true);
                        msg = result;
            }
            else             if (e instanceof org.apache.airavata.model.error.AiravataSystemException) {
                        result.ase = (org.apache.airavata.model.error.AiravataSystemException) e;
                        result.setAseIsSet(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 
            {
              msgType = org.apache.thrift.protocol.TMessageType.EXCEPTION;
              msg = (org.apache.thrift.TBase)new org.apache.thrift.TApplicationException(org.apache.thrift.TApplicationException.INTERNAL_ERROR, e.getMessage());
            }
            try {
              fcall.sendResponse(fb,msg,msgType,seqid);
              return;
            } catch (Exception ex) {
              LOGGER.error("Exception writing to internal frame buffer", ex);
            }
            fb.close();
          }
        };
      }

      protected boolean isOneway() {
        return false;
      }

      public void start(I iface, searchExperimentsByCreationTime_args args, org.apache.thrift.async.AsyncMethodCallback<List<org.apache.airavata.model.experiment.ExperimentSummaryModel>> resultHandler) throws TException {
        iface.searchExperimentsByCreationTime(args.authzToken, args.gatewayId, args.userName, args.fromTime, args.toTime, args.limit, args.offset,resultHandler);
      }
    }

    public static class searchExperiments<I extends AsyncIface> extends org.apache.thrift.AsyncProcessFunction<I, searchExperiments_args, List<org.apache.airavata.model.experiment.ExperimentSummaryModel>> {
      public searchExperiments() {
        super("searchExperiments");
      }

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

      public AsyncMethodCallback<List<org.apache.airavata.model.experiment.ExperimentSummaryModel>> getResultHandler(final AsyncFrameBuffer fb, final int seqid) {
        final org.apache.thrift.AsyncProcessFunction fcall = this;
        return new AsyncMethodCallback<List<org.apache.airavata.model.experiment.ExperimentSummaryModel>>() { 
          public void onComplete(List<org.apache.airavata.model.experiment.ExperimentSummaryModel> o) {
            searchExperiments_result result = new searchExperiments_result();
            result.success = o;
            try {
              fcall.sendResponse(fb,result, org.apache.thrift.protocol.TMessageType.REPLY,seqid);
              return;
            } catch (Exception e) {
              LOGGER.error("Exception writing to internal frame buffer", e);
            }
            fb.close();
          }
          public void onError(Exception e) {
            byte msgType = org.apache.thrift.protocol.TMessageType.REPLY;
            org.apache.thrift.TBase msg;
            searchExperiments_result result = new searchExperiments_result();
            if (e instanceof org.apache.airavata.model.error.InvalidRequestException) {
                        result.ire = (org.apache.airavata.model.error.InvalidRequestException) e;
                        result.setIreIsSet(true);
                        msg = result;
            }
            else             if (e instanceof org.apache.airavata.model.error.AiravataClientException) {
                        result.ace = (org.apache.airavata.model.error.AiravataClientException) e;
                        result.setAceIsSet(true);
                        msg = result;
            }
            else             if (e instanceof org.apache.airavata.model.error.AiravataSystemException) {
                        result.ase = (org.apache.airavata.model.error.AiravataSystemException) e;
                        result.setAseIsSet(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 
            {
              msgType = org.apache.thrift.protocol.TMessageType.EXCEPTION;
              msg = (org.apache.thrift.TBase)new org.apache.thrift.TApplicationException(org.apache.thrift.TApplicationException.INTERNAL_ERROR, e.getMessage());
            }
            try {
              fcall.sendResponse(fb,msg,msgType,seqid);
              return;
            } catch (Exception ex) {
              LOGGER.error("Exception writing to internal frame buffer", ex);
            }
            fb.close();
          }
        };
      }

      protected boolean isOneway() {
        return false;
      }

      public void start(I iface, searchExperiments_args args, org.apache.thrift.async.AsyncMethodCallback<List<org.apache.airavata.model.experiment.ExperimentSummaryModel>> resultHandler) throws TException {
        iface.searchExperiments(args.authzToken, args.gatewayId, args.userName, args.filters, args.limit, args.offset,resultHandler);
      }
    }

    public static class getExperimentStatistics<I extends AsyncIface> extends org.apache.thrift.AsyncProcessFunction<I, getExperimentStatistics_args, org.apache.airavata.model.experiment.ExperimentStatistics> {
      public getExperimentStatistics() {
        super("getExperimentStatistics");
      }

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

      public AsyncMethodCallback<org.apache.airavata.model.experiment.ExperimentStatistics> getResultHandler(final AsyncFrameBuffer fb, final int seqid) {
        final org.apache.thrift.AsyncProcessFunction fcall = this;
        return new AsyncMethodCallback<org.apache.airavata.model.experiment.ExperimentStatistics>() { 
          public void onComplete(org.apache.airavata.model.experiment.ExperimentStatistics o) {
            getExperimentStatistics_result result = new getExperimentStatistics_result();
            result.success = o;
            try {
              fcall.sendResponse(fb,result, org.apache.thrift.protocol.TMessageType.REPLY,seqid);
              return;
            } catch (Exception e) {
              LOGGER.error("Exception writing to internal frame buffer", e);
            }
            fb.close();
          }
          public void onError(Exception e) {
            byte msgType = org.apache.thrift.protocol.TMessageType.REPLY;
            org.apache.thrift.TBase msg;
            getExperimentStatistics_result result = new getExperimentStatistics_result();
            if (e instanceof org.apache.airavata.model.error.InvalidRequestException) {
                        result.ire = (org.apache.airavata.model.error.InvalidRequestException) e;
                        result.setIreIsSet(true);
                        msg = result;
            }
            else             if (e instanceof org.apache.airavata.model.error.AiravataClientException) {
                        result.ace = (org.apache.airavata.model.error.AiravataClientException) e;
                        result.setAceIsSet(true);
                        msg = result;
            }
            else             if (e instanceof org.apache.airavata.model.error.AiravataSystemException) {
                        result.ase = (org.apache.airavata.model.error.AiravataSystemException) e;
                        result.setAseIsSet(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 
            {
              msgType = org.apache.thrift.protocol.TMessageType.EXCEPTION;
              msg = (org.apache.thrift.TBase)new org.apache.thrift.TApplicationException(org.apache.thrift.TApplicationException.INTERNAL_ERROR, e.getMessage());
            }
            try {
              fcall.sendResponse(fb,msg,msgType,seqid);
              return;
            } catch (Exception ex) {
              LOGGER.error("Exception writing to internal frame buffer", ex);
            }
            fb.close();
          }
        };
      }

      protected boolean isOneway() {
        return false;
      }

      public void start(I iface, getExperimentStatistics_args args, org.apache.thrift.async.AsyncMethodCallback<org.apache.airavata.model.experiment.ExperimentStatistics> resultHandler) throws TException {
        iface.getExperimentStatistics(args.authzToken, args.gatewayId, args.fromTime, args.toTime,resultHandler);
      }
    }

    public static class getExperimentsInProject<I extends AsyncIface> extends org.apache.thrift.AsyncProcessFunction<I, getExperimentsInProject_args, List<org.apache.airavata.model.experiment.ExperimentModel>> {
      public getExperimentsInProject() {
        super("getExperimentsInProject");
      }

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

      public AsyncMethodCallback<List<org.apache.airavata.model.experiment.ExperimentModel>> getResultHandler(final AsyncFrameBuffer fb, final int seqid) {
        final org.apache.thrift.AsyncProcessFunction fcall = this;
        return new AsyncMethodCallback<List<org.apache.airavata.model.experiment.ExperimentModel>>() { 
          public void onComplete(List<org.apache.airavata.model.experiment.ExperimentModel> o) {
            getExperimentsInProject_result result = new getExperimentsInProject_result();
            result.success = o;
            try {
              fcall.sendResponse(fb,result, org.apache.thrift.protocol.TMessageType.REPLY,seqid);
              return;
            } catch (Exception e) {
              LOGGER.error("Exception writing to internal frame buffer", e);
            }
            fb.close();
          }
          public void onError(Exception e) {
            byte msgType = org.apache.thrift.protocol.TMessageType.REPLY;
            org.apache.thrift.TBase msg;
            getExperimentsInProject_result result = new getExperimentsInProject_result();
            if (e instanceof org.apache.airavata.model.error.InvalidRequestException) {
                        result.ire = (org.apache.airavata.model.error.InvalidRequestException) e;
                        result.setIreIsSet(true);
                        msg = result;
            }
            else             if (e instanceof org.apache.airavata.model.error.AiravataClientException) {
                        result.ace = (org.apache.airavata.model.error.AiravataClientException) e;
                        result.setAceIsSet(true);
                        msg = result;
            }
            else             if (e instanceof org.apache.airavata.model.error.AiravataSystemException) {
                        result.ase = (org.apache.airavata.model.error.AiravataSystemException) e;
                        result.setAseIsSet(true);
                        msg = result;
            }
            else             if (e instanceof org.apache.airavata.model.error.ProjectNotFoundException) {
                        result.pnfe = (org.apache.airavata.model.error.ProjectNotFoundException) e;
                        result.setPnfeIsSet(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 
            {
              msgType = org.apache.thrift.protocol.TMessageType.EXCEPTION;
              msg = (org.apache.thrift.TBase)new org.apache.thrift.TApplicationException(org.apache.thrift.TApplicationException.INTERNAL_ERROR, e.getMessage());
            }
            try {
              fcall.sendResponse(fb,msg,msgType,seqid);
              return;
            } catch (Exception ex) {
              LOGGER.error("Exception writing to internal frame buffer", ex);
            }
            fb.close();
          }
        };
      }

      protected boolean isOneway() {
        return false;
      }

      public void start(I iface, getExperimentsInProject_args args, org.apache.thrift.async.AsyncMethodCallback<List<org.apache.airavata.model.experiment.ExperimentModel>> resultHandler) throws TException {
        iface.getExperimentsInProject(args.authzToken, args.projectId, args.limit, args.offset,resultHandler);
      }
    }

    public static class getUserExperiments<I extends AsyncIface> extends org.apache.thrift.AsyncProcessFunction<I, getUserExperiments_args, List<org.apache.airavata.model.experiment.ExperimentModel>> {
      public getUserExperiments() {
        super("getUserExperiments");
      }

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

      public AsyncMethodCallback<List<org.apache.airavata.model.experiment.ExperimentModel>> getResultHandler(final AsyncFrameBuffer fb, final int seqid) {
        final org.apache.thrift.AsyncProcessFunction fcall = this;
        return new AsyncMethodCallback<List<org.apache.airavata.model.experiment.ExperimentModel>>() { 
          public void onComplete(List<org.apache.airavata.model.experiment.ExperimentModel> o) {
            getUserExperiments_result result = new getUserExperiments_result();
            result.success = o;
            try {
              fcall.sendResponse(fb,result, org.apache.thrift.protocol.TMessageType.REPLY,seqid);
              return;
            } catch (Exception e) {
              LOGGER.error("Exception writing to internal frame buffer", e);
            }
            fb.close();
          }
          public void onError(Exception e) {
            byte msgType = org.apache.thrift.protocol.TMessageType.REPLY;
            org.apache.thrift.TBase msg;
            getUserExperiments_result result = new getUserExperiments_result();
            if (e instanceof org.apache.airavata.model.error.InvalidRequestException) {
                        result.ire = (org.apache.airavata.model.error.InvalidRequestException) e;
                        result.setIreIsSet(true);
                        msg = result;
            }
            else             if (e instanceof org.apache.airavata.model.error.AiravataClientException) {
                        result.ace = (org.apache.airavata.model.error.AiravataClientException) e;
                        result.setAceIsSet(true);
                        msg = result;
            }
            else             if (e instanceof org.apache.airavata.model.error.AiravataSystemException) {
                        result.ase = (org.apache.airavata.model.error.AiravataSystemException) e;
                        result.setAseIsSet(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 
            {
              msgType = org.apache.thrift.protocol.TMessageType.EXCEPTION;
              msg = (org.apache.thrift.TBase)new org.apache.thrift.TApplicationException(org.apache.thrift.TApplicationException.INTERNAL_ERROR, e.getMessage());
            }
            try {
              fcall.sendResponse(fb,msg,msgType,seqid);
              return;
            } catch (Exception ex) {
              LOGGER.error("Exception writing to internal frame buffer", ex);
            }
            fb.close();
          }
        };
      }

      protected boolean isOneway() {
        return false;
      }

      public void start(I iface, getUserExperiments_args args, org.apache.thrift.async.AsyncMethodCallback<List<org.apache.airavata.model.experiment.ExperimentModel>> resultHandler) throws TException {
        iface.getUserExperiments(args.authzToken, args.gatewayId, args.userName, args.limit, args.offset,resultHandler);
      }
    }

    public static class createExperiment<I extends AsyncIface> extends org.apache.thrift.AsyncProcessFunction<I, createExperiment_args, String> {
      public createExperiment() {
        super("createExperiment");
      }

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

      public AsyncMethodCallback<String> getResultHandler(final AsyncFrameBuffer fb, final int seqid) {
        final org.apache.thrift.AsyncProcessFunction fcall = this;
        return new AsyncMethodCallback<String>() { 
          public void onComplete(String o) {
            createExperiment_result result = new createExperiment_result();
            result.success = o;
            try {
              fcall.sendResponse(fb,result, org.apache.thrift.protocol.TMessageType.REPLY,seqid);
              return;
            } catch (Exception e) {
              LOGGER.error("Exception writing to internal frame buffer", e);
            }
            fb.close();
          }
          public void onError(Exception e) {
            byte msgType = org.apache.thrift.protocol.TMessageType.REPLY;
            org.apache.thrift.TBase msg;
            createExperiment_result result = new createExperiment_result();
            if (e instanceof org.apache.airavata.model.error.InvalidRequestException) {
                        result.ire = (org.apache.airavata.model.error.InvalidRequestException) e;
                        result.setIreIsSet(true);
                        msg = result;
            }
            else             if (e instanceof org.apache.airavata.model.error.AiravataClientException) {
                        result.ace = (org.apache.airavata.model.error.AiravataClientException) e;
                        result.setAceIsSet(true);
                        msg = result;
            }
            else             if (e instanceof org.apache.airavata.model.error.AiravataSystemException) {
                        result.ase = (org.apache.airavata.model.error.AiravataSystemException) e;
                        result.setAseIsSet(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 
            {
              msgType = org.apache.thrift.protocol.TMessageType.EXCEPTION;
              msg = (org.apache.thrift.TBase)new org.apache.thrift.TApplicationException(org.apache.thrift.TApplicationException.INTERNAL_ERROR, e.getMessage());
            }
            try {
              fcall.sendResponse(fb,msg,msgType,seqid);
              return;
            } catch (Exception ex) {
              LOGGER.error("Exception writing to internal frame buffer", ex);
            }
            fb.close();
          }
        };
      }

      protected boolean isOneway() {
        return false;
      }

      public void start(I iface, createExperiment_args args, org.apache.thrift.async.AsyncMethodCallback<String> resultHandler) throws TException {
        iface.createExperiment(args.authzToken, args.gatewayId, args.experiment,resultHandler);
      }
    }

    public static class deleteExperiment<I extends AsyncIface> extends org.apache.thrift.AsyncProcessFunction<I, deleteExperiment_args, Boolean> {
      public deleteExperiment() {
        super("deleteExperiment");
      }

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

      public AsyncMethodCallback<Boolean> getResultHandler(final AsyncFrameBuffer fb, final int seqid) {
        final org.apache.thrift.AsyncProcessFunction fcall = this;
        return new AsyncMethodCallback<Boolean>() { 
          public void onComplete(Boolean o) {
            deleteExperiment_result result = new deleteExperiment_result();
            result.success = o;
            result.setSuccessIsSet(true);
            try {
              fcall.sendResponse(fb,result, org.apache.thrift.protocol.TMessageType.REPLY,seqid);
              return;
            } catch (Exception e) {
              LOGGER.error("Exception writing to internal frame buffer", e);
            }
            fb.close();
          }
          public void onError(Exception e) {
            byte msgType = org.apache.thrift.protocol.TMessageType.REPLY;
            org.apache.thrift.TBase msg;
            deleteExperiment_result result = new deleteExperiment_result();
            if (e instanceof org.apache.airavata.model.error.InvalidRequestException) {
                        result.ire = (org.apache.airavata.model.error.InvalidRequestException) e;
                        result.setIreIsSet(true);
                        msg = result;
            }
            else             if (e instanceof org.apache.airavata.model.error.AiravataClientException) {
                        result.ace = (org.apache.airavata.model.error.AiravataClientException) e;
                        result.setAceIsSet(true);
                        msg = result;
            }
            else             if (e instanceof org.apache.airavata.model.error.AiravataSystemException) {
                        result.ase = (org.apache.airavata.model.error.AiravataSystemException) e;
                        result.setAseIsSet(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 
            {
              msgType = org.apache.thrift.protocol.TMessageType.EXCEPTION;
              msg = (org.apache.thrift.TBase)new org.apache.thrift.TApplicationException(org.apache.thrift.TApplicationException.INTERNAL_ERROR, e.getMessage());
            }
            try {
              fcall.sendResponse(fb,msg,msgType,seqid);
              return;
            } catch (Exception ex) {
              LOGGER.error("Exception writing to internal frame buffer", ex);
            }
            fb.close();
          }
        };
      }

      protected boolean isOneway() {
        return false;
      }

      public void start(I iface, deleteExperiment_args args, org.apache.thrift.async.AsyncMethodCallback<Boolean> resultHandler) throws TException {
        iface.deleteExperiment(args.authzToken, args.experimentId,resultHandler);
      }
    }

    public static class getExperiment<I extends AsyncIface> extends org.apache.thrift.AsyncProcessFunction<I, getExperiment_args, org.apache.airavata.model.experiment.ExperimentModel> {
      public getExperiment() {
        super("getExperiment");
      }

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

      public AsyncMethodCallback<org.apache.airavata.model.experiment.ExperimentModel> getResultHandler(final AsyncFrameBuffer fb, final int seqid) {
        final org.apache.thrift.AsyncProcessFunction fcall = this;
        return new AsyncMethodCallback<org.apache.airavata.model.experiment.ExperimentModel>() { 
          public void onComplete(org.apache.airavata.model.experiment.ExperimentModel o) {
            getExperiment_result result = new getExperiment_result();
            result.success = o;
            try {
              fcall.sendResponse(fb,result, org.apache.thrift.protocol.TMessageType.REPLY,seqid);
              return;
            } catch (Exception e) {
              LOGGER.error("Exception writing to internal frame buffer", e);
            }
            fb.close();
          }
          public void onError(Exception e) {
            byte msgType = org.apache.thrift.protocol.TMessageType.REPLY;
            org.apache.thrift.TBase msg;
            getExperiment_result result = new getExperiment_result();
            if (e instanceof org.apache.airavata.model.error.InvalidRequestException) {
                        result.ire = (org.apache.airavata.model.error.InvalidRequestException) e;
                        result.setIreIsSet(true);
                        msg = result;
            }
            else             if (e instanceof org.apache.airavata.model.error.ExperimentNotFoundException) {
                        result.enf = (org.apache.airavata.model.error.ExperimentNotFoundException) e;
                        result.setEnfIsSet(true);
                        msg = result;
            }
            else             if (e instanceof org.apache.airavata.model.error.AiravataClientException) {
                        result.ace = (org.apache.airavata.model.error.AiravataClientException) e;
                        result.setAceIsSet(true);
                        msg = result;
            }
            else             if (e instanceof org.apache.airavata.model.error.AiravataSystemException) {
                        result.ase = (org.apache.airavata.model.error.AiravataSystemException) e;
                        result.setAseIsSet(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 
            {
              msgType = org.apache.thrift.protocol.TMessageType.EXCEPTION;
              msg = (org.apache.thrift.TBase)new org.apache.thrift.TApplicationException(org.apache.thrift.TApplicationException.INTERNAL_ERROR, e.getMessage());
            }
            try {
              fcall.sendResponse(fb,msg,msgType,seqid);
              return;
            } catch (Exception ex) {
              LOGGER.error("Exception writing to internal frame buffer", ex);
            }
            fb.close();
          }
        };
      }

      protected boolean isOneway() {
        return false;
      }

      public void start(I iface, getExperiment_args args, org.apache.thrift.async.AsyncMethodCallback<org.apache.airavata.model.experiment.ExperimentModel> resultHandler) throws TException {
        iface.getExperiment(args.authzToken, args.airavataExperimentId,resultHandler);
      }
    }

    public static class getDetailedExperimentTree<I extends AsyncIface> extends org.apache.thrift.AsyncProcessFunction<I, getDetailedExperimentTree_args, org.apache.airavata.model.experiment.ExperimentModel> {
      public getDetailedExperimentTree() {
        super("getDetailedExperimentTree");
      }

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

      public AsyncMethodCallback<org.apache.airavata.model.experiment.ExperimentModel> getResultHandler(final AsyncFrameBuffer fb, final int seqid) {
        final org.apache.thrift.AsyncProcessFunction fcall = this;
        return new AsyncMethodCallback<org.apache.airavata.model.experiment.ExperimentModel>() { 
          public void onComplete(org.apache.airavata.model.experiment.ExperimentModel o) {
            getDetailedExperimentTree_result result = new getDetailedExperimentTree_result();
            result.success = o;
            try {
              fcall.sendResponse(fb,result, org.apache.thrift.protocol.TMessageType.REPLY,seqid);
              return;
            } catch (Exception e) {
              LOGGER.error("Exception writing to internal frame buffer", e);
            }
            fb.close();
          }
          public void onError(Exception e) {
            byte msgType = org.apache.thrift.protocol.TMessageType.REPLY;
            org.apache.thrift.TBase msg;
            getDetailedExperimentTree_result result = new getDetailedExperimentTree_result();
            if (e instanceof org.apache.airavata.model.error.InvalidRequestException) {
                        result.ire = (org.apache.airavata.model.error.InvalidRequestException) e;
                        result.setIreIsSet(true);
                        msg = result;
            }
            else             if (e instanceof org.apache.airavata.model.error.ExperimentNotFoundException) {
                        result.enf = (org.apache.airavata.model.error.ExperimentNotFoundException) e;
                        result.setEnfIsSet(true);
                        msg = result;
            }
            else             if (e instanceof org.apache.airavata.model.error.AiravataClientException) {
                        result.ace = (org.apache.airavata.model.error.AiravataClientException) e;
                        result.setAceIsSet(true);
                        msg = result;
            }
            else             if (e instanceof org.apache.airavata.model.error.AiravataSystemException) {
                        result.ase = (org.apache.airavata.model.error.AiravataSystemException) e;
                        result.setAseIsSet(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 
            {
              msgType = org.apache.thrift.protocol.TMessageType.EXCEPTION;
              msg = (org.apache.thrift.TBase)new org.apache.thrift.TApplicationException(org.apache.thrift.TApplicationException.INTERNAL_ERROR, e.getMessage());
            }
            try {
              fcall.sendResponse(fb,msg,msgType,seqid);
              return;
            } catch (Exception ex) {
              LOGGER.error("Exception writing to internal frame buffer", ex);
            }
            fb.close();
          }
        };
      }

      protected boolean isOneway() {
        return false;
      }

      public void start(I iface, getDetailedExperimentTree_args args, org.apache.thrift.async.AsyncMethodCallback<org.apache.airavata.model.experiment.ExperimentModel> resultHandler) throws TException {
        iface.getDetailedExperimentTree(args.authzToken, args.airavataExperimentId,resultHandler);
      }
    }

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

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

      public AsyncMethodCallback<Void> getResultHandler(final AsyncFrameBuffer fb, final int seqid) {
        final org.apache.thrift.AsyncProcessFunction fcall = this;
        return new AsyncMethodCallback<Void>() { 
          public void onComplete(Void o) {
            updateExperiment_result result = new updateExperiment_result();
            try {
              fcall.sendResponse(fb,result, org.apache.thrift.protocol.TMessageType.REPLY,seqid);
              return;
            } catch (Exception e) {
              LOGGER.error("Exception writing to internal frame buffer", e);
            }
            fb.close();
          }
          public void onError(Exception e) {
            byte msgType = org.apache.thrift.protocol.TMessageType.REPLY;
            org.apache.thrift.TBase msg;
            updateExperiment_result result = new updateExperiment_result();
            if (e instanceof org.apache.airavata.model.error.InvalidRequestException) {
                        result.ire = (org.apache.airavata.model.error.InvalidRequestException) e;
                        result.setIreIsSet(true);
                        msg = result;
            }
            else             if (e instanceof org.apache.airavata.model.error.ExperimentNotFoundException) {
                        result.enf = (org.apache.airavata.model.error.ExperimentNotFoundException) e;
                        result.setEnfIsSet(true);
                        msg = result;
            }
            else             if (e instanceof org.apache.airavata.model.error.AiravataClientException) {
                        result.ace = (org.apache.airavata.model.error.AiravataClientException) e;
                        result.setAceIsSet(true);
                        msg = result;
            }
            else             if (e instanceof org.apache.airavata.model.error.AiravataSystemException) {
                        result.ase = (org.apache.airavata.model.error.AiravataSystemException) e;
                        result.setAseIsSet(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 
            {
              msgType = org.apache.thrift.protocol.TMessageType.EXCEPTION;
              msg = (org.apache.thrift.TBase)new org.apache.thrift.TApplicationException(org.apache.thrift.TApplicationException.INTERNAL_ERROR, e.getMessage());
            }
            try {
              fcall.sendResponse(fb,msg,msgType,seqid);
              return;
            } catch (Exception ex) {
              LOGGER.error("Exception writing to internal frame buffer", ex);
            }
            fb.close();
          }
        };
      }

      protected boolean isOneway() {
        return false;
      }

      public void start(I iface, updateExperiment_args args, org.apache.thrift.async.AsyncMethodCallback<Void> resultHandler) throws TException {
        iface.updateExperiment(args.authzToken, args.airavataExperimentId, args.experiment,resultHandler);
      }
    }

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

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

      public AsyncMethodCallback<Void> getResultHandler(final AsyncFrameBuffer fb, final int seqid) {
        final org.apache.thrift.AsyncProcessFunction fcall = this;
        return new AsyncMethodCallback<Void>() { 
          public void onComplete(Void o) {
            updateExperimentConfiguration_result result = new updateExperimentConfiguration_result();
            try {
              fcall.sendResponse(fb,result, org.apache.thrift.protocol.TMessageType.REPLY,seqid);
              return;
            } catch (Exception e) {
              LOGGER.error("Exception writing to internal frame buffer", e);
            }
            fb.close();
          }
          public void onError(Exception e) {
            byte msgType = org.apache.thrift.protocol.TMessageType.REPLY;
            org.apache.thrift.TBase msg;
            updateExperimentConfiguration_result result = new updateExperimentConfiguration_result();
            if (e instanceof org.apache.airavata.model.error.AuthorizationException) {
                        result.ae = (org.apache.airavata.model.error.AuthorizationException) e;
                        result.setAeIsSet(true);
                        msg = result;
            }
             else 
            {
              msgType = org.apache.thrift.protocol.TMessageType.EXCEPTION;
              msg = (org.apache.thrift.TBase)new org.apache.thrift.TApplicationException(org.apache.thrift.TApplicationException.INTERNAL_ERROR, e.getMessage());
            }
            try {
              fcall.sendResponse(fb,msg,msgType,seqid);
              return;
            } catch (Exception ex) {
              LOGGER.error("Exception writing to internal frame buffer", ex);
            }
            fb.close();
          }
        };
      }

      protected boolean isOneway() {
        return false;
      }

      public void start(I iface, updateExperimentConfiguration_args args, org.apache.thrift.async.AsyncMethodCallback<Void> resultHandler) throws TException {
        iface.updateExperimentConfiguration(args.authzToken, args.airavataExperimentId, args.userConfiguration,resultHandler);
      }
    }

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

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

      public AsyncMethodCallback<Void> getResultHandler(final AsyncFrameBuffer fb, final int seqid) {
        final org.apache.thrift.AsyncProcessFunction fcall = this;
        return new AsyncMethodCallback<Void>() { 
          public void onComplete(Void o) {
            updateResourceScheduleing_result result = new updateResourceScheduleing_result();
            try {
              fcall.sendResponse(fb,result, org.apache.thrift.protocol.TMessageType.REPLY,seqid);
              return;
            } catch (Exception e) {
              LOGGER.error("Exception writing to internal frame buffer", e);
            }
            fb.close();
          }
          public void onError(Exception e) {
            byte msgType = org.apache.thrift.protocol.TMessageType.REPLY;
            org.apache.thrift.TBase msg;
            updateResourceScheduleing_result result = new updateResourceScheduleing_result();
            if (e instanceof org.apache.airavata.model.error.AuthorizationException) {
                        result.ae = (org.apache.airavata.model.error.AuthorizationException) e;
                        result.setAeIsSet(true);
                        msg = result;
            }
             else 
            {
              msgType = org.apache.thrift.protocol.TMessageType.EXCEPTION;
              msg = (org.apache.thrift.TBase)new org.apache.thrift.TApplicationException(org.apache.thrift.TApplicationException.INTERNAL_ERROR, e.getMessage());
            }
            try {
              fcall.sendResponse(fb,msg,msgType,seqid);
              return;
            } catch (Exception ex) {
              LOGGER.error("Exception writing to internal frame buffer", ex);
            }
            fb.close();
          }
        };
      }

      protected boolean isOneway() {
        return false;
      }

      public void start(I iface, updateResourceScheduleing_args args, org.apache.thrift.async.AsyncMethodCallback<Void> resultHandler) throws TException {
        iface.updateResourceScheduleing(args.authzToken, args.airavataExperimentId, args.resourceScheduling,resultHandler);
      }
    }

    public static class validateExperiment<I extends AsyncIface> extends org.apache.thrift.AsyncProcessFunction<I, validateExperiment_args, Boolean> {
      public validateExperiment() {
        super("validateExperiment");
      }

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

      public AsyncMethodCallback<Boolean> getResultHandler(final AsyncFrameBuffer fb, final int seqid) {
        final org.apache.thrift.AsyncProcessFunction fcall = this;
        return new AsyncMethodCallback<Boolean>() { 
          public void onComplete(Boolean o) {
            validateExperiment_result result = new validateExperiment_result();
            result.success = o;
            result.setSuccessIsSet(true);
            try {
              fcall.sendResponse(fb,result, org.apache.thrift.protocol.TMessageType.REPLY,seqid);
              return;
            } catch (Exception e) {
              LOGGER.error("Exception writing to internal frame buffer", e);
            }
            fb.close();
          }
          public void onError(Exception e) {
            byte msgType = org.apache.thrift.protocol.TMessageType.REPLY;
            org.apache.thrift.TBase msg;
            validateExperiment_result result = new validateExperiment_result();
            if (e instanceof org.apache.airavata.model.error.InvalidRequestException) {
                        result.ire = (org.apache.airavata.model.error.InvalidRequestException) e;
                        result.setIreIsSet(true);
                        msg = result;
            }
            else             if (e instanceof org.apache.airavata.model.error.ExperimentNotFoundException) {
                        result.enf = (org.apache.airavata.model.error.ExperimentNotFoundException) e;
                        result.setEnfIsSet(true);
                        msg = result;
            }
            else             if (e instanceof org.apache.airavata.model.error.AiravataClientException) {
                        result.ace = (org.apache.airavata.model.error.AiravataClientException) e;
                        result.setAceIsSet(true);
                        msg = result;
            }
            else             if (e instanceof org.apache.airavata.model.error.AiravataSystemException) {
                        result.ase = (org.apache.airavata.model.error.AiravataSystemException) e;
                        result.setAseIsSet(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 
            {
              msgType = org.apache.thrift.protocol.TMessageType.EXCEPTION;
              msg = (org.apache.thrift.TBase)new org.apache.thrift.TApplicationException(org.apache.thrift.TApplicationException.INTERNAL_ERROR, e.getMessage());
            }
            try {
              fcall.sendResponse(fb,msg,msgType,seqid);
              return;
            } catch (Exception ex) {
              LOGGER.error("Exception writing to internal frame buffer", ex);
            }
            fb.close();
          }
        };
      }

      protected boolean isOneway() {
        return false;
      }

      public void start(I iface, validateExperiment_args args, org.apache.thrift.async.AsyncMethodCallback<Boolean> resultHandler) throws TException {
        iface.validateExperiment(args.authzToken, args.airavataExperimentId,resultHandler);
      }
    }

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

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

      public AsyncMethodCallback<Void> getResultHandler(final AsyncFrameBuffer fb, final int seqid) {
        final org.apache.thrift.AsyncProcessFunction fcall = this;
        return new AsyncMethodCallback<Void>() { 
          public void onComplete(Void o) {
            launchExperiment_result result = new launchExperiment_result();
            try {
              fcall.sendResponse(fb,result, org.apache.thrift.protocol.TMessageType.REPLY,seqid);
              return;
            } catch (Exception e) {
              LOGGER.error("Exception writing to internal frame buffer", e);
            }
            fb.close();
          }
          public void onError(Exception e) {
            byte msgType = org.apache.thrift.protocol.TMessageType.REPLY;
            org.apache.thrift.TBase msg;
            launchExperiment_result result = new launchExperiment_result();
            if (e instanceof org.apache.airavata.model.error.InvalidRequestException) {
                        result.ire = (org.apache.airavata.model.error.InvalidRequestException) e;
                        result.setIreIsSet(true);
                        msg = result;
            }
            else             if (e instanceof org.apache.airavata.model.error.ExperimentNotFoundException) {
                        result.enf = (org.apache.airavata.model.error.ExperimentNotFoundException) e;
                        result.setEnfIsSet(true);
                        msg = result;
            }
            else             if (e instanceof org.apache.airavata.model.error.AiravataClientException) {
                        result.ace = (org.apache.airavata.model.error.AiravataClientException) e;
                        result.setAceIsSet(true);
                        msg = result;
            }
            else             if (e instanceof org.apache.airavata.model.error.AiravataSystemException) {
                        result.ase = (org.apache.airavata.model.error.AiravataSystemException) e;
                        result.setAseIsSet(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 
            {
              msgType = org.apache.thrift.protocol.TMessageType.EXCEPTION;
              msg = (org.apache.thrift.TBase)new org.apache.thrift.TApplicationException(org.apache.thrift.TApplicationException.INTERNAL_ERROR, e.getMessage());
            }
            try {
              fcall.sendResponse(fb,msg,msgType,seqid);
              return;
            } catch (Exception ex) {
              LOGGER.error("Exception writing to internal frame buffer", ex);
            }
            fb.close();
          }
        };
      }

      protected boolean isOneway() {
        return false;
      }

      public void start(I iface, launchExperiment_args args, org.apache.thrift.async.AsyncMethodCallback<Void> resultHandler) throws TException {
        iface.launchExperiment(args.authzToken, args.airavataExperimentId, args.gatewayId,resultHandler);
      }
    }

    public static class getExperimentStatus<I extends AsyncIface> extends org.apache.thrift.AsyncProcessFunction<I, getExperimentStatus_args, org.apache.airavata.model.status.ExperimentStatus> {
      public getExperimentStatus() {
        super("getExperimentStatus");
      }

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

      public AsyncMethodCallback<org.apache.airavata.model.status.ExperimentStatus> getResultHandler(final AsyncFrameBuffer fb, final int seqid) {
        final org.apache.thrift.AsyncProcessFunction fcall = this;
        return new AsyncMethodCallback<org.apache.airavata.model.status.ExperimentStatus>() { 
          public void onComplete(org.apache.airavata.model.status.ExperimentStatus o) {
            getExperimentStatus_result result = new getExperimentStatus_result();
            result.success = o;
            try {
              fcall.sendResponse(fb,result, org.apache.thrift.protocol.TMessageType.REPLY,seqid);
              return;
            } catch (Exception e) {
              LOGGER.error("Exception writing to internal frame buffer", e);
            }
            fb.close();
          }
          public void onError(Exception e) {
            byte msgType = org.apache.thrift.protocol.TMessageType.REPLY;
            org.apache.thrift.TBase msg;
            getExperimentStatus_result result = new getExperimentStatus_result();
            if (e instanceof org.apache.airavata.model.error.InvalidRequestException) {
                        result.ire = (org.apache.airavata.model.error.InvalidRequestException) e;
                        result.setIreIsSet(true);
                        msg = result;
            }
            else             if (e instanceof org.apache.airavata.model.error.ExperimentNotFoundException) {
                        result.enf = (org.apache.airavata.model.error.ExperimentNotFoundException) e;
                        result.setEnfIsSet(true);
                        msg = result;
            }
            else             if (e instanceof org.apache.airavata.model.error.AiravataClientException) {
                        result.ace = (org.apache.airavata.model.error.AiravataClientException) e;
                        result.setAceIsSet(true);
                        msg = result;
            }
            else             if (e instanceof org.apache.airavata.model.error.AiravataSystemException) {
                        result.ase = (org.apache.airavata.model.error.AiravataSystemException) e;
                        result.setAseIsSet(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 
            {
              msgType = org.apache.thrift.protocol.TMessageType.EXCEPTION;
              msg = (org.apache.thrift.TBase)new org.apache.thrift.TApplicationException(org.apache.thrift.TApplicationException.INTERNAL_ERROR, e.getMessage());
            }
            try {
              fcall.sendResponse(fb,msg,msgType,seqid);
              return;
            } catch (Exception ex) {
              LOGGER.error("Exception writing to internal frame buffer", ex);
            }
            fb.close();
          }
        };
      }

      protected boolean isOneway() {
        return false;
      }

      public void start(I iface, getExperimentStatus_args args, org.apache.thrift.async.AsyncMethodCallback<org.apache.airavata.model.status.ExperimentStatus> resultHandler) throws TException {
        iface.getExperimentStatus(args.authzToken, args.airavataExperimentId,resultHandler);
      }
    }

    public static class getExperimentOutputs<I extends AsyncIface> extends org.apache.thrift.AsyncProcessFunction<I, getExperimentOutputs_args, List<org.apache.airavata.model.application.io.OutputDataObjectType>> {
      public getExperimentOutputs() {
        super("getExperimentOutputs");
      }

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

      public AsyncMethodCallback<List<org.apache.airavata.model.application.io.OutputDataObjectType>> getResultHandler(final AsyncFrameBuffer fb, final int seqid) {
        final org.apache.thrift.AsyncProcessFunction fcall = this;
        return new AsyncMethodCallback<List<org.apache.airavata.model.application.io.OutputDataObjectType>>() { 
          public void onComplete(List<org.apache.airavata.model.application.io.OutputDataObjectType> o) {
            getExperimentOutputs_result result = new getExperimentOutputs_result();
            result.success = o;
            try {
              fcall.sendResponse(fb,result, org.apache.thrift.protocol.TMessageType.REPLY,seqid);
              return;
            } catch (Exception e) {
              LOGGER.error("Exception writing to internal frame buffer", e);
            }
            fb.close();
          }
          public void onError(Exception e) {
            byte msgType = org.apache.thrift.protocol.TMessageType.REPLY;
            org.apache.thrift.TBase msg;
            getExperimentOutputs_result result = new getExperimentOutputs_result();
            if (e instanceof org.apache.airavata.model.error.InvalidRequestException) {
                        result.ire = (org.apache.airavata.model.error.InvalidRequestException) e;
                        result.setIreIsSet(true);
                        msg = result;
            }
            else             if (e instanceof org.apache.airavata.model.error.ExperimentNotFoundException) {
                        result.enf = (org.apache.airavata.model.error.ExperimentNotFoundException) e;
                        result.setEnfIsSet(true);
                        msg = result;
            }
            else             if (e instanceof org.apache.airavata.model.error.AiravataClientException) {
                        result.ace = (org.apache.airavata.model.error.AiravataClientException) e;
                        result.setAceIsSet(true);
                        msg = result;
            }
            else             if (e instanceof org.apache.airavata.model.error.AiravataSystemException) {
                        result.ase = (org.apache.airavata.model.error.AiravataSystemException) e;
                        result.setAseIsSet(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 
            {
              msgType = org.apache.thrift.protocol.TMessageType.EXCEPTION;
              msg = (org.apache.thrift.TBase)new org.apache.thrift.TApplicationException(org.apache.thrift.TApplicationException.INTERNAL_ERROR, e.getMessage());
            }
            try {
              fcall.sendResponse(fb,msg,msgType,seqid);
              return;
            } catch (Exception ex) {
              LOGGER.error("Exception writing to internal frame buffer", ex);
            }
            fb.close();
          }
        };
      }

      protected boolean isOneway() {
        return false;
      }

      public void start(I iface, getExperimentOutputs_args args, org.apache.thrift.async.AsyncMethodCallback<List<org.apache.airavata.model.application.io.OutputDataObjectType>> resultHandler) throws TException {
        iface.getExperimentOutputs(args.authzToken, args.airavataExperimentId,resultHandler);
      }
    }

    public static class getIntermediateOutputs<I extends AsyncIface> extends org.apache.thrift.AsyncProcessFunction<I, getIntermediateOutputs_args, List<org.apache.airavata.model.application.io.OutputDataObjectType>> {
      public getIntermediateOutputs() {
        super("getIntermediateOutputs");
      }

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

      public AsyncMethodCallback<List<org.apache.airavata.model.application.io.OutputDataObjectType>> getResultHandler(final AsyncFrameBuffer fb, final int seqid) {
        final org.apache.thrift.AsyncProcessFunction fcall = this;
        return new AsyncMethodCallback<List<org.apache.airavata.model.application.io.OutputDataObjectType>>() { 
          public void onComplete(List<org.apache.airavata.model.application.io.OutputDataObjectType> o) {
            getIntermediateOutputs_result result = new getIntermediateOutputs_result();
            result.success = o;
            try {
              fcall.sendResponse(fb,result, org.apache.thrift.protocol.TMessageType.REPLY,seqid);
              return;
            } catch (Exception e) {
              LOGGER.error("Exception writing to internal frame buffer", e);
            }
            fb.close();
          }
          public void onError(Exception e) {
            byte msgType = org.apache.thrift.protocol.TMessageType.REPLY;
            org.apache.thrift.TBase msg;
            getIntermediateOutputs_result result = new getIntermediateOutputs_result();
            if (e instanceof org.apache.airavata.model.error.InvalidRequestException) {
                        result.ire = (org.apache.airavata.model.error.InvalidRequestException) e;
                        result.setIreIsSet(true);
                        msg = result;
            }
            else             if (e instanceof org.apache.airavata.model.error.ExperimentNotFoundException) {
                        result.enf = (org.apache.airavata.model.error.ExperimentNotFoundException) e;
                        result.setEnfIsSet(true);
                        msg = result;
            }
            else             if (e instanceof org.apache.airavata.model.error.AiravataClientException) {
                        result.ace = (org.apache.airavata.model.error.AiravataClientException) e;
                        result.setAceIsSet(true);
                        msg = result;
            }
            else             if (e instanceof org.apache.airavata.model.error.AiravataSystemException) {
                        result.ase = (org.apache.airavata.model.error.AiravataSystemException) e;
                        result.setAseIsSet(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 
            {
              msgType = org.apache.thrift.protocol.TMessageType.EXCEPTION;
              msg = (org.apache.thrift.TBase)new org.apache.thrift.TApplicationException(org.apache.thrift.TApplicationException.INTERNAL_ERROR, e.getMessage());
            }
            try {
              fcall.sendResponse(fb,msg,msgType,seqid);
              return;
            } catch (Exception ex) {
              LOGGER.error("Exception writing to internal frame buffer", ex);
            }
            fb.close();
          }
        };
      }

      protected boolean isOneway() {
        return false;
      }

      public void start(I iface, getIntermediateOutputs_args args, org.apache.thrift.async.AsyncMethodCallback<List<org.apache.airavata.model.application.io.OutputDataObjectType>> resultHandler) throws TException {
        iface.getIntermediateOutputs(args.authzToken, args.airavataExperimentId,resultHandler);
      }
    }

    public static class getJobStatuses<I extends AsyncIface> extends org.apache.thrift.AsyncProcessFunction<I, getJobStatuses_args, Map<String,org.apache.airavata.model.status.JobStatus>> {
      public getJobStatuses() {
        super("getJobStatuses");
      }

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

      public AsyncMethodCallback<Map<String,org.apache.airavata.model.status.JobStatus>> getResultHandler(final AsyncFrameBuffer fb, final int seqid) {
        final org.apache.thrift.AsyncProcessFunction fcall = this;
        return new AsyncMethodCallback<Map<String,org.apache.airavata.model.status.JobStatus>>() { 
          public void onComplete(Map<String,org.apache.airavata.model.status.JobStatus> o) {
            getJobStatuses_result result = new getJobStatuses_result();
            result.success = o;
            try {
              fcall.sendResponse(fb,result, org.apache.thrift.protocol.TMessageType.REPLY,seqid);
              return;
            } catch (Exception e) {
              LOGGER.error("Exception writing to internal frame buffer", e);
            }
            fb.close();
          }
          public void onError(Exception e) {
            byte msgType = org.apache.thrift.protocol.TMessageType.REPLY;
            org.apache.thrift.TBase msg;
            getJobStatuses_result result = new getJobStatuses_result();
            if (e instanceof org.apache.airavata.model.error.InvalidRequestException) {
                        result.ire = (org.apache.airavata.model.error.InvalidRequestException) e;
                        result.setIreIsSet(true);
                        msg = result;
            }
            else             if (e instanceof org.apache.airavata.model.error.ExperimentNotFoundException) {
                        result.enf = (org.apache.airavata.model.error.ExperimentNotFoundException) e;
                        result.setEnfIsSet(true);
                        msg = result;
            }
            else             if (e instanceof org.apache.airavata.model.error.AiravataClientException) {
                        result.ace = (org.apache.airavata.model.error.AiravataClientException) e;
                        result.setAceIsSet(true);
                        msg = result;
            }
            else             if (e instanceof org.apache.airavata.model.error.AiravataSystemException) {
                        result.ase = (org.apache.airavata.model.error.AiravataSystemException) e;
                        result.setAseIsSet(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 
            {
              msgType = org.apache.thrift.protocol.TMessageType.EXCEPTION;
              msg = (org.apache.thrift.TBase)new org.apache.thrift.TApplicationException(org.apache.thrift.TApplicationException.INTERNAL_ERROR, e.getMessage());
            }
            try {
              fcall.sendResponse(fb,msg,msgType,seqid);
              return;
            } catch (Exception ex) {
              LOGGER.error("Exception writing to internal frame buffer", ex);
            }
            fb.close();
          }
        };
      }

      protected boolean isOneway() {
        return false;
      }

      public void start(I iface, getJobStatuses_args args, org.apache.thrift.async.AsyncMethodCallback<Map<String,org.apache.airavata.model.status.JobStatus>> resultHandler) throws TException {
        iface.getJobStatuses(args.authzToken, args.airavataExperimentId,resultHandler);
      }
    }

    public static class getJobDetails<I extends AsyncIface> extends org.apache.thrift.AsyncProcessFunction<I, getJobDetails_args, List<org.apache.airavata.model.job.JobModel>> {
      public getJobDetails() {
        super("getJobDetails");
      }

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

      public AsyncMethodCallback<List<org.apache.airavata.model.job.JobModel>> getResultHandler(final AsyncFrameBuffer fb, final int seqid) {
        final org.apache.thrift.AsyncProcessFunction fcall = this;
        return new AsyncMethodCallback<List<org.apache.airavata.model.job.JobModel>>() { 
          public void onComplete(List<org.apache.airavata.model.job.JobModel> o) {
            getJobDetails_result result = new getJobDetails_result();
            result.success = o;
            try {
              fcall.sendResponse(fb,result, org.apache.thrift.protocol.TMessageType.REPLY,seqid);
              return;
            } catch (Exception e) {
              LOGGER.error("Exception writing to internal frame buffer", e);
            }
            fb.close();
          }
          public void onError(Exception e) {
            byte msgType = org.apache.thrift.protocol.TMessageType.REPLY;
            org.apache.thrift.TBase msg;
            getJobDetails_result result = new getJobDetails_result();
            if (e instanceof org.apache.airavata.model.error.InvalidRequestException) {
                        result.ire = (org.apache.airavata.model.error.InvalidRequestException) e;
                        result.setIreIsSet(true);
                        msg = result;
            }
            else             if (e instanceof org.apache.airavata.model.error.ExperimentNotFoundException) {
                        result.enf = (org.apache.airavata.model.error.ExperimentNotFoundException) e;
                        result.setEnfIsSet(true);
                        msg = result;
            }
            else             if (e instanceof org.apache.airavata.model.error.AiravataClientException) {
                        result.ace = (org.apache.airavata.model.error.AiravataClientException) e;
                        result.setAceIsSet(true);
                        msg = result;
            }
            else             if (e instanceof org.apache.airavata.model.error.AiravataSystemException) {
                        result.ase = (org.apache.airavata.model.error.AiravataSystemException) e;
                        result.setAseIsSet(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 
            {
              msgType = org.apache.thrift.protocol.TMessageType.EXCEPTION;
              msg = (org.apache.thrift.TBase)new org.apache.thrift.TApplicationException(org.apache.thrift.TApplicationException.INTERNAL_ERROR, e.getMessage());
            }
            try {
              fcall.sendResponse(fb,msg,msgType,seqid);
              return;
            } catch (Exception ex) {
              LOGGER.error("Exception writing to internal frame buffer", ex);
            }
            fb.close();
          }
        };
      }

      protected boolean isOneway() {
        return false;
      }

      public void start(I iface, getJobDetails_args args, org.apache.thrift.async.AsyncMethodCallback<List<org.apache.airavata.model.job.JobModel>> resultHandler) throws TException {
        iface.getJobDetails(args.authzToken, args.airavataExperimentId,resultHandler);
      }
    }

    public static class cloneExperiment<I extends AsyncIface> extends org.apache.thrift.AsyncProcessFunction<I, cloneExperiment_args, String> {
      public cloneExperiment() {
        super("cloneExperiment");
      }

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

      public AsyncMethodCallback<String> getResultHandler(final AsyncFrameBuffer fb, final int seqid) {
        final org.apache.thrift.AsyncProcessFunction fcall = this;
        return new AsyncMethodCallback<String>() { 
          public void onComplete(String o) {
            cloneExperiment_result result = new cloneExperiment_result();
            result.success = o;
            try {
              fcall.sendResponse(fb,result, org.apache.thrift.protocol.TMessageType.REPLY,seqid);
              return;
            } catch (Exception e) {
              LOGGER.error("Exception writing to internal frame buffer", e);
            }
            fb.close();
          }
          public void onError(Exception e) {
            byte msgType = org.apache.thrift.protocol.TMessageType.REPLY;
            org.apache.thrift.TBase msg;
            cloneExperiment_result result = new cloneExperiment_result();
            if (e instanceof org.apache.airavata.model.error.InvalidRequestException) {
                        result.ire = (org.apache.airavata.model.error.InvalidRequestException) e;
                        result.setIreIsSet(true);
                        msg = result;
            }
            else             if (e instanceof org.apache.airavata.model.error.ExperimentNotFoundException) {
                        result.enf = (org.apache.airavata.model.error.ExperimentNotFoundException) e;
                        result.setEnfIsSet(true);
                        msg = result;
            }
            else             if (e instanceof org.apache.airavata.model.error.AiravataClientException) {
                        result.ace = (org.apache.airavata.model.error.AiravataClientException) e;
                        result.setAceIsSet(true);
                        msg = result;
            }
            else             if (e instanceof org.apache.airavata.model.error.AiravataSystemException) {
                        result.ase = (org.apache.airavata.model.error.AiravataSystemException) e;
                        result.setAseIsSet(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 
            {
              msgType = org.apache.thrift.protocol.TMessageType.EXCEPTION;
              msg = (org.apache.thrift.TBase)new org.apache.thrift.TApplicationException(org.apache.thrift.TApplicationException.INTERNAL_ERROR, e.getMessage());
            }
            try {
              fcall.sendResponse(fb,msg,msgType,seqid);
              return;
            } catch (Exception ex) {
              LOGGER.error("Exception writing to internal frame buffer", ex);
            }
            fb.close();
          }
        };
      }

      protected boolean isOneway() {
        return false;
      }

      public void start(I iface, cloneExperiment_args args, org.apache.thrift.async.AsyncMethodCallback<String> resultHandler) throws TException {
        iface.cloneExperiment(args.authzToken, args.existingExperimentID, args.newExperimentName,resultHandler);
      }
    }

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

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

      public AsyncMethodCallback<Void> getResultHandler(final AsyncFrameBuffer fb, final int seqid) {
        final org.apache.thrift.AsyncProcessFunction fcall = this;
        return new AsyncMethodCallback<Void>() { 
          public void onComplete(Void o) {
            terminateExperiment_result result = new terminateExperiment_result();
            try {
              fcall.sendResponse(fb,result, org.apache.thrift.protocol.TMessageType.REPLY,seqid);
              return;
            } catch (Exception e) {
              LOGGER.error("Exception writing to internal frame buffer", e);
            }
            fb.close();
          }
          public void onError(Exception e) {
            byte msgType = org.apache.thrift.protocol.TMessageType.REPLY;
            org.apache.thrift.TBase msg;
            terminateExperiment_result result = new terminateExperiment_result();
            if (e instanceof org.apache.airavata.model.error.InvalidRequestException) {
                        result.ire = (org.apache.airavata.model.error.InvalidRequestException) e;
                        result.setIreIsSet(true);
                        msg = result;
            }
            else             if (e instanceof org.apache.airavata.model.error.ExperimentNotFoundException) {
                        result.enf = (org.apache.airavata.model.error.ExperimentNotFoundException) e;
                        result.setEnfIsSet(true);
                        msg = result;
            }
            else             if (e instanceof org.apache.airavata.model.error.AiravataClientException) {
                        result.ace = (org.apache.airavata.model.error.AiravataClientException) e;
                        result.setAceIsSet(true);
                        msg = result;
            }
            else             if (e instanceof org.apache.airavata.model.error.AiravataSystemException) {
                        result.ase = (org.apache.airavata.model.error.AiravataSystemException) e;
                        result.setAseIsSet(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 
            {
              msgType = org.apache.thrift.protocol.TMessageType.EXCEPTION;
              msg = (org.apache.thrift.TBase)new org.apache.thrift.TApplicationException(org.apache.thrift.TApplicationException.INTERNAL_ERROR, e.getMessage());
            }
            try {
              fcall.sendResponse(fb,msg,msgType,seqid);
              return;
            } catch (Exception ex) {
              LOGGER.error("Exception writing to internal frame buffer", ex);
            }
            fb.close();
          }
        };
      }

      protected boolean isOneway() {
        return false;
      }

      public void start(I iface, terminateExperiment_args args, org.apache.thrift.async.AsyncMethodCallback<Void> resultHandler) throws TException {
        iface.terminateExperiment(args.authzToken, args.airavataExperimentId, args.gatewayId,resultHandler);
      }
    }

    public static class registerApplicationModule<I extends AsyncIface> extends org.apache.thrift.AsyncProcessFunction<I, registerApplicationModule_args, String> {
      public registerApplicationModule() {
        super("registerApplicationModule");
      }

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

      public AsyncMethodCallback<String> getResultHandler(final AsyncFrameBuffer fb, final int seqid) {
        final org.apache.thrift.AsyncProcessFunction fcall = this;
        return new AsyncMethodCallback<String>() { 
          public void onComplete(String o) {
            registerApplicationModule_result result = new registerApplicationModule_result();
            result.success = o;
            try {
              fcall.sendResponse(fb,result, org.apache.thrift.protocol.TMessageType.REPLY,seqid);
              return;
            } catch (Exception e) {
              LOGGER.error("Exception writing to internal frame buffer", e);
            }
            fb.close();
          }
          public void onError(Exception e) {
            byte msgType = org.apache.thrift.protocol.TMessageType.REPLY;
            org.apache.thrift.TBase msg;
            registerApplicationModule_result result = new registerApplicationModule_result();
            if (e instanceof org.apache.airavata.model.error.InvalidRequestException) {
                        result.ire = (org.apache.airavata.model.error.InvalidRequestException) e;
                        result.setIreIsSet(true);
                        msg = result;
            }
            else             if (e instanceof org.apache.airavata.model.error.AiravataClientException) {
                        result.ace = (org.apache.airavata.model.error.AiravataClientException) e;
                        result.setAceIsSet(true);
                        msg = result;
            }
            else             if (e instanceof org.apache.airavata.model.error.AiravataSystemException) {
                        result.ase = (org.apache.airavata.model.error.AiravataSystemException) e;
                        result.setAseIsSet(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 
            {
              msgType = org.apache.thrift.protocol.TMessageType.EXCEPTION;
              msg = (org.apache.thrift.TBase)new org.apache.thrift.TApplicationException(org.apache.thrift.TApplicationException.INTERNAL_ERROR, e.getMessage());
            }
            try {
              fcall.sendResponse(fb,msg,msgType,seqid);
              return;
            } catch (Exception ex) {
              LOGGER.error("Exception writing to internal frame buffer", ex);
            }
            fb.close();
          }
        };
      }

      protected boolean isOneway() {
        return false;
      }

      public void start(I iface, registerApplicationModule_args args, org.apache.thrift.async.AsyncMethodCallback<String> resultHandler) throws TException {
        iface.registerApplicationModule(args.authzToken, args.gatewayId, args.applicationModule,resultHandler);
      }
    }

    public static class getApplicationModule<I extends AsyncIface> extends org.apache.thrift.AsyncProcessFunction<I, getApplicationModule_args, org.apache.airavata.model.appcatalog.appdeployment.ApplicationModule> {
      public getApplicationModule() {
        super("getApplicationModule");
      }

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

      public AsyncMethodCallback<org.apache.airavata.model.appcatalog.appdeployment.ApplicationModule> getResultHandler(final AsyncFrameBuffer fb, final int seqid) {
        final org.apache.thrift.AsyncProcessFunction fcall = this;
        return new AsyncMethodCallback<org.apache.airavata.model.appcatalog.appdeployment.ApplicationModule>() { 
          public void onComplete(org.apache.airavata.model.appcatalog.appdeployment.ApplicationModule o) {
            getApplicationModule_result result = new getApplicationModule_result();
            result.success = o;
            try {
              fcall.sendResponse(fb,result, org.apache.thrift.protocol.TMessageType.REPLY,seqid);
              return;
            } catch (Exception e) {
              LOGGER.error("Exception writing to internal frame buffer", e);
            }
            fb.close();
          }
          public void onError(Exception e) {
            byte msgType = org.apache.thrift.protocol.TMessageType.REPLY;
            org.apache.thrift.TBase msg;
            getApplicationModule_result result = new getApplicationModule_result();
            if (e instanceof org.apache.airavata.model.error.InvalidRequestException) {
                        result.ire = (org.apache.airavata.model.error.InvalidRequestException) e;
                        result.setIreIsSet(true);
                        msg = result;
            }
            else             if (e instanceof org.apache.airavata.model.error.AiravataClientException) {
                        result.ace = (org.apache.airavata.model.error.AiravataClientException) e;
                        result.setAceIsSet(true);
                        msg = result;
            }
            else             if (e instanceof org.apache.airavata.model.error.AiravataSystemException) {
                        result.ase = (org.apache.airavata.model.error.AiravataSystemException) e;
                        result.setAseIsSet(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 
            {
              msgType = org.apache.thrift.protocol.TMessageType.EXCEPTION;
              msg = (org.apache.thrift.TBase)new org.apache.thrift.TApplicationException(org.apache.thrift.TApplicationException.INTERNAL_ERROR, e.getMessage());
            }
            try {
              fcall.sendResponse(fb,msg,msgType,seqid);
              return;
            } catch (Exception ex) {
              LOGGER.error("Exception writing to internal frame buffer", ex);
            }
            fb.close();
          }
        };
      }

      protected boolean isOneway() {
        return false;
      }

      public void start(I iface, getApplicationModule_args args, org.apache.thrift.async.AsyncMethodCallback<org.apache.airavata.model.appcatalog.appdeployment.ApplicationModule> resultHandler) throws TException {
        iface.getApplicationModule(args.authzToken, args.appModuleId,resultHandler);
      }
    }

    public static class updateApplicationModule<I extends AsyncIface> extends org.apache.thrift.AsyncProcessFunction<I, updateApplicationModule_args, Boolean> {
      public updateApplicationModule() {
        super("updateApplicationModule");
      }

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

      public AsyncMethodCallback<Boolean> getResultHandler(final AsyncFrameBuffer fb, final int seqid) {
        final org.apache.thrift.AsyncProcessFunction fcall = this;
        return new AsyncMethodCallback<Boolean>() { 
          public void onComplete(Boolean o) {
            updateApplicationModule_result result = new updateApplicationModule_result();
            result.success = o;
            result.setSuccessIsSet(true);
            try {
              fcall.sendResponse(fb,result, org.apache.thrift.protocol.TMessageType.REPLY,seqid);
              return;
            } catch (Exception e) {
              LOGGER.error("Exception writing to internal frame buffer", e);
            }
            fb.close();
          }
          public void onError(Exception e) {
            byte msgType = org.apache.thrift.protocol.TMessageType.REPLY;
            org.apache.thrift.TBase msg;
            updateApplicationModule_result result = new updateApplicationModule_result();
            if (e instanceof org.apache.airavata.model.error.InvalidRequestException) {
                        result.ire = (org.apache.airavata.model.error.InvalidRequestException) e;
                        result.setIreIsSet(true);
                        msg = result;
            }
            else             if (e instanceof org.apache.airavata.model.error.AiravataClientException) {
                        result.ace = (org.apache.airavata.model.error.AiravataClientException) e;
                        result.setAceIsSet(true);
                        msg = result;
            }
            else             if (e instanceof org.apache.airavata.model.error.AiravataSystemException) {
                        result.ase = (org.apache.airavata.model.error.AiravataSystemException) e;
                        result.setAseIsSet(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 
            {
              msgType = org.apache.thrift.protocol.TMessageType.EXCEPTION;
              msg = (org.apache.thrift.TBase)new org.apache.thrift.TApplicationException(org.apache.thrift.TApplicationException.INTERNAL_ERROR, e.getMessage());
            }
            try {
              fcall.sendResponse(fb,msg,msgType,seqid);
              return;
            } catch (Exception ex) {
              LOGGER.error("Exception writing to internal frame buffer", ex);
            }
            fb.close();
          }
        };
      }

      protected boolean isOneway() {
        return false;
      }

      public void start(I iface, updateApplicationModule_args args, org.apache.thrift.async.AsyncMethodCallback<Boolean> resultHandler) throws TException {
        iface.updateApplicationModule(args.authzToken, args.appModuleId, args.applicationModule,resultHandler);
      }
    }

    public static class getAllAppModules<I extends AsyncIface> extends org.apache.thrift.AsyncProcessFunction<I, getAllAppModules_args, List<org.apache.airavata.model.appcatalog.appdeployment.ApplicationModule>> {
      public getAllAppModules() {
        super("getAllAppModules");
      }

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

      public AsyncMethodCallback<List<org.apache.airavata.model.appcatalog.appdeployment.ApplicationModule>> getResultHandler(final AsyncFrameBuffer fb, final int seqid) {
        final org.apache.thrift.AsyncProcessFunction fcall = this;
        return new AsyncMethodCallback<List<org.apache.airavata.model.appcatalog.appdeployment.ApplicationModule>>() { 
          public void onComplete(List<org.apache.airavata.model.appcatalog.appdeployment.ApplicationModule> o) {
            getAllAppModules_result result = new getAllAppModules_result();
            result.success = o;
            try {
              fcall.sendResponse(fb,result, org.apache.thrift.protocol.TMessageType.REPLY,seqid);
              return;
            } catch (Exception e) {
              LOGGER.error("Exception writing to internal frame buffer", e);
            }
            fb.close();
          }
          public void onError(Exception e) {
            byte msgType = org.apache.thrift.protocol.TMessageType.REPLY;
            org.apache.thrift.TBase msg;
            getAllAppModules_result result = new getAllAppModules_result();
            if (e instanceof org.apache.airavata.model.error.InvalidRequestException) {
                        result.ire = (org.apache.airavata.model.error.InvalidRequestException) e;
                        result.setIreIsSet(true);
                        msg = result;
            }
            else             if (e instanceof org.apache.airavata.model.error.AiravataClientException) {
                        result.ace = (org.apache.airavata.model.error.AiravataClientException) e;
                        result.setAceIsSet(true);
                        msg = result;
            }
            else             if (e instanceof org.apache.airavata.model.error.AiravataSystemException) {
                        result.ase = (org.apache.airavata.model.error.AiravataSystemException) e;
                        result.setAseIsSet(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 
            {
              msgType = org.apache.thrift.protocol.TMessageType.EXCEPTION;
              msg = (org.apache.thrift.TBase)new org.apache.thrift.TApplicationException(org.apache.thrift.TApplicationException.INTERNAL_ERROR, e.getMessage());
            }
            try {
              fcall.sendResponse(fb,msg,msgType,seqid);
              return;
            } catch (Exception ex) {
              LOGGER.error("Exception writing to internal frame buffer", ex);
            }
            fb.close();
          }
        };
      }

      protected boolean isOneway() {
        return false;
      }

      public void start(I iface, getAllAppModules_args args, org.apache.thrift.async.AsyncMethodCallback<List<org.apache.airavata.model.appcatalog.appdeployment.ApplicationModule>> resultHandler) throws TException {
        iface.getAllAppModules(args.authzToken, args.gatewayId,resultHandler);
      }
    }

    public static class deleteApplicationModule<I extends AsyncIface> extends org.apache.thrift.AsyncProcessFunction<I, deleteApplicationModule_args, Boolean> {
      public deleteApplicationModule() {
        super("deleteApplicationModule");
      }

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

      public AsyncMethodCallback<Boolean> getResultHandler(final AsyncFrameBuffer fb, final int seqid) {
        final org.apache.thrift.AsyncProcessFunction fcall = this;
        return new AsyncMethodCallback<Boolean>() { 
          public void onComplete(Boolean o) {
            deleteApplicationModule_result result = new deleteApplicationModule_result();
            result.success = o;
            result.setSuccessIsSet(true);
            try {
              fcall.sendResponse(fb,result, org.apache.thrift.protocol.TMessageType.REPLY,seqid);
              return;
            } catch (Exception e) {
              LOGGER.error("Exception writing to internal frame buffer", e);
            }
            fb.close();
          }
          public void onError(Exception e) {
            byte msgType = org.apache.thrift.protocol.TMessageType.REPLY;
            org.apache.thrift.TBase msg;
            deleteApplicationModule_result result = new deleteApplicationModule_result();
            if (e instanceof org.apache.airavata.model.error.InvalidRequestException) {
                        result.ire = (org.apache.airavata.model.error.InvalidRequestException) e;
                        result.setIreIsSet(true);
                        msg = result;
            }
            else             if (e instanceof org.apache.airavata.model.error.AiravataClientException) {
                        result.ace = (org.apache.airavata.model.error.AiravataClientException) e;
                        result.setAceIsSet(true);
                        msg = result;
            }
            else             if (e instanceof org.apache.airavata.model.error.AiravataSystemException) {
                        result.ase = (org.apache.airavata.model.error.AiravataSystemException) e;
                        result.setAseIsSet(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 
            {
              msgType = org.apache.thrift.protocol.TMessageType.EXCEPTION;
              msg = (org.apache.thrift.TBase)new org.apache.thrift.TApplicationException(org.apache.thrift.TApplicationException.INTERNAL_ERROR, e.getMessage());
            }
            try {
              fcall.sendResponse(fb,msg,msgType,seqid);
              return;
            } catch (Exception ex) {
              LOGGER.error("Exception writing to internal frame buffer", ex);
            }
            fb.close();
          }
        };
      }

      protected boolean isOneway() {
        return false;
      }

      public void start(I iface, deleteApplicationModule_args args, org.apache.thrift.async.AsyncMethodCallback<Boolean> resultHandler) throws TException {
        iface.deleteApplicationModule(args.authzToken, args.appModuleId,resultHandler);
      }
    }

    public static class registerApplicationDeployment<I extends AsyncIface> extends org.apache.thrift.AsyncProcessFunction<I, registerApplicationDeployment_args, String> {
      public registerApplicationDeployment() {
        super("registerApplicationDeployment");
      }

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

      public AsyncMethodCallback<String> getResultHandler(final AsyncFrameBuffer fb, final int seqid) {
        final org.apache.thrift.AsyncProcessFunction fcall = this;
        return new AsyncMethodCallback<String>() { 
          public void onComplete(String o) {
            registerApplicationDeployment_result result = new registerApplicationDeployment_result();
            result.success = o;
            try {
              fcall.sendResponse(fb,result, org.apache.thrift.protocol.TMessageType.REPLY,seqid);
              return;
            } catch (Exception e) {
              LOGGER.error("Exception writing to internal frame buffer", e);
            }
            fb.close();
          }
          public void onError(Exception e) {
            byte msgType = org.apache.thrift.protocol.TMessageType.REPLY;
            org.apache.thrift.TBase msg;
            registerApplicationDeployment_result result = new registerApplicationDeployment_result();
            if (e instanceof org.apache.airavata.model.error.InvalidRequestException) {
                        result.ire = (org.apache.airavata.model.error.InvalidRequestException) e;
                        result.setIreIsSet(true);
                        msg = result;
            }
            else             if (e instanceof org.apache.airavata.model.error.AiravataClientException) {
                        result.ace = (org.apache.airavata.model.error.AiravataClientException) e;
                        result.setAceIsSet(true);
                        msg = result;
            }
            else             if (e instanceof org.apache.airavata.model.error.AiravataSystemException) {
                        result.ase = (org.apache.airavata.model.error.AiravataSystemException) e;
                        result.setAseIsSet(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 
            {
              msgType = org.apache.thrift.protocol.TMessageType.EXCEPTION;
              msg = (org.apache.thrift.TBase)new org.apache.thrift.TApplicationException(org.apache.thrift.TApplicationException.INTERNAL_ERROR, e.getMessage());
            }
            try {
              fcall.sendResponse(fb,msg,msgType,seqid);
              return;
            } catch (Exception ex) {
              LOGGER.error("Exception writing to internal frame buffer", ex);
            }
            fb.close();
          }
        };
      }

      protected boolean isOneway() {
        return false;
      }

      public void start(I iface, registerApplicationDeployment_args args, org.apache.thrift.async.AsyncMethodCallback<String> resultHandler) throws TException {
        iface.registerApplicationDeployment(args.authzToken, args.gatewayId, args.applicationDeployment,resultHandler);
      }
    }

    public static class getApplicationDeployment<I extends AsyncIface> extends org.apache.thrift.AsyncProcessFunction<I, getApplicationDeployment_args, org.apache.airavata.model.appcatalog.appdeployment.ApplicationDeploymentDescription> {
      public getApplicationDeployment() {
        super("getApplicationDeployment");
      }

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

      public AsyncMethodCallback<org.apache.airavata.model.appcatalog.appdeployment.ApplicationDeploymentDescription> getResultHandler(final AsyncFrameBuffer fb, final int seqid) {
        final org.apache.thrift.AsyncProcessFunction fcall = this;
        return new AsyncMethodCallback<org.apache.airavata.model.appcatalog.appdeployment.ApplicationDeploymentDescription>() { 
          public void onComplete(org.apache.airavata.model.appcatalog.appdeployment.ApplicationDeploymentDescription o) {
            getApplicationDeployment_result result = new getApplicationDeployment_result();
            result.success = o;
            try {
              fcall.sendResponse(fb,result, org.apache.thrift.protocol.TMessageType.REPLY,seqid);
              return;
            } catch (Exception e) {
              LOGGER.error("Exception writing to internal frame buffer", e);
            }
            fb.close();
          }
          public void onError(Exception e) {
            byte msgType = org.apache.thrift.protocol.TMessageType.REPLY;
            org.apache.thrift.TBase msg;
            getApplicationDeployment_result result = new getApplicationDeployment_result();
            if (e instanceof org.apache.airavata.model.error.InvalidRequestException) {
                        result.ire = (org.apache.airavata.model.error.InvalidRequestException) e;
                        result.setIreIsSet(true);
                        msg = result;
            }
            else             if (e instanceof org.apache.airavata.model.error.AiravataClientException) {
                        result.ace = (org.apache.airavata.model.error.AiravataClientException) e;
                        result.setAceIsSet(true);
                        msg = result;
            }
            else             if (e instanceof org.apache.airavata.model.error.AiravataSystemException) {
                        result.ase = (org.apache.airavata.model.error.AiravataSystemException) e;
                        result.setAseIsSet(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 
            {
              msgType = org.apache.thrift.protocol.TMessageType.EXCEPTION;
              msg = (org.apache.thrift.TBase)new org.apache.thrift.TApplicationException(org.apache.thrift.TApplicationException.INTERNAL_ERROR, e.getMessage());
            }
            try {
              fcall.sendResponse(fb,msg,msgType,seqid);
              return;
            } catch (Exception ex) {
              LOGGER.error("Exception writing to internal frame buffer", ex);
            }
            fb.close();
          }
        };
      }

      protected boolean isOneway() {
        return false;
      }

      public void start(I iface, getApplicationDeployment_args args, org.apache.thrift.async.AsyncMethodCallback<org.apache.airavata.model.appcatalog.appdeployment.ApplicationDeploymentDescription> resultHandler) throws TException {
        iface.getApplicationDeployment(args.authzToken, args.appDeploymentId,resultHandler);
      }
    }

    public static class updateApplicationDeployment<I extends AsyncIface> extends org.apache.thrift.AsyncProcessFunction<I, updateApplicationDeployment_args, Boolean> {
      public updateApplicationDeployment() {
        super("updateApplicationDeployment");
      }

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

      public AsyncMethodCallback<Boolean> getResultHandler(final AsyncFrameBuffer fb, final int seqid) {
        final org.apache.thrift.AsyncProcessFunction fcall = this;
        return new AsyncMethodCallback<Boolean>() { 
          public void onComplete(Boolean o) {
            updateApplicationDeployment_result result = new updateApplicationDeployment_result();
            result.success = o;
            result.setSuccessIsSet(true);
            try {
              fcall.sendResponse(fb,result, org.apache.thrift.protocol.TMessageType.REPLY,seqid);
              return;
            } catch (Exception e) {
              LOGGER.error("Exception writing to internal frame buffer", e);
            }
            fb.close();
          }
          public void onError(Exception e) {
            byte msgType = org.apache.thrift.protocol.TMessageType.REPLY;
            org.apache.thrift.TBase msg;
            updateApplicationDeployment_result result = new updateApplicationDeployment_result();
            if (e instanceof org.apache.airavata.model.error.InvalidRequestException) {
                        result.ire = (org.apache.airavata.model.error.InvalidRequestException) e;
                        result.setIreIsSet(true);
                        msg = result;
            }
            else             if (e instanceof org.apache.airavata.model.error.AiravataClientException) {
                        result.ace = (org.apache.airavata.model.error.AiravataClientException) e;
                        result.setAceIsSet(true);
                        msg = result;
            }
            else             if (e instanceof org.apache.airavata.model.error.AiravataSystemException) {
                        result.ase = (org.apache.airavata.model.error.AiravataSystemException) e;
                        result.setAseIsSet(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 
            {
              msgType = org.apache.thrift.protocol.TMessageType.EXCEPTION;
              msg = (org.apache.thrift.TBase)new org.apache.thrift.TApplicationException(org.apache.thrift.TApplicationException.INTERNAL_ERROR, e.getMessage());
            }
            try {
              fcall.sendResponse(fb,msg,msgType,seqid);
              return;
            } catch (Exception ex) {
              LOGGER.error("Exception writing to internal frame buffer", ex);
            }
            fb.close();
          }
        };
      }

      protected boolean isOneway() {
        return false;
      }

      public void start(I iface, updateApplicationDeployment_args args, org.apache.thrift.async.AsyncMethodCallback<Boolean> resultHandler) throws TException {
        iface.updateApplicationDeployment(args.authzToken, args.appDeploymentId, args.applicationDeployment,resultHandler);
      }
    }

    public static class deleteApplicationDeployment<I extends AsyncIface> extends org.apache.thrift.AsyncProcessFunction<I, deleteApplicationDeployment_args, Boolean> {
      public deleteApplicationDeployment() {
        super("deleteApplicationDeployment");
      }

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

      public AsyncMethodCallback<Boolean> getResultHandler(final AsyncFrameBuffer fb, final int seqid) {
        final org.apache.thrift.AsyncProcessFunction fcall = this;
        return new AsyncMethodCallback<Boolean>() { 
          public void onComplete(Boolean o) {
            deleteApplicationDeployment_result result = new deleteApplicationDeployment_result();
            result.success = o;
            result.setSuccessIsSet(true);
            try {
              fcall.sendResponse(fb,result, org.apache.thrift.protocol.TMessageType.REPLY,seqid);
              return;
            } catch (Exception e) {
              LOGGER.error("Exception writing to internal frame buffer", e);
            }
            fb.close();
          }
          public void onError(Exception e) {
            byte msgType = org.apache.thrift.protocol.TMessageType.REPLY;
            org.apache.thrift.TBase msg;
            deleteApplicationDeployment_result result = new deleteApplicationDeployment_result();
            if (e instanceof org.apache.airavata.model.error.InvalidRequestException) {
                        result.ire = (org.apache.airavata.model.error.InvalidRequestException) e;
                        result.setIreIsSet(true);
                        msg = result;
            }
            else             if (e instanceof org.apache.airavata.model.error.AiravataClientException) {
                        result.ace = (org.apache.airavata.model.error.AiravataClientException) e;
                        result.setAceIsSet(true);
                        msg = result;
            }
            else             if (e instanceof org.apache.airavata.model.error.AiravataSystemException) {
                        result.ase = (org.apache.airavata.model.error.AiravataSystemException) e;
                        result.setAseIsSet(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 
            {
              msgType = org.apache.thrift.protocol.TMessageType.EXCEPTION;
              msg = (org.apache.thrift.TBase)new org.apache.thrift.TApplicationException(org.apache.thrift.TApplicationException.INTERNAL_ERROR, e.getMessage());
            }
            try {
              fcall.sendResponse(fb,msg,msgType,seqid);
              return;
            } catch (Exception ex) {
              LOGGER.error("Exception writing to internal frame buffer", ex);
            }
            fb.close();
          }
        };
      }

      protected boolean isOneway() {
        return false;
      }

      public void start(I iface, deleteApplicationDeployment_args args, org.apache.thrift.async.AsyncMethodCallback<Boolean> resultHandler) throws TException {
        iface.deleteApplicationDeployment(args.authzToken, args.appDeploymentId,resultHandler);
      }
    }

    public static class getAllApplicationDeployments<I extends AsyncIface> extends org.apache.thrift.AsyncProcessFunction<I, getAllApplicationDeployments_args, List<org.apache.airavata.model.appcatalog.appdeployment.ApplicationDeploymentDescription>> {
      public getAllApplicationDeployments() {
        super("getAllApplicationDeployments");
      }

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

      public AsyncMethodCallback<List<org.apache.airavata.model.appcatalog.appdeployment.ApplicationDeploymentDescription>> getResultHandler(final AsyncFrameBuffer fb, final int seqid) {
        final org.apache.thrift.AsyncProcessFunction fcall = this;
        return new AsyncMethodCallback<List<org.apache.airavata.model.appcatalog.appdeployment.ApplicationDeploymentDescription>>() { 
          public void onComplete(List<org.apache.airavata.model.appcatalog.appdeployment.ApplicationDeploymentDescription> o) {
            getAllApplicationDeployments_result result = new getAllApplicationDeployments_result();
            result.success = o;
            try {
              fcall.sendResponse(fb,result, org.apache.thrift.protocol.TMessageType.REPLY,seqid);
              return;
            } catch (Exception e) {
              LOGGER.error("Exception writing to internal frame buffer", e);
            }
            fb.close();
          }
          public void onError(Exception e) {
            byte msgType = org.apache.thrift.protocol.TMessageType.REPLY;
            org.apache.thrift.TBase msg;
            getAllApplicationDeployments_result result = new getAllApplicationDeployments_result();
            if (e instanceof org.apache.airavata.model.error.InvalidRequestException) {
                        result.ire = (org.apache.airavata.model.error.InvalidRequestException) e;
                        result.setIreIsSet(true);
                        msg = result;
            }
            else             if (e instanceof org.apache.airavata.model.error.AiravataClientException) {
                        result.ace = (org.apache.airavata.model.error.AiravataClientException) e;
                        result.setAceIsSet(true);
                        msg = result;
            }
            else             if (e instanceof org.apache.airavata.model.error.AiravataSystemException) {
                        result.ase = (org.apache.airavata.model.error.AiravataSystemException) e;
                        result.setAseIsSet(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 
            {
              msgType = org.apache.thrift.protocol.TMessageType.EXCEPTION;
              msg = (org.apache.thrift.TBase)new org.apache.thrift.TApplicationException(org.apache.thrift.TApplicationException.INTERNAL_ERROR, e.getMessage());
            }
            try {
              fcall.sendResponse(fb,msg,msgType,seqid);
              return;
            } catch (Exception ex) {
              LOGGER.error("Exception writing to internal frame buffer", ex);
            }
            fb.close();
          }
        };
      }

      protected boolean isOneway() {
        return false;
      }

      public void start(I iface, getAllApplicationDeployments_args args, org.apache.thrift.async.AsyncMethodCallback<List<org.apache.airavata.model.appcatalog.appdeployment.ApplicationDeploymentDescription>> resultHandler) throws TException {
        iface.getAllApplicationDeployments(args.authzToken, args.gatewayId,resultHandler);
      }
    }

    public static class getAppModuleDeployedResources<I extends AsyncIface> extends org.apache.thrift.AsyncProcessFunction<I, getAppModuleDeployedResources_args, List<String>> {
      public getAppModuleDeployedResources() {
        super("getAppModuleDeployedResources");
      }

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

      public AsyncMethodCallback<List<String>> getResultHandler(final AsyncFrameBuffer fb, final int seqid) {
        final org.apache.thrift.AsyncProcessFunction fcall = this;
        return new AsyncMethodCallback<List<String>>() { 
          public void onComplete(List<String> o) {
            getAppModuleDeployedResources_result result = new getAppModuleDeployedResources_result();
            result.success = o;
            try {
              fcall.sendResponse(fb,result, org.apache.thrift.protocol.TMessageType.REPLY,seqid);
              return;
            } catch (Exception e) {
              LOGGER.error("Exception writing to internal frame buffer", e);
            }
            fb.close();
          }
          public void onError(Exception e) {
            byte msgType = org.apache.thrift.protocol.TMessageType.REPLY;
            org.apache.thrift.TBase msg;
            getAppModuleDeployedResources_result result = new getAppModuleDeployedResources_result();
            if (e instanceof org.apache.airavata.model.error.InvalidRequestException) {
                        result.ire = (org.apache.airavata.model.error.InvalidRequestException) e;
                        result.setIreIsSet(true);
                        msg = result;
            }
            else             if (e instanceof org.apache.airavata.model.error.AiravataClientException) {
                        result.ace = (org.apache.airavata.model.error.AiravataClientException) e;
                        result.setAceIsSet(true);
                        msg = result;
            }
            else             if (e instanceof org.apache.airavata.model.error.AiravataSystemException) {
                        result.ase = (org.apache.airavata.model.error.AiravataSystemException) e;
                        result.setAseIsSet(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 
            {
              msgType = org.apache.thrift.protocol.TMessageType.EXCEPTION;
              msg = (org.apache.thrift.TBase)new org.apache.thrift.TApplicationException(org.apache.thrift.TApplicationException.INTERNAL_ERROR, e.getMessage());
            }
            try {
              fcall.sendResponse(fb,msg,msgType,seqid);
              return;
            } catch (Exception ex) {
              LOGGER.error("Exception writing to internal frame buffer", ex);
            }
            fb.close();
          }
        };
      }

      protected boolean isOneway() {
        return false;
      }

      public void start(I iface, getAppModuleDeployedResources_args args, org.apache.thrift.async.AsyncMethodCallback<List<String>> resultHandler) throws TException {
        iface.getAppModuleDeployedResources(args.authzToken, args.appModuleId,resultHandler);
      }
    }

    public static class registerApplicationInterface<I extends AsyncIface> extends org.apache.thrift.AsyncProcessFunction<I, registerApplicationInterface_args, String> {
      public registerApplicationInterface() {
        super("registerApplicationInterface");
      }

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

      public AsyncMethodCallback<String> getResultHandler(final AsyncFrameBuffer fb, final int seqid) {
        final org.apache.thrift.AsyncProcessFunction fcall = this;
        return new AsyncMethodCallback<String>() { 
          public void onComplete(String o) {
            registerApplicationInterface_result result = new registerApplicationInterface_result();
            result.success = o;
            try {
              fcall.sendResponse(fb,result, org.apache.thrift.protocol.TMessageType.REPLY,seqid);
              return;
            } catch (Exception e) {
              LOGGER.error("Exception writing to internal frame buffer", e);
            }
            fb.close();
          }
          public void onError(Exception e) {
            byte msgType = org.apache.thrift.protocol.TMessageType.REPLY;
            org.apache.thrift.TBase msg;
            registerApplicationInterface_result result = new registerApplicationInterface_result();
            if (e instanceof org.apache.airavata.model.error.InvalidRequestException) {
                        result.ire = (org.apache.airavata.model.error.InvalidRequestException) e;
                        result.setIreIsSet(true);
                        msg = result;
            }
            else             if (e instanceof org.apache.airavata.model.error.AiravataClientException) {
                        result.ace = (org.apache.airavata.model.error.AiravataClientException) e;
                        result.setAceIsSet(true);
                        msg = result;
            }
            else             if (e instanceof org.apache.airavata.model.error.AiravataSystemException) {
                        result.ase = (org.apache.airavata.model.error.AiravataSystemException) e;
                        result.setAseIsSet(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 
            {
              msgType = org.apache.thrift.protocol.TMessageType.EXCEPTION;
              msg = (org.apache.thrift.TBase)new org.apache.thrift.TApplicationException(org.apache.thrift.TApplicationException.INTERNAL_ERROR, e.getMessage());
            }
            try {
              fcall.sendResponse(fb,msg,msgType,seqid);
              return;
            } catch (Exception ex) {
              LOGGER.error("Exception writing to internal frame buffer", ex);
            }
            fb.close();
          }
        };
      }

      protected boolean isOneway() {
        return false;
      }

      public void start(I iface, registerApplicationInterface_args args, org.apache.thrift.async.AsyncMethodCallback<String> resultHandler) throws TException {
        iface.registerApplicationInterface(args.authzToken, args.gatewayId, args.applicationInterface,resultHandler);
      }
    }

    public static class getApplicationInterface<I extends AsyncIface> extends org.apache.thrift.AsyncProcessFunction<I, getApplicationInterface_args, org.apache.airavata.model.appcatalog.appinterface.ApplicationInterfaceDescription> {
      public getApplicationInterface() {
        super("getApplicationInterface");
      }

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

      public AsyncMethodCallback<org.apache.airavata.model.appcatalog.appinterface.ApplicationInterfaceDescription> getResultHandler(final AsyncFrameBuffer fb, final int seqid) {
        final org.apache.thrift.AsyncProcessFunction fcall = this;
        return new AsyncMethodCallback<org.apache.airavata.model.appcatalog.appinterface.ApplicationInterfaceDescription>() { 
          public void onComplete(org.apache.airavata.model.appcatalog.appinterface.ApplicationInterfaceDescription o) {
            getApplicationInterface_result result = new getApplicationInterface_result();
            result.success = o;
            try {
              fcall.sendResponse(fb,result, org.apache.thrift.protocol.TMessageType.REPLY,seqid);
              return;
            } catch (Exception e) {
              LOGGER.error("Exception writing to internal frame buffer", e);
            }
            fb.close();
          }
          public void onError(Exception e) {
            byte msgType = org.apache.thrift.protocol.TMessageType.REPLY;
            org.apache.thrift.TBase msg;
            getApplicationInterface_result result = new getApplicationInterface_result();
            if (e instanceof org.apache.airavata.model.error.InvalidRequestException) {
                        result.ire = (org.apache.airavata.model.error.InvalidRequestException) e;
                        result.setIreIsSet(true);
                        msg = result;
            }
            else             if (e instanceof org.apache.airavata.model.error.AiravataClientException) {
                        result.ace = (org.apache.airavata.model.error.AiravataClientException) e;
                        result.setAceIsSet(true);
                        msg = result;
            }
            else             if (e instanceof org.apache.airavata.model.error.AiravataSystemException) {
                        result.ase = (org.apache.airavata.model.error.AiravataSystemException) e;
                        result.setAseIsSet(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 
            {
              msgType = org.apache.thrift.protocol.TMessageType.EXCEPTION;
              msg = (org.apache.thrift.TBase)new org.apache.thrift.TApplicationException(org.apache.thrift.TApplicationException.INTERNAL_ERROR, e.getMessage());
            }
            try {
              fcall.sendResponse(fb,msg,msgType,seqid);
              return;
            } catch (Exception ex) {
              LOGGER.error("Exception writing to internal frame buffer", ex);
            }
            fb.close();
          }
        };
      }

      protected boolean isOneway() {
        return false;
      }

      public void start(I iface, getApplicationInterface_args args, org.apache.thrift.async.AsyncMethodCallback<org.apache.airavata.model.appcatalog.appinterface.ApplicationInterfaceDescription> resultHandler) throws TException {
        iface.getApplicationInterface(args.authzToken, args.appInterfaceId,resultHandler);
      }
    }

    public static class updateApplicationInterface<I extends AsyncIface> extends org.apache.thrift.AsyncProcessFunction<I, updateApplicationInterface_args, Boolean> {
      public updateApplicationInterface() {
        super("updateApplicationInterface");
      }

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

      public AsyncMethodCallback<Boolean> getResultHandler(final AsyncFrameBuffer fb, final int seqid) {
        final org.apache.thrift.AsyncProcessFunction fcall = this;
        return new AsyncMethodCallback<Boolean>() { 
          public void onComplete(Boolean o) {
            updateApplicationInterface_result result = new updateApplicationInterface_result();
            result.success = o;
            result.setSuccessIsSet(true);
            try {
              fcall.sendResponse(fb,result, org.apache.thrift.protocol.TMessageType.REPLY,seqid);
              return;
            } catch (Exception e) {
              LOGGER.error("Exception writing to internal frame buffer", e);
            }
            fb.close();
          }
          public void onError(Exception e) {
            byte msgType = org.apache.thrift.protocol.TMessageType.REPLY;
            org.apache.thrift.TBase msg;
            updateApplicationInterface_result result = new updateApplicationInterface_result();
            if (e instanceof org.apache.airavata.model.error.InvalidRequestException) {
                        result.ire = (org.apache.airavata.model.error.InvalidRequestException) e;
                        result.setIreIsSet(true);
                        msg = result;
            }
            else             if (e instanceof org.apache.airavata.model.error.AiravataClientException) {
                        result.ace = (org.apache.airavata.model.error.AiravataClientException) e;
                        result.setAceIsSet(true);
                        msg = result;
            }
            else             if (e instanceof org.apache.airavata.model.error.AiravataSystemException) {
                        result.ase = (org.apache.airavata.model.error.AiravataSystemException) e;
                        result.setAseIsSet(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 
            {
              msgType = org.apache.thrift.protocol.TMessageType.EXCEPTION;
              msg = (org.apache.thrift.TBase)new org.apache.thrift.TApplicationException(org.apache.thrift.TApplicationException.INTERNAL_ERROR, e.getMessage());
            }
            try {
              fcall.sendResponse(fb,msg,msgType,seqid);
              return;
            } catch (Exception ex) {
              LOGGER.error("Exception writing to internal frame buffer", ex);
            }
            fb.close();
          }
        };
      }

      protected boolean isOneway() {
        return false;
      }

      public void start(I iface, updateApplicationInterface_args args, org.apache.thrift.async.AsyncMethodCallback<Boolean> resultHandler) throws TException {
        iface.updateApplicationInterface(args.authzToken, args.appInterfaceId, args.applicationInterface,resultHandler);
      }
    }

    public static class deleteApplicationInterface<I extends AsyncIface> extends org.apache.thrift.AsyncProcessFunction<I, deleteApplicationInterface_args, Boolean> {
      public deleteApplicationInterface() {
        super("deleteApplicationInterface");
      }

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

      public AsyncMethodCallback<Boolean> getResultHandler(final AsyncFrameBuffer fb, final int seqid) {
        final org.apache.thrift.AsyncProcessFunction fcall = this;
        return new AsyncMethodCallback<Boolean>() { 
          public void onComplete(Boolean o) {
            deleteApplicationInterface_result result = new deleteApplicationInterface_result();
            result.success = o;
            result.setSuccessIsSet(true);
            try {
              fcall.sendResponse(fb,result, org.apache.thrift.protocol.TMessageType.REPLY,seqid);
              return;
            } catch (Exception e) {
              LOGGER.error("Exception writing to internal frame buffer", e);
            }
            fb.close();
          }
          public void onError(Exception e) {
            byte msgType = org.apache.thrift.protocol.TMessageType.REPLY;
            org.apache.thrift.TBase msg;
            deleteApplicationInterface_result result = new deleteApplicationInterface_result();
            if (e instanceof org.apache.airavata.model.error.InvalidRequestException) {
                        result.ire = (org.apache.airavata.model.error.InvalidRequestException) e;
                        result.setIreIsSet(true);
                        msg = result;
            }
            else             if (e instanceof org.apache.airavata.model.error.AiravataClientException) {
                        result.ace = (org.apache.airavata.model.error.AiravataClientException) e;
                        result.setAceIsSet(true);
                        msg = result;
            }
            else             if (e instanceof org.apache.airavata.model.error.AiravataSystemException) {
                        result.ase = (org.apache.airavata.model.error.AiravataSystemException) e;
                        result.setAseIsSet(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 
            {
              msgType = org.apache.thrift.protocol.TMessageType.EXCEPTION;
              msg = (org.apache.thrift.TBase)new org.apache.thrift.TApplicationException(org.apache.thrift.TApplicationException.INTERNAL_ERROR, e.getMessage());
            }
            try {
              fcall.sendResponse(fb,msg,msgType,seqid);
              return;
            } catch (Exception ex) {
              LOGGER.error("Exception writing to internal frame buffer", ex);
            }
            fb.close();
          }
        };
      }

      protected boolean isOneway() {
        return false;
      }

      public void start(I iface, deleteApplicationInterface_args args, org.apache.thrift.async.AsyncMethodCallback<Boolean> resultHandler) throws TException {
        iface.deleteApplicationInterface(args.authzToken, args.appInterfaceId,resultHandler);
      }
    }

    public static class getAllApplicationInterfaceNames<I extends AsyncIface> extends org.apache.thrift.AsyncProcessFunction<I, getAllApplicationInterfaceNames_args, Map<String,String>> {
      public getAllApplicationInterfaceNames() {
        super("getAllApplicationInterfaceNames");
      }

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

      public AsyncMethodCallback<Map<String,String>> getResultHandler(final AsyncFrameBuffer fb, final int seqid) {
        final org.apache.thrift.AsyncProcessFunction fcall = this;
        return new AsyncMethodCallback<Map<String,String>>() { 
          public void onComplete(Map<String,String> o) {
            getAllApplicationInterfaceNames_result result = new getAllApplicationInterfaceNames_result();
            result.success = o;
            try {
              fcall.sendResponse(fb,result, org.apache.thrift.protocol.TMessageType.REPLY,seqid);
              return;
            } catch (Exception e) {
              LOGGER.error("Exception writing to internal frame buffer", e);
            }
            fb.close();
          }
          public void onError(Exception e) {
            byte msgType = org.apache.thrift.protocol.TMessageType.REPLY;
            org.apache.thrift.TBase msg;
            getAllApplicationInterfaceNames_result result = new getAllApplicationInterfaceNames_result();
            if (e instanceof org.apache.airavata.model.error.InvalidRequestException) {
                        result.ire = (org.apache.airavata.model.error.InvalidRequestException) e;
                        result.setIreIsSet(true);
                        msg = result;
            }
            else             if (e instanceof org.apache.airavata.model.error.AiravataClientException) {
                        result.ace = (org.apache.airavata.model.error.AiravataClientException) e;
                        result.setAceIsSet(true);
                        msg = result;
            }
            else             if (e instanceof org.apache.airavata.model.error.AiravataSystemException) {
                        result.ase = (org.apache.airavata.model.error.AiravataSystemException) e;
                        result.setAseIsSet(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 
            {
              msgType = org.apache.thrift.protocol.TMessageType.EXCEPTION;
              msg = (org.apache.thrift.TBase)new org.apache.thrift.TApplicationException(org.apache.thrift.TApplicationException.INTERNAL_ERROR, e.getMessage());
            }
            try {
              fcall.sendResponse(fb,msg,msgType,seqid);
              return;
            } catch (Exception ex) {
              LOGGER.error("Exception writing to internal frame buffer", ex);
            }
            fb.close();
          }
        };
      }

      protected boolean isOneway() {
        return false;
      }

      public void start(I iface, getAllApplicationInterfaceNames_args args, org.apache.thrift.async.AsyncMethodCallback<Map<String,String>> resultHandler) throws TException {
        iface.getAllApplicationInterfaceNames(args.authzToken, args.gatewayId,resultHandler);
      }
    }

    public static class getAllApplicationInterfaces<I extends AsyncIface> extends org.apache.thrift.AsyncProcessFunction<I, getAllApplicationInterfaces_args, List<org.apache.airavata.model.appcatalog.appinterface.ApplicationInterfaceDescription>> {
      public getAllApplicationInterfaces() {
        super("getAllApplicationInterfaces");
      }

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

      public AsyncMethodCallback<List<org.apache.airavata.model.appcatalog.appinterface.ApplicationInterfaceDescription>> getResultHandler(final AsyncFrameBuffer fb, final int seqid) {
        final org.apache.thrift.AsyncProcessFunction fcall = this;
        return new AsyncMethodCallback<List<org.apache.airavata.model.appcatalog.appinterface.ApplicationInterfaceDescription>>() { 
          public void onComplete(List<org.apache.airavata.model.appcatalog.appinterface.ApplicationInterfaceDescription> o) {
            getAllApplicationInterfaces_result result = new getAllApplicationInterfaces_result();
            result.success = o;
            try {
              fcall.sendResponse(fb,result, org.apache.thrift.protocol.TMessageType.REPLY,seqid);
              return;
            } catch (Exception e) {
              LOGGER.error("Exception writing to internal frame buffer", e);
            }
            fb.close();
          }
          public void onError(Exception e) {
            byte msgType = org.apache.thrift.protocol.TMessageType.REPLY;
            org.apache.thrift.TBase msg;
            getAllApplicationInterfaces_result result = new getAllApplicationInterfaces_result();
            if (e instanceof org.apache.airavata.model.error.InvalidRequestException) {
                        result.ire = (org.apache.airavata.model.error.InvalidRequestException) e;
                        result.setIreIsSet(true);
                        msg = result;
            }
            else             if (e instanceof org.apache.airavata.model.error.AiravataClientException) {
                        result.ace = (org.apache.airavata.model.error.AiravataClientException) e;
                        result.setAceIsSet(true);
                        msg = result;
            }
            else             if (e instanceof org.apache.airavata.model.error.AiravataSystemException) {
                        result.ase = (org.apache.airavata.model.error.AiravataSystemException) e;
                        result.setAseIsSet(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 
            {
              msgType = org.apache.thrift.protocol.TMessageType.EXCEPTION;
              msg = (org.apache.thrift.TBase)new org.apache.thrift.TApplicationException(org.apache.thrift.TApplicationException.INTERNAL_ERROR, e.getMessage());
            }
            try {
              fcall.sendResponse(fb,msg,msgType,seqid);
              return;
            } catch (Exception ex) {
              LOGGER.error("Exception writing to internal frame buffer", ex);
            }
            fb.close();
          }
        };
      }

      protected boolean isOneway() {
        return false;
      }

      public void start(I iface, getAllApplicationInterfaces_args args, org.apache.thrift.async.AsyncMethodCallback<List<org.apache.airavata.model.appcatalog.appinterface.ApplicationInterfaceDescription>> resultHandler) throws TException {
        iface.getAllApplicationInterfaces(args.authzToken, args.gatewayId,resultHandler);
      }
    }

    public static class getApplicationInputs<I extends AsyncIface> extends org.apache.thrift.AsyncProcessFunction<I, getApplicationInputs_args, List<org.apache.airavata.model.application.io.InputDataObjectType>> {
      public getApplicationInputs() {
        super("getApplicationInputs");
      }

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

      public AsyncMethodCallback<List<org.apache.airavata.model.application.io.InputDataObjectType>> getResultHandler(final AsyncFrameBuffer fb, final int seqid) {
        final org.apache.thrift.AsyncProcessFunction fcall = this;
        return new AsyncMethodCallback<List<org.apache.airavata.model.application.io.InputDataObjectType>>() { 
          public void onComplete(List<org.apache.airavata.model.application.io.InputDataObjectType> o) {
            getApplicationInputs_result result = new getApplicationInputs_result();
            result.success = o;
            try {
              fcall.sendResponse(fb,result, org.apache.thrift.protocol.TMessageType.REPLY,seqid);
              return;
            } catch (Exception e) {
              LOGGER.error("Exception writing to internal frame buffer", e);
            }
            fb.close();
          }
          public void onError(Exception e) {
            byte msgType = org.apache.thrift.protocol.TMessageType.REPLY;
            org.apache.thrift.TBase msg;
            getApplicationInputs_result result = new getApplicationInputs_result();
            if (e instanceof org.apache.airavata.model.error.InvalidRequestException) {
                        result.ire = (org.apache.airavata.model.error.InvalidRequestException) e;
                        result.setIreIsSet(true);
                        msg = result;
            }
            else             if (e instanceof org.apache.airavata.model.error.AiravataClientException) {
                        result.ace = (org.apache.airavata.model.error.AiravataClientException) e;
                        result.setAceIsSet(true);
                        msg = result;
            }
            else             if (e instanceof org.apache.airavata.model.error.AiravataSystemException) {
                        result.ase = (org.apache.airavata.model.error.AiravataSystemException) e;
                        result.setAseIsSet(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 
            {
              msgType = org.apache.thrift.protocol.TMessageType.EXCEPTION;
              msg = (org.apache.thrift.TBase)new org.apache.thrift.TApplicationException(org.apache.thrift.TApplicationException.INTERNAL_ERROR, e.getMessage());
            }
            try {
              fcall.sendResponse(fb,msg,msgType,seqid);
              return;
            } catch (Exception ex) {
              LOGGER.error("Exception writing to internal frame buffer", ex);
            }
            fb.close();
          }
        };
      }

      protected boolean isOneway() {
        return false;
      }

      public void start(I iface, getApplicationInputs_args args, org.apache.thrift.async.AsyncMethodCallback<List<org.apache.airavata.model.application.io.InputDataObjectType>> resultHandler) throws TException {
        iface.getApplicationInputs(args.authzToken, args.appInterfaceId,resultHandler);
      }
    }

    public static class getApplicationOutputs<I extends AsyncIface> extends org.apache.thrift.AsyncProcessFunction<I, getApplicationOutputs_args, List<org.apache.airavata.model.application.io.OutputDataObjectType>> {
      public getApplicationOutputs() {
        super("getApplicationOutputs");
      }

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

      public AsyncMethodCallback<List<org.apache.airavata.model.application.io.OutputDataObjectType>> getResultHandler(final AsyncFrameBuffer fb, final int seqid) {
        final org.apache.thrift.AsyncProcessFunction fcall = this;
        return new AsyncMethodCallback<List<org.apache.airavata.model.application.io.OutputDataObjectType>>() { 
          public void onComplete(List<org.apache.airavata.model.application.io.OutputDataObjectType> o) {
            getApplicationOutputs_result result = new getApplicationOutputs_result();
            result.success = o;
            try {
              fcall.sendResponse(fb,result, org.apache.thrift.protocol.TMessageType.REPLY,seqid);
              return;
            } catch (Exception e) {
              LOGGER.error("Exception writing to internal frame buffer", e);
            }
            fb.close();
          }
          public void onError(Exception e) {
            byte msgType = org.apache.thrift.protocol.TMessageType.REPLY;
            org.apache.thrift.TBase msg;
            getApplicationOutputs_result result = new getApplicationOutputs_result();
            if (e instanceof org.apache.airavata.model.error.InvalidRequestException) {
                        result.ire = (org.apache.airavata.model.error.InvalidRequestException) e;
                        result.setIreIsSet(true);
                        msg = result;
            }
            else             if (e instanceof org.apache.airavata.model.error.AiravataClientException) {
                        result.ace = (org.apache.airavata.model.error.AiravataClientException) e;
                        result.setAceIsSet(true);
                        msg = result;
            }
            else             if (e instanceof org.apache.airavata.model.error.AiravataSystemException) {
                        result.ase = (org.apache.airavata.model.error.AiravataSystemException) e;
                        result.setAseIsSet(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 
            {
              msgType = org.apache.thrift.protocol.TMessageType.EXCEPTION;
              msg = (org.apache.thrift.TBase)new org.apache.thrift.TApplicationException(org.apache.thrift.TApplicationException.INTERNAL_ERROR, e.getMessage());
            }
            try {
              fcall.sendResponse(fb,msg,msgType,seqid);
              return;
            } catch (Exception ex) {
              LOGGER.error("Exception writing to internal frame buffer", ex);
            }
            fb.close();
          }
        };
      }

      protected boolean isOneway() {
        return false;
      }

      public void start(I iface, getApplicationOutputs_args args, org.apache.thrift.async.AsyncMethodCallback<List<org.apache.airavata.model.application.io.OutputDataObjectType>> resultHandler) throws TException {
        iface.getApplicationOutputs(args.authzToken, args.appInterfaceId,resultHandler);
      }
    }

    public static class getAvailableAppInterfaceComputeResources<I extends AsyncIface> extends org.apache.thrift.AsyncProcessFunction<I, getAvailableAppInterfaceComputeResources_args, Map<String,String>> {
      public getAvailableAppInterfaceComputeResources() {
        super("getAvailableAppInterfaceComputeResources");
      }

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

      public AsyncMethodCallback<Map<String,String>> getResultHandler(final AsyncFrameBuffer fb, final int seqid) {
        final org.apache.thrift.AsyncProcessFunction fcall = this;
        return new AsyncMethodCallback<Map<String,String>>() { 
          public void onComplete(Map<String,String> o) {
            getAvailableAppInterfaceComputeResources_result result = new getAvailableAppInterfaceComputeResources_result();
            result.success = o;
            try {
              fcall.sendResponse(fb,result, org.apache.thrift.protocol.TMessageType.REPLY,seqid);
              return;
            } catch (Exception e) {
              LOGGER.error("Exception writing to internal frame buffer", e);
            }
            fb.close();
          }
          public void onError(Exception e) {
            byte msgType = org.apache.thrift.protocol.TMessageType.REPLY;
            org.apache.thrift.TBase msg;
            getAvailableAppInterfaceComputeResources_result result = new getAvailableAppInterfaceComputeResources_result();
            if (e instanceof org.apache.airavata.model.error.InvalidRequestException) {
                        result.ire = (org.apache.airavata.model.error.InvalidRequestException) e;
                        result.setIreIsSet(true);
                        msg = result;
            }
            else             if (e instanceof org.apache.airavata.model.error.AiravataClientException) {
                        result.ace = (org.apache.airavata.model.error.AiravataClientException) e;
                        result.setAceIsSet(true);
                        msg = result;
            }
            else             if (e instanceof org.apache.airavata.model.error.AiravataSystemException) {
                        result.ase = (org.apache.airavata.model.error.AiravataSystemException) e;
                        result.setAseIsSet(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 
            {
              msgType = org.apache.thrift.protocol.TMessageType.EXCEPTION;
              msg = (org.apache.thrift.TBase)new org.apache.thrift.TApplicationException(org.apache.thrift.TApplicationException.INTERNAL_ERROR, e.getMessage());
            }
            try {
              fcall.sendResponse(fb,msg,msgType,seqid);
              return;
            } catch (Exception ex) {
              LOGGER.error("Exception writing to internal frame buffer", ex);
            }
            fb.close();
          }
        };
      }

      protected boolean isOneway() {
        return false;
      }

      public void start(I iface, getAvailableAppInterfaceComputeResources_args args, org.apache.thrift.async.AsyncMethodCallback<Map<String,String>> resultHandler) throws TException {
        iface.getAvailableAppInterfaceComputeResources(args.authzToken, args.appInterfaceId,resultHandler);
      }
    }

    public static class registerComputeResource<I extends AsyncIface> extends org.apache.thrift.AsyncProcessFunction<I, registerComputeResource_args, String> {
      public registerComputeResource() {
        super("registerComputeResource");
      }

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

      public AsyncMethodCallback<String> getResultHandler(final AsyncFrameBuffer fb, final int seqid) {
        final org.apache.thrift.AsyncProcessFunction fcall = this;
        return new AsyncMethodCallback<String>() { 
          public void onComplete(String o) {
            registerComputeResource_result result = new registerComputeResource_result();
            result.success = o;
            try {
              fcall.sendResponse(fb,result, org.apache.thrift.protocol.TMessageType.REPLY,seqid);
              return;
            } catch (Exception e) {
              LOGGER.error("Exception writing to internal frame buffer", e);
            }
            fb.close();
          }
          public void onError(Exception e) {
            byte msgType = org.apache.thrift.protocol.TMessageType.REPLY;
            org.apache.thrift.TBase msg;
            registerComputeResource_result result = new registerComputeResource_result();
            if (e instanceof org.apache.airavata.model.error.InvalidRequestException) {
                        result.ire = (org.apache.airavata.model.error.InvalidRequestException) e;
                        result.setIreIsSet(true);
                        msg = result;
            }
            else             if (e instanceof org.apache.airavata.model.error.AiravataClientException) {
                        result.ace = (org.apache.airavata.model.error.AiravataClientException) e;
                        result.setAceIsSet(true);
                        msg = result;
            }
            else             if (e instanceof org.apache.airavata.model.error.AiravataSystemException) {
                        result.ase = (org.apache.airavata.model.error.AiravataSystemException) e;
                        result.setAseIsSet(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 
            {
              msgType = org.apache.thrift.protocol.TMessageType.EXCEPTION;
              msg = (org.apache.thrift.TBase)new org.apache.thrift.TApplicationException(org.apache.thrift.TApplicationException.INTERNAL_ERROR, e.getMessage());
            }
            try {
              fcall.sendResponse(fb,msg,msgType,seqid);
              return;
            } catch (Exception ex) {
              LOGGER.error("Exception writing to internal frame buffer", ex);
            }
            fb.close();
          }
        };
      }

      protected boolean isOneway() {
        return false;
      }

      public void start(I iface, registerComputeResource_args args, org.apache.thrift.async.AsyncMethodCallback<String> resultHandler) throws TException {
        iface.registerComputeResource(args.authzToken, args.computeResourceDescription,resultHandler);
      }
    }

    public static class getComputeResource<I extends AsyncIface> extends org.apache.thrift.AsyncProcessFunction<I, getComputeResource_args, org.apache.airavata.model.appcatalog.computeresource.ComputeResourceDescription> {
      public getComputeResource() {
        super("getComputeResource");
      }

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

      public AsyncMethodCallback<org.apache.airavata.model.appcatalog.computeresource.ComputeResourceDescription> getResultHandler(final AsyncFrameBuffer fb, final int seqid) {
        final org.apache.thrift.AsyncProcessFunction fcall = this;
        return new AsyncMethodCallback<org.apache.airavata.model.appcatalog.computeresource.ComputeResourceDescription>() { 
          public void onComplete(org.apache.airavata.model.appcatalog.computeresource.ComputeResourceDescription o) {
            getComputeResource_result result = new getComputeResource_result();
            result.success = o;
            try {
              fcall.sendResponse(fb,result, org.apache.thrift.protocol.TMessageType.REPLY,seqid);
              return;
            } catch (Exception e) {
              LOGGER.error("Exception writing to internal frame buffer", e);
            }
            fb.close();
          }
          public void onError(Exception e) {
            byte msgType = org.apache.thrift.protocol.TMessageType.REPLY;
            org.apache.thrift.TBase msg;
            getComputeResource_result result = new getComputeResource_result();
            if (e instanceof org.apache.airavata.model.error.InvalidRequestException) {
                        result.ire = (org.apache.airavata.model.error.InvalidRequestException) e;
                        result.setIreIsSet(true);
                        msg = result;
            }
            else             if (e instanceof org.apache.airavata.model.error.AiravataClientException) {
                        result.ace = (org.apache.airavata.model.error.AiravataClientException) e;
                        result.setAceIsSet(true);
                        msg = result;
            }
            else             if (e instanceof org.apache.airavata.model.error.AiravataSystemException) {
                        result.ase = (org.apache.airavata.model.error.AiravataSystemException) e;
                        result.setAseIsSet(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 
            {
              msgType = org.apache.thrift.protocol.TMessageType.EXCEPTION;
              msg = (org.apache.thrift.TBase)new org.apache.thrift.TApplicationException(org.apache.thrift.TApplicationException.INTERNAL_ERROR, e.getMessage());
            }
            try {
              fcall.sendResponse(fb,msg,msgType,seqid);
              return;
            } catch (Exception ex) {
              LOGGER.error("Exception writing to internal frame buffer", ex);
            }
            fb.close();
          }
        };
      }

      protected boolean isOneway() {
        return false;
      }

      public void start(I iface, getComputeResource_args args, org.apache.thrift.async.AsyncMethodCallback<org.apache.airavata.model.appcatalog.computeresource.ComputeResourceDescription> resultHandler) throws TException {
        iface.getComputeResource(args.authzToken, args.computeResourceId,resultHandler);
      }
    }

    public static class getAllComputeResourceNames<I extends AsyncIface> extends org.apache.thrift.AsyncProcessFunction<I, getAllComputeResourceNames_args, Map<String,String>> {
      public getAllComputeResourceNames() {
        super("getAllComputeResourceNames");
      }

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

      public AsyncMethodCallback<Map<String,String>> getResultHandler(final AsyncFrameBuffer fb, final int seqid) {
        final org.apache.thrift.AsyncProcessFunction fcall = this;
        return new AsyncMethodCallback<Map<String,String>>() { 
          public void onComplete(Map<String,String> o) {
            getAllComputeResourceNames_result result = new getAllComputeResourceNames_result();
            result.success = o;
            try {
              fcall.sendResponse(fb,result, org.apache.thrift.protocol.TMessageType.REPLY,seqid);
              return;
            } catch (Exception e) {
              LOGGER.error("Exception writing to internal frame buffer", e);
            }
            fb.close();
          }
          public void onError(Exception e) {
            byte msgType = org.apache.thrift.protocol.TMessageType.REPLY;
            org.apache.thrift.TBase msg;
            getAllComputeResourceNames_result result = new getAllComputeResourceNames_result();
            if (e instanceof org.apache.airavata.model.error.InvalidRequestException) {
                        result.ire = (org.apache.airavata.model.error.InvalidRequestException) e;
                        result.setIreIsSet(true);
                        msg = result;
            }
            else             if (e instanceof org.apache.airavata.model.error.AiravataClientException) {
                        result.ace = (org.apache.airavata.model.error.AiravataClientException) e;
                        result.setAceIsSet(true);
                        msg = result;
            }
            else             if (e instanceof org.apache.airavata.model.error.AiravataSystemException) {
                        result.ase = (org.apache.airavata.model.error.AiravataSystemException) e;
                        result.setAseIsSet(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 
            {
              msgType = org.apache.thrift.protocol.TMessageType.EXCEPTION;
              msg = (org.apache.thrift.TBase)new org.apache.thrift.TApplicationException(org.apache.thrift.TApplicationException.INTERNAL_ERROR, e.getMessage());
            }
            try {
              fcall.sendResponse(fb,msg,msgType,seqid);
              return;
            } catch (Exception ex) {
              LOGGER.error("Exception writing to internal frame buffer", ex);
            }
            fb.close();
          }
        };
      }

      protected boolean isOneway() {
        return false;
      }

      public void start(I iface, getAllComputeResourceNames_args args, org.apache.thrift.async.AsyncMethodCallback<Map<String,String>> resultHandler) throws TException {
        iface.getAllComputeResourceNames(args.authzToken,resultHandler);
      }
    }

    public static class updateComputeResource<I extends AsyncIface> extends org.apache.thrift.AsyncProcessFunction<I, updateComputeResource_args, Boolean> {
      public updateComputeResource() {
        super("updateComputeResource");
      }

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

      public AsyncMethodCallback<Boolean> getResultHandler(final AsyncFrameBuffer fb, final int seqid) {
        final org.apache.thrift.AsyncProcessFunction fcall = this;
        return new AsyncMethodCallback<Boolean>() { 
          public void onComplete(Boolean o) {
            updateComputeResource_result result = new updateComputeResource_result();
            result.success = o;
            result.setSuccessIsSet(true);
            try {
              fcall.sendResponse(fb,result, org.apache.thrift.protocol.TMessageType.REPLY,seqid);
              return;
            } catch (Exception e) {
              LOGGER.error("Exception writing to internal frame buffer", e);
            }
            fb.close();
          }
          public void onError(Exception e) {
            byte msgType = org.apache.thrift.protocol.TMessageType.REPLY;
            org.apache.thrift.TBase msg;
            updateComputeResource_result result = new updateComputeResource_result();
            if (e instanceof org.apache.airavata.model.error.InvalidRequestException) {
                        result.ire = (org.apache.airavata.model.error.InvalidRequestException) e;
                        result.setIreIsSet(true);
                        msg = result;
            }
            else             if (e instanceof org.apache.airavata.model.error.AiravataClientException) {
                        result.ace = (org.apache.airavata.model.error.AiravataClientException) e;
                        result.setAceIsSet(true);
                        msg = result;
            }
            else             if (e instanceof org.apache.airavata.model.error.AiravataSystemException) {
                        result.ase = (org.apache.airavata.model.error.AiravataSystemException) e;
                        result.setAseIsSet(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 
            {
              msgType = org.apache.thrift.protocol.TMessageType.EXCEPTION;
              msg = (org.apache.thrift.TBase)new org.apache.thrift.TApplicationException(org.apache.thrift.TApplicationException.INTERNAL_ERROR, e.getMessage());
            }
            try {
              fcall.sendResponse(fb,msg,msgType,seqid);
              return;
            } catch (Exception ex) {
              LOGGER.error("Exception writing to internal frame buffer", ex);
            }
            fb.close();
          }
        };
      }

      protected boolean isOneway() {
        return false;
      }

      public void start(I iface, updateComputeResource_args args, org.apache.thrift.async.AsyncMethodCallback<Boolean> resultHandler) throws TException {
        iface.updateComputeResource(args.authzToken, args.computeResourceId, args.computeResourceDescription,resultHandler);
      }
    }

    public static class deleteComputeResource<I extends AsyncIface> extends org.apache.thrift.AsyncProcessFunction<I, deleteComputeResource_args, Boolean> {
      public deleteComputeResource() {
        super("deleteComputeResource");
      }

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

      public AsyncMethodCallback<Boolean> getResultHandler(final AsyncFrameBuffer fb, final int seqid) {
        final org.apache.thrift.AsyncProcessFunction fcall = this;
        return new AsyncMethodCallback<Boolean>() { 
          public void onComplete(Boolean o) {
            deleteComputeResource_result result = new deleteComputeResource_result();
            result.success = o;
            result.setSuccessIsSet(true);
            try {
              fcall.sendResponse(fb,result, org.apache.thrift.protocol.TMessageType.REPLY,seqid);
              return;
            } catch (Exception e) {
              LOGGER.error("Exception writing to internal frame buffer", e);
            }
            fb.close();
          }
          public void onError(Exception e) {
            byte msgType = org.apache.thrift.protocol.TMessageType.REPLY;
            org.apache.thrift.TBase msg;
            deleteComputeResource_result result = new deleteComputeResource_result();
            if (e instanceof org.apache.airavata.model.error.InvalidRequestException) {
                        result.ire = (org.apache.airavata.model.error.InvalidRequestException) e;
                        result.setIreIsSet(true);
                        msg = result;
            }
            else             if (e instanceof org.apache.airavata.model.error.AiravataClientException) {
                        result.ace = (org.apache.airavata.model.error.AiravataClientException) e;
                        result.setAceIsSet(true);
                        msg = result;
            }
            else             if (e instanceof org.apache.airavata.model.error.AiravataSystemException) {
                        result.ase = (org.apache.airavata.model.error.AiravataSystemException) e;
                        result.setAseIsSet(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 
            {
              msgType = org.apache.thrift.protocol.TMessageType.EXCEPTION;
              msg = (org.apache.thrift.TBase)new org.apache.thrift.TApplicationException(org.apache.thrift.TApplicationException.INTERNAL_ERROR, e.getMessage());
            }
            try {
              fcall.sendResponse(fb,msg,msgType,seqid);
              return;
            } catch (Exception ex) {
              LOGGER.error("Exception writing to internal frame buffer", ex);
            }
            fb.close();
          }
        };
      }

      protected boolean isOneway() {
        return false;
      }

      public void start(I iface, deleteComputeResource_args args, org.apache.thrift.async.AsyncMethodCallback<Boolean> resultHandler) throws TException {
        iface.deleteComputeResource(args.authzToken, args.computeResourceId,resultHandler);
      }
    }

    public static class addLocalSubmissionDetails<I extends AsyncIface> extends org.apache.thrift.AsyncProcessFunction<I, addLocalSubmissionDetails_args, String> {
      public addLocalSubmissionDetails() {
        super("addLocalSubmissionDetails");
      }

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

      public AsyncMethodCallback<String> getResultHandler(final AsyncFrameBuffer fb, final int seqid) {
        final org.apache.thrift.AsyncProcessFunction fcall = this;
        return new AsyncMethodCallback<String>() { 
          public void onComplete(String o) {
            addLocalSubmissionDetails_result result = new addLocalSubmissionDetails_result();
            result.success = o;
            try {
              fcall.sendResponse(fb,result, org.apache.thrift.protocol.TMessageType.REPLY,seqid);
              return;
            } catch (Exception e) {
              LOGGER.error("Exception writing to internal frame buffer", e);
            }
            fb.close();
          }
          public void onError(Exception e) {
            byte msgType = org.apache.thrift.protocol.TMessageType.REPLY;
            org.apache.thrift.TBase msg;
            addLocalSubmissionDetails_result result = new addLocalSubmissionDetails_result();
            if (e instanceof org.apache.airavata.model.error.InvalidRequestException) {
                        result.ire = (org.apache.airavata.model.error.InvalidRequestException) e;
                        result.setIreIsSet(true);
                        msg = result;
            }
            else             if (e instanceof org.apache.airavata.model.error.AiravataClientException) {
                        result.ace = (org.apache.airavata.model.error.AiravataClientException) e;
                        result.setAceIsSet(true);
                        msg = result;
            }
            else             if (e instanceof org.apache.airavata.model.error.AiravataSystemException) {
                        result.ase = (org.apache.airavata.model.error.AiravataSystemException) e;
                        result.setAseIsSet(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 
            {
              msgType = org.apache.thrift.protocol.TMessageType.EXCEPTION;
              msg = (org.apache.thrift.TBase)new org.apache.thrift.TApplicationException(org.apache.thrift.TApplicationException.INTERNAL_ERROR, e.getMessage());
            }
            try {
              fcall.sendResponse(fb,msg,msgType,seqid);
              return;
            } catch (Exception ex) {
              LOGGER.error("Exception writing to internal frame buffer", ex);
            }
            fb.close();
          }
        };
      }

      protected boolean isOneway() {
        return false;
      }

      public void start(I iface, addLocalSubmissionDetails_args args, org.apache.thrift.async.AsyncMethodCallback<String> resultHandler) throws TException {
        iface.addLocalSubmissionDetails(args.authzToken, args.computeResourceId, args.priorityOrder, args.localSubmission,resultHandler);
      }
    }

    public static class updateLocalSubmissionDetails<I extends AsyncIface> extends org.apache.thrift.AsyncProcessFunction<I, updateLocalSubmissionDetails_args, Boolean> {
      public updateLocalSubmissionDetails() {
        super("updateLocalSubmissionDetails");
      }

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

      public AsyncMethodCallback<Boolean> getResultHandler(final AsyncFrameBuffer fb, final int seqid) {
        final org.apache.thrift.AsyncProcessFunction fcall = this;
        return new AsyncMethodCallback<Boolean>() { 
          public void onComplete(Boolean o) {
            updateLocalSubmissionDetails_result result = new updateLocalSubmissionDetails_result();
            result.success = o;
            result.setSuccessIsSet(true);
            try {
              fcall.sendResponse(fb,result, org.apache.thrift.protocol.TMessageType.REPLY,seqid);
              return;
            } catch (Exception e) {
              LOGGER.error("Exception writing to internal frame buffer", e);
            }
            fb.close();
          }
          public void onError(Exception e) {
            byte msgType = org.apache.thrift.protocol.TMessageType.REPLY;
            org.apache.thrift.TBase msg;
            updateLocalSubmissionDetails_result result = new updateLocalSubmissionDetails_result();
            if (e instanceof org.apache.airavata.model.error.InvalidRequestException) {
                        result.ire = (org.apache.airavata.model.error.InvalidRequestException) e;
                        result.setIreIsSet(true);
                        msg = result;
            }
            else             if (e instanceof org.apache.airavata.model.error.AiravataClientException) {
                        result.ace = (org.apache.airavata.model.error.AiravataClientException) e;
                        result.setAceIsSet(true);
                        msg = result;
            }
            else             if (e instanceof org.apache.airavata.model.error.AiravataSystemException) {
                        result.ase = (org.apache.airavata.model.error.AiravataSystemException) e;
                        result.setAseIsSet(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 
            {
              msgType = org.apache.thrift.protocol.TMessageType.EXCEPTION;
              msg = (org.apache.thrift.TBase)new org.apache.thrift.TApplicationException(org.apache.thrift.TApplicationException.INTERNAL_ERROR, e.getMessage());
            }
            try {
              fcall.sendResponse(fb,msg,msgType,seqid);
              return;
            } catch (Exception ex) {
              LOGGER.error("Exception writing to internal frame buffer", ex);
            }
            fb.close();
          }
        };
      }

      protected boolean isOneway() {
        return false;
      }

      public void start(I iface, updateLocalSubmissionDetails_args args, org.apache.thrift.async.AsyncMethodCallback<Boolean> resultHandler) throws TException {
        iface.updateLocalSubmissionDetails(args.authzToken, args.jobSubmissionInterfaceId, args.localSubmission,resultHandler);
      }
    }

    public static class getLocalJobSubmission<I extends AsyncIface> extends org.apache.thrift.AsyncProcessFunction<I, getLocalJobSubmission_args, org.apache.airavata.model.appcatalog.computeresource.LOCALSubmission> {
      public getLocalJobSubmission() {
        super("getLocalJobSubmission");
      }

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

      public AsyncMethodCallback<org.apache.airavata.model.appcatalog.computeresource.LOCALSubmission> getResultHandler(final AsyncFrameBuffer fb, final int seqid) {
        final org.apache.thrift.AsyncProcessFunction fcall = this;
        return new AsyncMethodCallback<org.apache.airavata.model.appcatalog.computeresource.LOCALSubmission>() { 
          public void onComplete(org.apache.airavata.model.appcatalog.computeresource.LOCALSubmission o) {
            getLocalJobSubmission_result result = new getLocalJobSubmission_result();
            result.success = o;
            try {
              fcall.sendResponse(fb,result, org.apache.thrift.protocol.TMessageType.REPLY,seqid);
              return;
            } catch (Exception e) {
              LOGGER.error("Exception writing to internal frame buffer", e);
            }
            fb.close();
          }
          public void onError(Exception e) {
            byte msgType = org.apache.thrift.protocol.TMessageType.REPLY;
            org.apache.thrift.TBase msg;
            getLocalJobSubmission_result result = new getLocalJobSubmission_result();
            if (e instanceof org.apache.airavata.model.error.InvalidRequestException) {
                        result.ire = (org.apache.airavata.model.error.InvalidRequestException) e;
                        result.setIreIsSet(true);
                        msg = result;
            }
            else             if (e instanceof org.apache.airavata.model.error.AiravataClientException) {
                        result.ace = (org.apache.airavata.model.error.AiravataClientException) e;
                        result.setAceIsSet(true);
                        msg = result;
            }
            else             if (e instanceof org.apache.airavata.model.error.AiravataSystemException) {
                        result.ase = (org.apache.airavata.model.error.AiravataSystemException) e;
                        result.setAseIsSet(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 
            {
              msgType = org.apache.thrift.protocol.TMessageType.EXCEPTION;
              msg = (org.apache.thrift.TBase)new org.apache.thrift.TApplicationException(org.apache.thrift.TApplicationException.INTERNAL_ERROR, e.getMessage());
            }
            try {
              fcall.sendResponse(fb,msg,msgType,seqid);
              return;
            } catch (Exception ex) {
              LOGGER.error("Exception writing to internal frame buffer", ex);
            }
            fb.close();
          }
        };
      }

      protected boolean isOneway() {
        return false;
      }

      public void start(I iface, getLocalJobSubmission_args args, org.apache.thrift.async.AsyncMethodCallback<org.apache.airavata.model.appcatalog.computeresource.LOCALSubmission> resultHandler) throws TException {
        iface.getLocalJobSubmission(args.authzToken, args.jobSubmissionId,resultHandler);
      }
    }

    public static class addSSHJobSubmissionDetails<I extends AsyncIface> extends org.apache.thrift.AsyncProcessFunction<I, addSSHJobSubmissionDetails_args, String> {
      public addSSHJobSubmissionDetails() {
        super("addSSHJobSubmissionDetails");
      }

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

      public AsyncMethodCallback<String> getResultHandler(final AsyncFrameBuffer fb, final int seqid) {
        final org.apache.thrift.AsyncProcessFunction fcall = this;
        return new AsyncMethodCallback<String>() { 
          public void onComplete(String o) {
            addSSHJobSubmissionDetails_result result = new addSSHJobSubmissionDetails_result();
            result.success = o;
            try {
              fcall.sendResponse(fb,result, org.apache.thrift.protocol.TMessageType.REPLY,seqid);
              return;
            } catch (Exception e) {
              LOGGER.error("Exception writing to internal frame buffer", e);
            }
            fb.close();
          }
          public void onError(Exception e) {
            byte msgType = org.apache.thrift.protocol.TMessageType.REPLY;
            org.apache.thrift.TBase msg;
            addSSHJobSubmissionDetails_result result = new addSSHJobSubmissionDetails_result();
            if (e instanceof org.apache.airavata.model.error.InvalidRequestException) {
                        result.ire = (org.apache.airavata.model.error.InvalidRequestException) e;
                        result.setIreIsSet(true);
                        msg = result;
            }
            else             if (e instanceof org.apache.airavata.model.error.AiravataClientException) {
                        result.ace = (org.apache.airavata.model.error.AiravataClientException) e;
                        result.setAceIsSet(true);
                        msg = result;
            }
            else             if (e instanceof org.apache.airavata.model.error.AiravataSystemException) {
                        result.ase = (org.apache.airavata.model.error.AiravataSystemException) e;
                        result.setAseIsSet(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 
            {
              msgType = org.apache.thrift.protocol.TMessageType.EXCEPTION;
              msg = (org.apache.thrift.TBase)new org.apache.thrift.TApplicationException(org.apache.thrift.TApplicationException.INTERNAL_ERROR, e.getMessage());
            }
            try {
              fcall.sendResponse(fb,msg,msgType,seqid);
              return;
            } catch (Exception ex) {
              LOGGER.error("Exception writing to internal frame buffer", ex);
            }
            fb.close();
          }
        };
      }

      protected boolean isOneway() {
        return false;
      }

      public void start(I iface, addSSHJobSubmissionDetails_args args, org.apache.thrift.async.AsyncMethodCallback<String> resultHandler) throws TException {
        iface.addSSHJobSubmissionDetails(args.authzToken, args.computeResourceId, args.priorityOrder, args.sshJobSubmission,resultHandler);
      }
    }

    public static class addSSHForkJobSubmissionDetails<I extends AsyncIface> extends org.apache.thrift.AsyncProcessFunction<I, addSSHForkJobSubmissionDetails_args, String> {
      public addSSHForkJobSubmissionDetails() {
        super("addSSHForkJobSubmissionDetails");
      }

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

      public AsyncMethodCallback<String> getResultHandler(final AsyncFrameBuffer fb, final int seqid) {
        final org.apache.thrift.AsyncProcessFunction fcall = this;
        return new AsyncMethodCallback<String>() { 
          public void onComplete(String o) {
            addSSHForkJobSubmissionDetails_result result = new addSSHForkJobSubmissionDetails_result();
            result.success = o;
            try {
              fcall.sendResponse(fb,result, org.apache.thrift.protocol.TMessageType.REPLY,seqid);
              return;
            } catch (Exception e) {
              LOGGER.error("Exception writing to internal frame buffer", e);
            }
            fb.close();
          }
          public void onError(Exception e) {
            byte msgType = org.apache.thrift.protocol.TMessageType.REPLY;
            org.apache.thrift.TBase msg;
            addSSHForkJobSubmissionDetails_result result = new addSSHForkJobSubmissionDetails_result();
            if (e instanceof org.apache.airavata.model.error.InvalidRequestException) {
                        result.ire = (org.apache.airavata.model.error.InvalidRequestException) e;
                        result.setIreIsSet(true);
                        msg = result;
            }
            else             if (e instanceof org.apache.airavata.model.error.AiravataClientException) {
                        result.ace = (org.apache.airavata.model.error.AiravataClientException) e;
                        result.setAceIsSet(true);
                        msg = result;
            }
            else             if (e instanceof org.apache.airavata.model.error.AiravataSystemException) {
                        result.ase = (org.apache.airavata.model.error.AiravataSystemException) e;
                        result.setAseIsSet(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 
            {
              msgType = org.apache.thrift.protocol.TMessageType.EXCEPTION;
              msg = (org.apache.thrift.TBase)new org.apache.thrift.TApplicationException(org.apache.thrift.TApplicationException.INTERNAL_ERROR, e.getMessage());
            }
            try {
              fcall.sendResponse(fb,msg,msgType,seqid);
              return;
            } catch (Exception ex) {
              LOGGER.error("Exception writing to internal frame buffer", ex);
            }
            fb.close();
          }
        };
      }

      protected boolean isOneway() {
        return false;
      }

      public void start(I iface, addSSHForkJobSubmissionDetails_args args, org.apache.thrift.async.AsyncMethodCallback<String> resultHandler) throws TException {
        iface.addSSHForkJobSubmissionDetails(args.authzToken, args.computeResourceId, args.priorityOrder, args.sshJobSubmission,resultHandler);
      }
    }

    public static class getSSHJobSubmission<I extends AsyncIface> extends org.apache.thrift.AsyncProcessFunction<I, getSSHJobSubmission_args, org.apache.airavata.model.appcatalog.computeresource.SSHJobSubmission> {
      public getSSHJobSubmission() {
        super("getSSHJobSubmission");
      }

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

      public AsyncMethodCallback<org.apache.airavata.model.appcatalog.computeresource.SSHJobSubmission> getResultHandler(final AsyncFrameBuffer fb, final int seqid) {
        final org.apache.thrift.AsyncProcessFunction fcall = this;
        return new AsyncMethodCallback<org.apache.airavata.model.appcatalog.computeresource.SSHJobSubmission>() { 
          public void onComplete(org.apache.airavata.model.appcatalog.computeresource.SSHJobSubmission o) {
            getSSHJobSubmission_result result = new getSSHJobSubmission_result();
            result.success = o;
            try {
              fcall.sendResponse(fb,result, org.apache.thrift.protocol.TMessageType.REPLY,seqid);
              return;
            } catch (Exception e) {
              LOGGER.error("Exception writing to internal frame buffer", e);
            }
            fb.close();
          }
          public void onError(Exception e) {
            byte msgType = org.apache.thrift.protocol.TMessageType.REPLY;
            org.apache.thrift.TBase msg;
            getSSHJobSubmission_result result = new getSSHJobSubmission_result();
            if (e instanceof org.apache.airavata.model.error.InvalidRequestException) {
                        result.ire = (org.apache.airavata.model.error.InvalidRequestException) e;
                        result.setIreIsSet(true);
                        msg = result;
            }
            else             if (e instanceof org.apache.airavata.model.error.AiravataClientException) {
                        result.ace = (org.apache.airavata.model.error.AiravataClientException) e;
                        result.setAceIsSet(true);
                        msg = result;
            }
            else             if (e instanceof org.apache.airavata.model.error.AiravataSystemException) {
                        result.ase = (org.apache.airavata.model.error.AiravataSystemException) e;
                        result.setAseIsSet(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 
            {
              msgType = org.apache.thrift.protocol.TMessageType.EXCEPTION;
              msg = (org.apache.thrift.TBase)new org.apache.thrift.TApplicationException(org.apache.thrift.TApplicationException.INTERNAL_ERROR, e.getMessage());
            }
            try {
              fcall.sendResponse(fb,msg,msgType,seqid);
              return;
            } catch (Exception ex) {
              LOGGER.error("Exception writing to internal frame buffer", ex);
            }
            fb.close();
          }
        };
      }

      protected boolean isOneway() {
        return false;
      }

      public void start(I iface, getSSHJobSubmission_args args, org.apache.thrift.async.AsyncMethodCallback<org.apache.airavata.model.appcatalog.computeresource.SSHJobSubmission> resultHandler) throws TException {
        iface.getSSHJobSubmission(args.authzToken, args.jobSubmissionId,resultHandler);
      }
    }

    public static class addUNICOREJobSubmissionDetails<I extends AsyncIface> extends org.apache.thrift.AsyncProcessFunction<I, addUNICOREJobSubmissionDetails_args, String> {
      public addUNICOREJobSubmissionDetails() {
        super("addUNICOREJobSubmissionDetails");
      }

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

      public AsyncMethodCallback<String> getResultHandler(final AsyncFrameBuffer fb, final int seqid) {
        final org.apache.thrift.AsyncProcessFunction fcall = this;
        return new AsyncMethodCallback<String>() { 
          public void onComplete(String o) {
            addUNICOREJobSubmissionDetails_result result = new addUNICOREJobSubmissionDetails_result();
            result.success = o;
            try {
              fcall.sendResponse(fb,result, org.apache.thrift.protocol.TMessageType.REPLY,seqid);
              return;
            } catch (Exception e) {
              LOGGER.error("Exception writing to internal frame buffer", e);
            }
            fb.close();
          }
          public void onError(Exception e) {
            byte msgType = org.apache.thrift.protocol.TMessageType.REPLY;
            org.apache.thrift.TBase msg;
            addUNICOREJobSubmissionDetails_result result = new addUNICOREJobSubmissionDetails_result();
            if (e instanceof org.apache.airavata.model.error.InvalidRequestException) {
                        result.ire = (org.apache.airavata.model.error.InvalidRequestException) e;
                        result.setIreIsSet(true);
                        msg = result;
            }
            else             if (e instanceof org.apache.airavata.model.error.AiravataClientException) {
                        result.ace = (org.apache.airavata.model.error.AiravataClientException) e;
                        result.setAceIsSet(true);
                        msg = result;
            }
            else             if (e instanceof org.apache.airavata.model.error.AiravataSystemException) {
                        result.ase = (org.apache.airavata.model.error.AiravataSystemException) e;
                        result.setAseIsSet(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 
            {
              msgType = org.apache.thrift.protocol.TMessageType.EXCEPTION;
              msg = (org.apache.thrift.TBase)new org.apache.thrift.TApplicationException(org.apache.thrift.TApplicationException.INTERNAL_ERROR, e.getMessage());
            }
            try {
              fcall.sendResponse(fb,msg,msgType,seqid);
              return;
            } catch (Exception ex) {
              LOGGER.error("Exception writing to internal frame buffer", ex);
            }
            fb.close();
          }
        };
      }

      protected boolean isOneway() {
        return false;
      }

      public void start(I iface, addUNICOREJobSubmissionDetails_args args, org.apache.thrift.async.AsyncMethodCallback<String> resultHandler) throws TException {
        iface.addUNICOREJobSubmissionDetails(args.authzToken, args.computeResourceId, args.priorityOrder, args.unicoreJobSubmission,resultHandler);
      }
    }

    public static class getUnicoreJobSubmission<I extends AsyncIface> extends org.apache.thrift.AsyncProcessFunction<I, getUnicoreJobSubmission_args, org.apache.airavata.model.appcatalog.computeresource.UnicoreJobSubmission> {
      public getUnicoreJobSubmission() {
        super("getUnicoreJobSubmission");
      }

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

      public AsyncMethodCallback<org.apache.airavata.model.appcatalog.computeresource.UnicoreJobSubmission> getResultHandler(final AsyncFrameBuffer fb, final int seqid) {
        final org.apache.thrift.AsyncProcessFunction fcall = this;
        return new AsyncMethodCallback<org.apache.airavata.model.appcatalog.computeresource.UnicoreJobSubmission>() { 
          public void onComplete(org.apache.airavata.model.appcatalog.computeresource.UnicoreJobSubmission o) {
            getUnicoreJobSubmission_result result = new getUnicoreJobSubmission_result();
            result.success = o;
            try {
              fcall.sendResponse(fb,result, org.apache.thrift.protocol.TMessageType.REPLY,seqid);
              return;
            } catch (Exception e) {
              LOGGER.error("Exception writing to internal frame buffer", e);
            }
            fb.close();
          }
          public void onError(Exception e) {
            byte msgType = org.apache.thrift.protocol.TMessageType.REPLY;
            org.apache.thrift.TBase msg;
            getUnicoreJobSubmission_result result = new getUnicoreJobSubmission_result();
            if (e instanceof org.apache.airavata.model.error.InvalidRequestException) {
                        result.ire = (org.apache.airavata.model.error.InvalidRequestException) e;
                        result.setIreIsSet(true);
                        msg = result;
            }
            else             if (e instanceof org.apache.airavata.model.error.AiravataClientException) {
                        result.ace = (org.apache.airavata.model.error.AiravataClientException) e;
                        result.setAceIsSet(true);
                        msg = result;
            }
            else             if (e instanceof org.apache.airavata.model.error.AiravataSystemException) {
                        result.ase = (org.apache.airavata.model.error.AiravataSystemException) e;
                        result.setAseIsSet(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 
            {
              msgType = org.apache.thrift.protocol.TMessageType.EXCEPTION;
              msg = (org.apache.thrift.TBase)new org.apache.thrift.TApplicationException(org.apache.thrift.TApplicationException.INTERNAL_ERROR, e.getMessage());
            }
            try {
              fcall.sendResponse(fb,msg,msgType,seqid);
              return;
            } catch (Exception ex) {
              LOGGER.error("Exception writing to internal frame buffer", ex);
            }
            fb.close();
          }
        };
      }

      protected boolean isOneway() {
        return false;
      }

      public void start(I iface, getUnicoreJobSubmission_args args, org.apache.thrift.async.AsyncMethodCallback<org.apache.airavata.model.appcatalog.computeresource.UnicoreJobSubmission> resultHandler) throws TException {
        iface.getUnicoreJobSubmission(args.authzToken, args.jobSubmissionId,resultHandler);
      }
    }

    public static class addCloudJobSubmissionDetails<I extends AsyncIface> extends org.apache.thrift.AsyncProcessFunction<I, addCloudJobSubmissionDetails_args, String> {
      public addCloudJobSubmissionDetails() {
        super("addCloudJobSubmissionDetails");
      }

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

      public AsyncMethodCallback<String> getResultHandler(final AsyncFrameBuffer fb, final int seqid) {
        final org.apache.thrift.AsyncProcessFunction fcall = this;
        return new AsyncMethodCallback<String>() { 
          public void onComplete(String o) {
            addCloudJobSubmissionDetails_result result = new addCloudJobSubmissionDetails_result();
            result.success = o;
            try {
              fcall.sendResponse(fb,result, org.apache.thrift.protocol.TMessageType.REPLY,seqid);
              return;
            } catch (Exception e) {
              LOGGER.error("Exception writing to internal frame buffer", e);
            }
            fb.close();
          }
          public void onError(Exception e) {
            byte msgType = org.apache.thrift.protocol.TMessageType.REPLY;
            org.apache.thrift.TBase msg;
            addCloudJobSubmissionDetails_result result = new addCloudJobSubmissionDetails_result();
            if (e instanceof org.apache.airavata.model.error.InvalidRequestException) {
                        result.ire = (org.apache.airavata.model.error.InvalidRequestException) e;
                        result.setIreIsSet(true);
                        msg = result;
            }
            else             if (e instanceof org.apache.airavata.model.error.AiravataClientException) {
                        result.ace = (org.apache.airavata.model.error.AiravataClientException) e;
                        result.setAceIsSet(true);
                        msg = result;
            }
            else             if (e instanceof org.apache.airavata.model.error.AiravataSystemException) {
                        result.ase = (org.apache.airavata.model.error.AiravataSystemException) e;
                        result.setAseIsSet(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 
            {
              msgType = org.apache.thrift.protocol.TMessageType.EXCEPTION;
              msg = (org.apache.thrift.TBase)new org.apache.thrift.TApplicationException(org.apache.thrift.TApplicationException.INTERNAL_ERROR, e.getMessage());
            }
            try {
              fcall.sendResponse(fb,msg,msgType,seqid);
              return;
            } catch (Exception ex) {
              LOGGER.error("Exception writing to internal frame buffer", ex);
            }
            fb.close();
          }
        };
      }

      protected boolean isOneway() {
        return false;
      }

      public void start(I iface, addCloudJobSubmissionDetails_args args, org.apache.thrift.async.AsyncMethodCallback<String> resultHandler) throws TException {
        iface.addCloudJobSubmissionDetails(args.authzToken, args.computeResourceId, args.priorityOrder, args.cloudSubmission,resultHandler);
      }
    }

    public static class getCloudJobSubmission<I extends AsyncIface> extends org.apache.thrift.AsyncProcessFunction<I, getCloudJobSubmission_args, org.apache.airavata.model.appcatalog.computeresource.CloudJobSubmission> {
      public getCloudJobSubmission() {
        super("getCloudJobSubmission");
      }

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

      public AsyncMethodCallback<org.apache.airavata.model.appcatalog.computeresource.CloudJobSubmission> getResultHandler(final AsyncFrameBuffer fb, final int seqid) {
        final org.apache.thrift.AsyncProcessFunction fcall = this;
        return new AsyncMethodCallback<org.apache.airavata.model.appcatalog.computeresource.CloudJobSubmission>() { 
          public void onComplete(org.apache.airavata.model.appcatalog.computeresource.CloudJobSubmission o) {
            getCloudJobSubmission_result result = new getCloudJobSubmission_result();
            result.success = o;
            try {
              fcall.sendResponse(fb,result, org.apache.thrift.protocol.TMessageType.REPLY,seqid);
              return;
            } catch (Exception e) {
              LOGGER.error("Exception writing to internal frame buffer", e);
            }
            fb.close();
          }
          public void onError(Exception e) {
            byte msgType = org.apache.thrift.protocol.TMessageType.REPLY;
            org.apache.thrift.TBase msg;
            getCloudJobSubmission_result result = new getCloudJobSubmission_result();
            if (e instanceof org.apache.airavata.model.error.InvalidRequestException) {
                        result.ire = (org.apache.airavata.model.error.InvalidRequestException) e;
                        result.setIreIsSet(true);
                        msg = result;
            }
            else             if (e instanceof org.apache.airavata.model.error.AiravataClientException) {
                        result.ace = (org.apache.airavata.model.error.AiravataClientException) e;
                        result.setAceIsSet(true);
                        msg = result;
            }
            else             if (e instanceof org.apache.airavata.model.error.AiravataSystemException) {
                        result.ase = (org.apache.airavata.model.error.AiravataSystemException) e;
                        result.setAseIsSet(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 
            {
              msgType = org.apache.thrift.protocol.TMessageType.EXCEPTION;
              msg = (org.apache.thrift.TBase)new org.apache.thrift.TApplicationException(org.apache.thrift.TApplicationException.INTERNAL_ERROR, e.getMessage());
            }
            try {
              fcall.sendResponse(fb,msg,msgType,seqid);
              return;
            } catch (Exception ex) {
              LOGGER.error("Exception writing to internal frame buffer", ex);
            }
            fb.close();
          }
        };
      }

      protected boolean isOneway() {
        return false;
      }

      public void start(I iface, getCloudJobSubmission_args args, org.apache.thrift.async.AsyncMethodCallback<org.apache.airavata.model.appcatalog.computeresource.CloudJobSubmission> resultHandler) throws TException {
        iface.getCloudJobSubmission(args.authzToken, args.jobSubmissionId,resultHandler);
      }
    }

    public static class updateSSHJobSubmissionDetails<I extends AsyncIface> extends org.apache.thrift.AsyncProcessFunction<I, updateSSHJobSubmissionDetails_args, Boolean> {
      public updateSSHJobSubmissionDetails() {
        super("updateSSHJobSubmissionDetails");
      }

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

      public AsyncMethodCallback<Boolean> getResultHandler(final AsyncFrameBuffer fb, final int seqid) {
        final org.apache.thrift.AsyncProcessFunction fcall = this;
        return new AsyncMethodCallback<Boolean>() { 
          public void onComplete(Boolean o) {
            updateSSHJobSubmissionDetails_result result = new updateSSHJobSubmissionDetails_result();
            result.success = o;
            result.setSuccessIsSet(true);
            try {
              fcall.sendResponse(fb,result, org.apache.thrift.protocol.TMessageType.REPLY,seqid);
              return;
            } catch (Exception e) {
              LOGGER.error("Exception writing to internal frame buffer", e);
            }
            fb.close();
          }
          public void onError(Exception e) {
            byte msgType = org.apache.thrift.protocol.TMessageType.REPLY;
            org.apache.thrift.TBase msg;
            updateSSHJobSubmissionDetails_result result = new updateSSHJobSubmissionDetails_result();
            if (e instanceof org.apache.airavata.model.error.InvalidRequestException) {
                        result.ire = (org.apache.airavata.model.error.InvalidRequestException) e;
                        result.setIreIsSet(true);
                        msg = result;
            }
            else             if (e instanceof org.apache.airavata.model.error.AiravataClientException) {
                        result.ace = (org.apache.airavata.model.error.AiravataClientException) e;
                        result.setAceIsSet(true);
                        msg = result;
            }
            else             if (e instanceof org.apache.airavata.model.error.AiravataSystemException) {
                        result.ase = (org.apache.airavata.model.error.AiravataSystemException) e;
                        result.setAseIsSet(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 
            {
              msgType = org.apache.thrift.protocol.TMessageType.EXCEPTION;
              msg = (org.apache.thrift.TBase)new org.apache.thrift.TApplicationException(org.apache.thrift.TApplicationException.INTERNAL_ERROR, e.getMessage());
            }
            try {
              fcall.sendResponse(fb,msg,msgType,seqid);
              return;
            } catch (Exception ex) {
              LOGGER.error("Exception writing to internal frame buffer", ex);
            }
            fb.close();
          }
        };
      }

      protected boolean isOneway() {
        return false;
      }

      public void start(I iface, updateSSHJobSubmissionDetails_args args, org.apache.thrift.async.AsyncMethodCallback<Boolean> resultHandler) throws TException {
        iface.updateSSHJobSubmissionDetails(args.authzToken, args.jobSubmissionInterfaceId, args.sshJobSubmission,resultHandler);
      }
    }

    public static class updateCloudJobSubmissionDetails<I extends AsyncIface> extends org.apache.thrift.AsyncProcessFunction<I, updateCloudJobSubmissionDetails_args, Boolean> {
      public updateCloudJobSubmissionDetails() {
        super("updateCloudJobSubmissionDetails");
      }

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

      public AsyncMethodCallback<Boolean> getResultHandler(final AsyncFrameBuffer fb, final int seqid) {
        final org.apache.thrift.AsyncProcessFunction fcall = this;
        return new AsyncMethodCallback<Boolean>() { 
          public void onComplete(Boolean o) {
            updateCloudJobSubmissionDetails_result result = new updateCloudJobSubmissionDetails_result();
            result.success = o;
            result.setSuccessIsSet(true);
            try {
              fcall.sendResponse(fb,result, org.apache.thrift.protocol.TMessageType.REPLY,seqid);
              return;
            } catch (Exception e) {
              LOGGER.error("Exception writing to internal frame buffer", e);
            }
            fb.close();
          }
          public void onError(Exception e) {
            byte msgType = org.apache.thrift.protocol.TMessageType.REPLY;
            org.apache.thrift.TBase msg;
            updateCloudJobSubmissionDetails_result result = new updateCloudJobSubmissionDetails_result();
            if (e instanceof org.apache.airavata.model.error.InvalidRequestException) {
                        result.ire = (org.apache.airavata.model.error.InvalidRequestException) e;
                        result.setIreIsSet(true);
                        msg = result;
            }
            else             if (e instanceof org.apache.airavata.model.error.AiravataClientException) {
                        result.ace = (org.apache.airavata.model.error.AiravataClientException) e;
                        result.setAceIsSet(true);
                        msg = result;
            }
            else             if (e instanceof org.apache.airavata.model.error.AiravataSystemException) {
                        result.ase = (org.apache.airavata.model.error.AiravataSystemException) e;
                        result.setAseIsSet(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 
            {
              msgType = org.apache.thrift.protocol.TMessageType.EXCEPTION;
              msg = (org.apache.thrift.TBase)new org.apache.thrift.TApplicationException(org.apache.thrift.TApplicationException.INTERNAL_ERROR, e.getMessage());
            }
            try {
              fcall.sendResponse(fb,msg,msgType,seqid);
              return;
            } catch (Exception ex) {
              LOGGER.error("Exception writing to internal frame buffer", ex);
            }
            fb.close();
          }
        };
      }

      protected boolean isOneway() {
        return false;
      }

      public void start(I iface, updateCloudJobSubmissionDetails_args args, org.apache.thrift.async.AsyncMethodCallback<Boolean> resultHandler) throws TException {
        iface.updateCloudJobSubmissionDetails(args.authzToken, args.jobSubmissionInterfaceId, args.sshJobSubmission,resultHandler);
      }
    }

    public static class updateUnicoreJobSubmissionDetails<I extends AsyncIface> extends org.apache.thrift.AsyncProcessFunction<I, updateUnicoreJobSubmissionDetails_args, Boolean> {
      public updateUnicoreJobSubmissionDetails() {
        super("updateUnicoreJobSubmissionDetails");
      }

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

      public AsyncMethodCallback<Boolean> getResultHandler(final AsyncFrameBuffer fb, final int seqid) {
        final org.apache.thrift.AsyncProcessFunction fcall = this;
        return new AsyncMethodCallback<Boolean>() { 
          public void onComplete(Boolean o) {
            updateUnicoreJobSubmissionDetails_result result = new updateUnicoreJobSubmissionDetails_result();
            result.success = o;
            result.setSuccessIsSet(true);
            try {
              fcall.sendResponse(fb,result, org.apache.thrift.protocol.TMessageType.REPLY,seqid);
              return;
            } catch (Exception e) {
              LOGGER.error("Exception writing to internal frame buffer", e);
            }
            fb.close();
          }
          public void onError(Exception e) {
            byte msgType = org.apache.thrift.protocol.TMessageType.REPLY;
            org.apache.thrift.TBase msg;
            updateUnicoreJobSubmissionDetails_result result = new updateUnicoreJobSubmissionDetails_result();
            if (e instanceof org.apache.airavata.model.error.InvalidRequestException) {
                        result.ire = (org.apache.airavata.model.error.InvalidRequestException) e;
                        result.setIreIsSet(true);
                        msg = result;
            }
            else             if (e instanceof org.apache.airavata.model.error.AiravataClientException) {
                        result.ace = (org.apache.airavata.model.error.AiravataClientException) e;
                        result.setAceIsSet(true);
                        msg = result;
            }
            else             if (e instanceof org.apache.airavata.model.error.AiravataSystemException) {
                        result.ase = (org.apache.airavata.model.error.AiravataSystemException) e;
                        result.setAseIsSet(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 
            {
              msgType = org.apache.thrift.protocol.TMessageType.EXCEPTION;
              msg = (org.apache.thrift.TBase)new org.apache.thrift.TApplicationException(org.apache.thrift.TApplicationException.INTERNAL_ERROR, e.getMessage());
            }
            try {
              fcall.sendResponse(fb,msg,msgType,seqid);
              return;
            } catch (Exception ex) {
              LOGGER.error("Exception writing to internal frame buffer", ex);
            }
            fb.close();
          }
        };
      }

      protected boolean isOneway() {
        return false;
      }

      public void start(I iface, updateUnicoreJobSubmissionDetails_args args, org.apache.thrift.async.AsyncMethodCallback<Boolean> resultHandler) throws TException {
        iface.updateUnicoreJobSubmissionDetails(args.authzToken, args.jobSubmissionInterfaceId, args.unicoreJobSubmission,resultHandler);
      }
    }

    public static class addLocalDataMovementDetails<I extends AsyncIface> extends org.apache.thrift.AsyncProcessFunction<I, addLocalDataMovementDetails_args, String> {
      public addLocalDataMovementDetails() {
        super("addLocalDataMovementDetails");
      }

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

      public AsyncMethodCallback<String> getResultHandler(final AsyncFrameBuffer fb, final int seqid) {
        final org.apache.thrift.AsyncProcessFunction fcall = this;
        return new AsyncMethodCallback<String>() { 
          public void onComplete(String o) {
            addLocalDataMovementDetails_result result = new addLocalDataMovementDetails_result();
            result.success = o;
            try {
              fcall.sendResponse(fb,result, org.apache.thrift.protocol.TMessageType.REPLY,seqid);
              return;
            } catch (Exception e) {
              LOGGER.error("Exception writing to internal frame buffer", e);
            }
            fb.close();
          }
          public void onError(Exception e) {
            byte msgType = org.apache.thrift.protocol.TMessageType.REPLY;
            org.apache.thrift.TBase msg;
            addLocalDataMovementDetails_result result = new addLocalDataMovementDetails_result();
            if (e instanceof org.apache.airavata.model.error.InvalidRequestException) {
                        result.ire = (org.apache.airavata.model.error.InvalidRequestException) e;
                        result.setIreIsSet(true);
                        msg = result;
            }
            else             if (e instanceof org.apache.airavata.model.error.AiravataClientException) {
                        result.ace = (org.apache.airavata.model.error.AiravataClientException) e;
                        result.setAceIsSet(true);
                        msg = result;
            }
            else             if (e instanceof org.apache.airavata.model.error.AiravataSystemException) {
                        result.ase = (org.apache.airavata.model.error.AiravataSystemException) e;
                        result.setAseIsSet(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 
            {
              msgType = org.apache.thrift.protocol.TMessageType.EXCEPTION;
              msg = (org.apache.thrift.TBase)new org.apache.thrift.TApplicationException(org.apache.thrift.TApplicationException.INTERNAL_ERROR, e.getMessage());
            }
            try {
              fcall.sendResponse(fb,msg,msgType,seqid);
              return;
            } catch (Exception ex) {
              LOGGER.error("Exception writing to internal frame buffer", ex);
            }
            fb.close();
          }
        };
      }

      protected boolean isOneway() {
        return false;
      }

      public void start(I iface, addLocalDataMovementDetails_args args, org.apache.thrift.async.AsyncMethodCallback<String> resultHandler) throws TException {
        iface.addLocalDataMovementDetails(args.authzToken, args.computeResourceId, args.priorityOrder, args.localDataMovement,resultHandler);
      }
    }

    public static class updateLocalDataMovementDetails<I extends AsyncIface> extends org.apache.thrift.AsyncProcessFunction<I, updateLocalDataMovementDetails_args, Boolean> {
      public updateLocalDataMovementDetails() {
        super("updateLocalDataMovementDetails");
      }

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

      public AsyncMethodCallback<Boolean> getResultHandler(final AsyncFrameBuffer fb, final int seqid) {
        final org.apache.thrift.AsyncProcessFunction fcall = this;
        return new AsyncMethodCallback<Boolean>() { 
          public void onComplete(Boolean o) {
            updateLocalDataMovementDetails_result result = new updateLocalDataMovementDetails_result();
            result.success = o;
            result.setSuccessIsSet(true);
            try {
              fcall.sendResponse(fb,result, org.apache.thrift.protocol.TMessageType.REPLY,seqid);
              return;
            } catch (Exception e) {
              LOGGER.error("Exception writing to internal frame buffer", e);
            }
            fb.close();
          }
          public void onError(Exception e) {
            byte msgType = org.apache.thrift.protocol.TMessageType.REPLY;
            org.apache.thrift.TBase msg;
            updateLocalDataMovementDetails_result result = new updateLocalDataMovementDetails_result();
            if (e instanceof org.apache.airavata.model.error.InvalidRequestException) {
                        result.ire = (org.apache.airavata.model.error.InvalidRequestException) e;
                        result.setIreIsSet(true);
                        msg = result;
            }
            else             if (e instanceof org.apache.airavata.model.error.AiravataClientException) {
                        result.ace = (org.apache.airavata.model.error.AiravataClientException) e;
                        result.setAceIsSet(true);
                        msg = result;
            }
            else             if (e instanceof org.apache.airavata.model.error.AiravataSystemException) {
                        result.ase = (org.apache.airavata.model.error.AiravataSystemException) e;
                        result.setAseIsSet(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 
            {
              msgType = org.apache.thrift.protocol.TMessageType.EXCEPTION;
              msg = (org.apache.thrift.TBase)new org.apache.thrift.TApplicationException(org.apache.thrift.TApplicationException.INTERNAL_ERROR, e.getMessage());
            }
            try {
              fcall.sendResponse(fb,msg,msgType,seqid);
              return;
            } catch (Exception ex) {
              LOGGER.error("Exception writing to internal frame buffer", ex);
            }
            fb.close();
          }
        };
      }

      protected boolean isOneway() {
        return false;
      }

      public void start(I iface, updateLocalDataMovementDetails_args args, org.apache.thrift.async.AsyncMethodCallback<Boolean> resultHandler) throws TException {
        iface.updateLocalDataMovementDetails(args.authzToken, args.dataMovementInterfaceId, args.localDataMovement,resultHandler);
      }
    }

    public static class getLocalDataMovement<I extends AsyncIface> extends org.apache.thrift.AsyncProcessFunction<I, getLocalDataMovement_args, org.apache.airavata.model.appcatalog.computeresource.LOCALDataMovement> {
      public getLocalDataMovement() {
        super("getLocalDataMovement");
      }

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

      public AsyncMethodCallback<org.apache.airavata.model.appcatalog.computeresource.LOCALDataMovement> getResultHandler(final AsyncFrameBuffer fb, final int seqid) {
        final org.apache.thrift.AsyncProcessFunction fcall = this;
        return new AsyncMethodCallback<org.apache.airavata.model.appcatalog.computeresource.LOCALDataMovement>() { 
          public void onComplete(org.apache.airavata.model.appcatalog.computeresource.LOCALDataMovement o) {
            getLocalDataMovement_result result = new getLocalDataMovement_result();
            result.success = o;
            try {
              fcall.sendResponse(fb,result, org.apache.thrift.protocol.TMessageType.REPLY,seqid);
              return;
            } catch (Exception e) {
              LOGGER.error("Exception writing to internal frame buffer", e);
            }
            fb.close();
          }
          public void onError(Exception e) {
            byte msgType = org.apache.thrift.protocol.TMessageType.REPLY;
            org.apache.thrift.TBase msg;
            getLocalDataMovement_result result = new getLocalDataMovement_result();
            if (e instanceof org.apache.airavata.model.error.InvalidRequestException) {
                        result.ire = (org.apache.airavata.model.error.InvalidRequestException) e;
                        result.setIreIsSet(true);
                        msg = result;
            }
            else             if (e instanceof org.apache.airavata.model.error.AiravataClientException) {
                        result.ace = (org.apache.airavata.model.error.AiravataClientException) e;
                        result.setAceIsSet(true);
                        msg = result;
            }
            else             if (e instanceof org.apache.airavata.model.error.AiravataSystemException) {
                        result.ase = (org.apache.airavata.model.error.AiravataSystemException) e;
                        result.setAseIsSet(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 
            {
              msgType = org.apache.thrift.protocol.TMessageType.EXCEPTION;
              msg = (org.apache.thrift.TBase)new org.apache.thrift.TApplicationException(org.apache.thrift.TApplicationException.INTERNAL_ERROR, e.getMessage());
            }
            try {
              fcall.sendResponse(fb,msg,msgType,seqid);
              return;
            } catch (Exception ex) {
              LOGGER.error("Exception writing to internal frame buffer", ex);
            }
            fb.close();
          }
        };
      }

      protected boolean isOneway() {
        return false;
      }

      public void start(I iface, getLocalDataMovement_args args, org.apache.thrift.async.AsyncMethodCallback<org.apache.airavata.model.appcatalog.computeresource.LOCALDataMovement> resultHandler) throws TException {
        iface.getLocalDataMovement(args.authzToken, args.dataMovementId,resultHandler);
      }
    }

    public static class addSCPDataMovementDetails<I extends AsyncIface> extends org.apache.thrift.AsyncProcessFunction<I, addSCPDataMovementDetails_args, String> {
      public addSCPDataMovementDetails() {
        super("addSCPDataMovementDetails");
      }

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

      public AsyncMethodCallback<String> getResultHandler(final AsyncFrameBuffer fb, final int seqid) {
        final org.apache.thrift.AsyncProcessFunction fcall = this;
        return new AsyncMethodCallback<String>() { 
          public void onComplete(String o) {
            addSCPDataMovementDetails_result result = new addSCPDataMovementDetails_result();
            result.success = o;
            try {
              fcall.sendResponse(fb,result, org.apache.thrift.protocol.TMessageType.REPLY,seqid);
              return;
            } catch (Exception e) {
              LOGGER.error("Exception writing to internal frame buffer", e);
            }
            fb.close();
          }
          public void onError(Exception e) {
            byte msgType = org.apache.thrift.protocol.TMessageType.REPLY;
            org.apache.thrift.TBase msg;
            addSCPDataMovementDetails_result result = new addSCPDataMovementDetails_result();
            if (e instanceof org.apache.airavata.model.error.InvalidRequestException) {
                        result.ire = (org.apache.airavata.model.error.InvalidRequestException) e;
                        result.setIreIsSet(true);
                        msg = result;
            }
            else             if (e instanceof org.apache.airavata.model.error.AiravataClientException) {
                        result.ace = (org.apache.airavata.model.error.AiravataClientException) e;
                        result.setAceIsSet(true);
                        msg = result;
            }
            else             if (e instanceof org.apache.airavata.model.error.AiravataSystemException) {
                        result.ase = (org.apache.airavata.model.error.AiravataSystemException) e;
                        result.setAseIsSet(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 
            {
              msgType = org.apache.thrift.protocol.TMessageType.EXCEPTION;
              msg = (org.apache.thrift.TBase)new org.apache.thrift.TApplicationException(org.apache.thrift.TApplicationException.INTERNAL_ERROR, e.getMessage());
            }
            try {
              fcall.sendResponse(fb,msg,msgType,seqid);
              return;
            } catch (Exception ex) {
              LOGGER.error("Exception writing to internal frame buffer", ex);
            }
            fb.close();
          }
        };
      }

      protected boolean isOneway() {
        return false;
      }

      public void start(I iface, addSCPDataMovementDetails_args args, org.apache.thrift.async.AsyncMethodCallback<String> resultHandler) throws TException {
        iface.addSCPDataMovementDetails(args.authzToken, args.computeResourceId, args.priorityOrder, args.scpDataMovement,resultHandler);
      }
    }

    public static class updateSCPDataMovementDetails<I extends AsyncIface> extends org.apache.thrift.AsyncProcessFunction<I, updateSCPDataMovementDetails_args, Boolean> {
      public updateSCPDataMovementDetails() {
        super("updateSCPDataMovementDetails");
      }

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

      public AsyncMethodCallback<Boolean> getResultHandler(final AsyncFrameBuffer fb, final int seqid) {
        final org.apache.thrift.AsyncProcessFunction fcall = this;
        return new AsyncMethodCallback<Boolean>() { 
          public void onComplete(Boolean o) {
            updateSCPDataMovementDetails_result result = new updateSCPDataMovementDetails_result();
            result.success = o;
            result.setSuccessIsSet(true);
            try {
              fcall.sendResponse(fb,result, org.apache.thrift.protocol.TMessageType.REPLY,seqid);
              return;
            } catch (Exception e) {
              LOGGER.error("Exception writing to internal frame buffer", e);
            }
            fb.close();
          }
          public void onError(Exception e) {
            byte msgType = org.apache.thrift.protocol.TMessageType.REPLY;
            org.apache.thrift.TBase msg;
            updateSCPDataMovementDetails_result result = new updateSCPDataMovementDetails_result();
            if (e instanceof org.apache.airavata.model.error.InvalidRequestException) {
                        result.ire = (org.apache.airavata.model.error.InvalidRequestException) e;
                        result.setIreIsSet(true);
                        msg = result;
            }
            else             if (e instanceof org.apache.airavata.model.error.AiravataClientException) {
                        result.ace = (org.apache.airavata.model.error.AiravataClientException) e;
                        result.setAceIsSet(true);
                        msg = result;
            }
            else             if (e instanceof org.apache.airavata.model.error.AiravataSystemException) {
                        result.ase = (org.apache.airavata.model.error.AiravataSystemException) e;
                        result.setAseIsSet(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 
            {
              msgType = org.apache.thrift.protocol.TMessageType.EXCEPTION;
              msg = (org.apache.thrift.TBase)new org.apache.thrift.TApplicationException(org.apache.thrift.TApplicationException.INTERNAL_ERROR, e.getMessage());
            }
            try {
              fcall.sendResponse(fb,msg,msgType,seqid);
              return;
            } catch (Exception ex) {
              LOGGER.error("Exception writing to internal frame buffer", ex);
            }
            fb.close();
          }
        };
      }

      protected boolean isOneway() {
        return false;
      }

      public void start(I iface, updateSCPDataMovementDetails_args args, org.apache.thrift.async.AsyncMethodCallback<Boolean> resultHandler) throws TException {
        iface.updateSCPDataMovementDetails(args.authzToken, args.dataMovementInterfaceId, args.scpDataMovement,resultHandler);
      }
    }

    public static class getSCPDataMovement<I extends AsyncIface> extends org.apache.thrift.AsyncProcessFunction<I, getSCPDataMovement_args, org.apache.airavata.model.appcatalog.computeresource.SCPDataMovement> {
      public getSCPDataMovement() {
        super("getSCPDataMovement");
      }

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

      public AsyncMethodCallback<org.apache.airavata.model.appcatalog.computeresource.SCPDataMovement> getResultHandler(final AsyncFrameBuffer fb, final int seqid) {
        final org.apache.thrift.AsyncProcessFunction fcall = this;
        return new AsyncMethodCallback<org.apache.airavata.model.appcatalog.computeresource.SCPDataMovement>() { 
          public void onComplete(org.apache.airavata.model.appcatalog.computeresource.SCPDataMovement o) {
            getSCPDataMovement_result result = new getSCPDataMovement_result();
            result.success = o;
            try {
              fcall.sendResponse(fb,result, org.apache.thrift.protocol.TMessageType.REPLY,seqid);
              return;
            } catch (Exception e) {
              LOGGER.error("Exception writing to internal frame buffer", e);
            }
            fb.close();
          }
          public void onError(Exception e) {
            byte msgType = org.apache.thrift.protocol.TMessageType.REPLY;
            org.apache.thrift.TBase msg;
            getSCPDataMovement_result result = new getSCPDataMovement_result();
            if (e instanceof org.apache.airavata.model.error.InvalidRequestException) {
                        result.ire = (org.apache.airavata.model.error.InvalidRequestException) e;
                        result.setIreIsSet(true);
                        msg = result;
            }
            else             if (e instanceof org.apache.airavata.model.error.AiravataClientException) {
                        result.ace = (org.apache.airavata.model.error.AiravataClientException) e;
                        result.setAceIsSet(true);
                        msg = result;
            }
            else             if (e instanceof org.apache.airavata.model.error.AiravataSystemException) {
                        result.ase = (org.apache.airavata.model.error.AiravataSystemException) e;
                        result.setAseIsSet(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 
            {
              msgType = org.apache.thrift.protocol.TMessageType.EXCEPTION;
              msg = (org.apache.thrift.TBase)new org.apache.thrift.TApplicationException(org.apache.thrift.TApplicationException.INTERNAL_ERROR, e.getMessage());
            }
            try {
              fcall.sendResponse(fb,msg,msgType,seqid);
              return;
            } catch (Exception ex) {
              LOGGER.error("Exception writing to internal frame buffer", ex);
            }
            fb.close();
          }
        };
      }

      protected boolean isOneway() {
        return false;
      }

      public void start(I iface, getSCPDataMovement_args args, org.apache.thrift.async.AsyncMethodCallback<org.apache.airavata.model.appcatalog.computeresource.SCPDataMovement> resultHandler) throws TException {
        iface.getSCPDataMovement(args.authzToken, args.dataMovementId,resultHandler);
      }
    }

    public static class addUnicoreDataMovementDetails<I extends AsyncIface> extends org.apache.thrift.AsyncProcessFunction<I, addUnicoreDataMovementDetails_args, String> {
      public addUnicoreDataMovementDetails() {
        super("addUnicoreDataMovementDetails");
      }

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

      public AsyncMethodCallback<String> getResultHandler(final AsyncFrameBuffer fb, final int seqid) {
        final org.apache.thrift.AsyncProcessFunction fcall = this;
        return new AsyncMethodCallback<String>() { 
          public void onComplete(String o) {
            addUnicoreDataMovementDetails_result result = new addUnicoreDataMovementDetails_result();
            result.success = o;
            try {
              fcall.sendResponse(fb,result, org.apache.thrift.protocol.TMessageType.REPLY,seqid);
              return;
            } catch (Exception e) {
              LOGGER.error("Exception writing to internal frame buffer", e);
            }
            fb.close();
          }
          public void onError(Exception e) {
            byte msgType = org.apache.thrift.protocol.TMessageType.REPLY;
            org.apache.thrift.TBase msg;
            addUnicoreDataMovementDetails_result result = new addUnicoreDataMovementDetails_result();
            if (e instanceof org.apache.airavata.model.error.InvalidRequestException) {
                        result.ire = (org.apache.airavata.model.error.InvalidRequestException) e;
                        result.setIreIsSet(true);
                        msg = result;
            }
            else             if (e instanceof org.apache.airavata.model.error.AiravataClientException) {
                        result.ace = (org.apache.airavata.model.error.AiravataClientException) e;
                        result.setAceIsSet(true);
                        msg = result;
            }
            else             if (e instanceof org.apache.airavata.model.error.AiravataSystemException) {
                        result.ase = (org.apache.airavata.model.error.AiravataSystemException) e;
                        result.setAseIsSet(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 
            {
              msgType = org.apache.thrift.protocol.TMessageType.EXCEPTION;
              msg = (org.apache.thrift.TBase)new org.apache.thrift.TApplicationException(org.apache.thrift.TApplicationException.INTERNAL_ERROR, e.getMessage());
            }
            try {
              fcall.sendResponse(fb,msg,msgType,seqid);
              return;
            } catch (Exception ex) {
              LOGGER.error("Exception writing to internal frame buffer", ex);
            }
            fb.close();
          }
        };
      }

      protected boolean isOneway() {
        return false;
      }

      public void start(I iface, addUnicoreDataMovementDetails_args args, org.apache.thrift.async.AsyncMethodCallback<String> resultHandler) throws TException {
        iface.addUnicoreDataMovementDetails(args.authzToken, args.computeResourceId, args.priorityOrder, args.unicoreDataMovement,resultHandler);
      }
    }

    public static class updateUnicoreDataMovementDetails<I extends AsyncIface> extends org.apache.thrift.AsyncProcessFunction<I, updateUnicoreDataMovementDetails_args, Boolean> {
      public updateUnicoreDataMovementDetails() {
        super("updateUnicoreDataMovementDetails");
      }

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

      public AsyncMethodCallback<Boolean> getResultHandler(final AsyncFrameBuffer fb, final int seqid) {
        final org.apache.thrift.AsyncProcessFunction fcall = this;
        return new AsyncMethodCallback<Boolean>() { 
          public void onComplete(Boolean o) {
            updateUnicoreDataMovementDetails_result result = new updateUnicoreDataMovementDetails_result();
            result.success = o;
            result.setSuccessIsSet(true);
            try {
              fcall.sendResponse(fb,result, org.apache.thrift.protocol.TMessageType.REPLY,seqid);
              return;
            } catch (Exception e) {
              LOGGER.error("Exception writing to internal frame buffer", e);
            }
            fb.close();
          }
          public void onError(Exception e) {
            byte msgType = org.apache.thrift.protocol.TMessageType.REPLY;
            org.apache.thrift.TBase msg;
            updateUnicoreDataMovementDetails_result result = new updateUnicoreDataMovementDetails_result();
            if (e instanceof org.apache.airavata.model.error.InvalidRequestException) {
                        result.ire = (org.apache.airavata.model.error.InvalidRequestException) e;
                        result.setIreIsSet(true);
                        msg = result;
            }
            else             if (e instanceof org.apache.airavata.model.error.AiravataClientException) {
                        result.ace = (org.apache.airavata.model.error.AiravataClientException) e;
                        result.setAceIsSet(true);
                        msg = result;
            }
            else             if (e instanceof org.apache.airavata.model.error.AiravataSystemException) {
                        result.ase = (org.apache.airavata.model.error.AiravataSystemException) e;
                        result.setAseIsSet(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 
            {
              msgType = org.apache.thrift.protocol.TMessageType.EXCEPTION;
              msg = (org.apache.thrift.TBase)new org.apache.thrift.TApplicationException(org.apache.thrift.TApplicationException.INTERNAL_ERROR, e.getMessage());
            }
            try {
              fcall.sendResponse(fb,msg,msgType,seqid);
              return;
            } catch (Exception ex) {
              LOGGER.error("Exception writing to internal frame buffer", ex);
            }
            fb.close();
          }
        };
      }

      protected boolean isOneway() {
        return false;
      }

      public void start(I iface, updateUnicoreDataMovementDetails_args args, org.apache.thrift.async.AsyncMethodCallback<Boolean> resultHandler) throws TException {
        iface.updateUnicoreDataMovementDetails(args.authzToken, args.dataMovementInterfaceId, args.unicoreDataMovement,resultHandler);
      }
    }

    public static class getUnicoreDataMovement<I extends AsyncIface> extends org.apache.thrift.AsyncProcessFunction<I, getUnicoreDataMovement_args, org.apache.airavata.model.appcatalog.computeresource.UnicoreDataMovement> {
      public getUnicoreDataMovement() {
        super("getUnicoreDataMovement");
      }

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

      public AsyncMethodCallback<org.apache.airavata.model.appcatalog.computeresource.UnicoreDataMovement> getResultHandler(final AsyncFrameBuffer fb, final int seqid) {
        final org.apache.thrift.AsyncProcessFunction fcall = this;
        return new AsyncMethodCallback<org.apache.airavata.model.appcatalog.computeresource.UnicoreDataMovement>() { 
          public void onComplete(org.apache.airavata.model.appcatalog.computeresource.UnicoreDataMovement o) {
            getUnicoreDataMovement_result result = new getUnicoreDataMovement_result();
            result.success = o;
            try {
              fcall.sendResponse(fb,result, org.apache.thrift.protocol.TMessageType.REPLY,seqid);
              return;
            } catch (Exception e) {
              LOGGER.error("Exception writing to internal frame buffer", e);
            }
            fb.close();
          }
          public void onError(Exception e) {
            byte msgType = org.apache.thrift.protocol.TMessageType.REPLY;
            org.apache.thrift.TBase msg;
            getUnicoreDataMovement_result result = new getUnicoreDataMovement_result();
            if (e instanceof org.apache.airavata.model.error.InvalidRequestException) {
                        result.ire = (org.apache.airavata.model.error.InvalidRequestException) e;
                        result.setIreIsSet(true);
                        msg = result;
            }
            else             if (e instanceof org.apache.airavata.model.error.AiravataClientException) {
                        result.ace = (org.apache.airavata.model.error.AiravataClientException) e;
                        result.setAceIsSet(true);
                        msg = result;
            }
            else             if (e instanceof org.apache.airavata.model.error.AiravataSystemException) {
                        result.ase = (org.apache.airavata.model.error.AiravataSystemException) e;
                        result.setAseIsSet(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 
            {
              msgType = org.apache.thrift.protocol.TMessageType.EXCEPTION;
              msg = (org.apache.thrift.TBase)new org.apache.thrift.TApplicationException(org.apache.thrift.TApplicationException.INTERNAL_ERROR, e.getMessage());
            }
            try {
              fcall.sendResponse(fb,msg,msgType,seqid);
              return;
            } catch (Exception ex) {
              LOGGER.error("Exception writing to internal frame buffer", ex);
            }
            fb.close();
          }
        };
      }

      protected boolean isOneway() {
        return false;
      }

      public void start(I iface, getUnicoreDataMovement_args args, org.apache.thrift.async.AsyncMethodCallback<org.apache.airavata.model.appcatalog.computeresource.UnicoreDataMovement> resultHandler) throws TException {
        iface.getUnicoreDataMovement(args.authzToken, args.dataMovementId,resultHandler);
      }
    }

    public static class addGridFTPDataMovementDetails<I extends AsyncIface> extends org.apache.thrift.AsyncProcessFunction<I, addGridFTPDataMovementDetails_args, String> {
      public addGridFTPDataMovementDetails() {
        super("addGridFTPDataMovementDetails");
      }

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

      public AsyncMethodCallback<String> getResultHandler(final AsyncFrameBuffer fb, final int seqid) {
        final org.apache.thrift.AsyncProcessFunction fcall = this;
        return new AsyncMethodCallback<String>() { 
          public void onComplete(String o) {
            addGridFTPDataMovementDetails_result result = new addGridFTPDataMovementDetails_result();
            result.success = o;
            try {
              fcall.sendResponse(fb,result, org.apache.thrift.protocol.TMessageType.REPLY,seqid);
              return;
            } catch (Exception e) {
              LOGGER.error("Exception writing to internal frame buffer", e);
            }
            fb.close();
          }
          public void onError(Exception e) {
            byte msgType = org.apache.thrift.protocol.TMessageType.REPLY;
            org.apache.thrift.TBase msg;
            addGridFTPDataMovementDetails_result result = new addGridFTPDataMovementDetails_result();
            if (e instanceof org.apache.airavata.model.error.InvalidRequestException) {
                        result.ire = (org.apache.airavata.model.error.InvalidRequestException) e;
                        result.setIreIsSet(true);
                        msg = result;
            }
            else             if (e instanceof org.apache.airavata.model.error.AiravataClientException) {
                        result.ace = (org.apache.airavata.model.error.AiravataClientException) e;
                        result.setAceIsSet(true);
                        msg = result;
            }
            else             if (e instanceof org.apache.airavata.model.error.AiravataSystemException) {
                        result.ase = (org.apache.airavata.model.error.AiravataSystemException) e;
                        result.setAseIsSet(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 
            {
              msgType = org.apache.thrift.protocol.TMessageType.EXCEPTION;
              msg = (org.apache.thrift.TBase)new org.apache.thrift.TApplicationException(org.apache.thrift.TApplicationException.INTERNAL_ERROR, e.getMessage());
            }
            try {
              fcall.sendResponse(fb,msg,msgType,seqid);
              return;
            } catch (Exception ex) {
              LOGGER.error("Exception writing to internal frame buffer", ex);
            }
            fb.close();
          }
        };
      }

      protected boolean isOneway() {
        return false;
      }

      public void start(I iface, addGridFTPDataMovementDetails_args args, org.apache.thrift.async.AsyncMethodCallback<String> resultHandler) throws TException {
        iface.addGridFTPDataMovementDetails(args.authzToken, args.computeResourceId, args.priorityOrder, args.gridFTPDataMovement,resultHandler);
      }
    }

    public static class updateGridFTPDataMovementDetails<I extends AsyncIface> extends org.apache.thrift.AsyncProcessFunction<I, updateGridFTPDataMovementDetails_args, Boolean> {
      public updateGridFTPDataMovementDetails() {
        super("updateGridFTPDataMovementDetails");
      }

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

      public AsyncMethodCallback<Boolean> getResultHandler(final AsyncFrameBuffer fb, final int seqid) {
        final org.apache.thrift.AsyncProcessFunction fcall = this;
        return new AsyncMethodCallback<Boolean>() { 
          public void onComplete(Boolean o) {
            updateGridFTPDataMovementDetails_result result = new updateGridFTPDataMovementDetails_result();
            result.success = o;
            result.setSuccessIsSet(true);
            try {
              fcall.sendResponse(fb,result, org.apache.thrift.protocol.TMessageType.REPLY,seqid);
              return;
            } catch (Exception e) {
              LOGGER.error("Exception writing to internal frame buffer", e);
            }
            fb.close();
          }
          public void onError(Exception e) {
            byte msgType = org.apache.thrift.protocol.TMessageType.REPLY;
            org.apache.thrift.TBase msg;
            updateGridFTPDataMovementDetails_result result = new updateGridFTPDataMovementDetails_result();
            if (e instanceof org.apache.airavata.model.error.InvalidRequestException) {
                        result.ire = (org.apache.airavata.model.error.InvalidRequestException) e;
                        result.setIreIsSet(true);
                        msg = result;
            }
            else             if (e instanceof org.apache.airavata.model.error.AiravataClientException) {
                        result.ace = (org.apache.airavata.model.error.AiravataClientException) e;
                        result.setAceIsSet(true);
                        msg = result;
            }
            else             if (e instanceof org.apache.airavata.model.error.AiravataSystemException) {
                        result.ase = (org.apache.airavata.model.error.AiravataSystemException) e;
                        result.setAseIsSet(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 
            {
              msgType = org.apache.thrift.protocol.TMessageType.EXCEPTION;
              msg = (org.apache.thrift.TBase)new org.apache.thrift.TApplicationException(org.apache.thrift.TApplicationException.INTERNAL_ERROR, e.getMessage());
            }
            try {
              fcall.sendResponse(fb,msg,msgType,seqid);
              return;
            } catch (Exception ex) {
              LOGGER.error("Exception writing to internal frame buffer", ex);
            }
            fb.close();
          }
        };
      }

      protected boolean isOneway() {
        return false;
      }

      public void start(I iface, updateGridFTPDataMovementDetails_args args, org.apache.thrift.async.AsyncMethodCallback<Boolean> resultHandler) throws TException {
        iface.updateGridFTPDataMovementDetails(args.authzToken, args.dataMovementInterfaceId, args.gridFTPDataMovement,resultHandler);
      }
    }

    public static class getGridFTPDataMovement<I extends AsyncIface> extends org.apache.thrift.AsyncProcessFunction<I, getGridFTPDataMovement_args, org.apache.airavata.model.appcatalog.computeresource.GridFTPDataMovement> {
      public getGridFTPDataMovement() {
        super("getGridFTPDataMovement");
      }

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

      public AsyncMethodCallback<org.apache.airavata.model.appcatalog.computeresource.GridFTPDataMovement> getResultHandler(final AsyncFrameBuffer fb, final int seqid) {
        final org.apache.thrift.AsyncProcessFunction fcall = this;
        return new AsyncMethodCallback<org.apache.airavata.model.appcatalog.computeresource.GridFTPDataMovement>() { 
          public void onComplete(org.apache.airavata.model.appcatalog.computeresource.GridFTPDataMovement o) {
            getGridFTPDataMovement_result result = new getGridFTPDataMovement_result();
            result.success = o;
            try {
              fcall.sendResponse(fb,result, org.apache.thrift.protocol.TMessageType.REPLY,seqid);
              return;
            } catch (Exception e) {
              LOGGER.error("Exception writing to internal frame buffer", e);
            }
            fb.close();
          }
          public void onError(Exception e) {
            byte msgType = org.apache.thrift.protocol.TMessageType.REPLY;
            org.apache.thrift.TBase msg;
            getGridFTPDataMovement_result result = new getGridFTPDataMovement_result();
            if (e instanceof org.apache.airavata.model.error.InvalidRequestException) {
                        result.ire = (org.apache.airavata.model.error.InvalidRequestException) e;
                        result.setIreIsSet(true);
                        msg = result;
            }
            else             if (e instanceof org.apache.airavata.model.error.AiravataClientException) {
                        result.ace = (org.apache.airavata.model.error.AiravataClientException) e;
                        result.setAceIsSet(true);
                        msg = result;
            }
            else             if (e instanceof org.apache.airavata.model.error.AiravataSystemException) {
                        result.ase = (org.apache.airavata.model.error.AiravataSystemException) e;
                        result.setAseIsSet(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 
            {
              msgType = org.apache.thrift.protocol.TMessageType.EXCEPTION;
              msg = (org.apache.thrift.TBase)new org.apache.thrift.TApplicationException(org.apache.thrift.TApplicationException.INTERNAL_ERROR, e.getMessage());
            }
            try {
              fcall.sendResponse(fb,msg,msgType,seqid);
              return;
            } catch (Exception ex) {
              LOGGER.error("Exception writing to internal frame buffer", ex);
            }
            fb.close();
          }
        };
      }

      protected boolean isOneway() {
        return false;
      }

      public void start(I iface, getGridFTPDataMovement_args args, org.apache.thrift.async.AsyncMethodCallback<org.apache.airavata.model.appcatalog.computeresource.GridFTPDataMovement> resultHandler) throws TException {
        iface.getGridFTPDataMovement(args.authzToken, args.dataMovementId,resultHandler);
      }
    }

    public static class changeJobSubmissionPriority<I extends AsyncIface> extends org.apache.thrift.AsyncProcessFunction<I, changeJobSubmissionPriority_args, Boolean> {
      public changeJobSubmissionPriority() {
        super("changeJobSubmissionPriority");
      }

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

      public AsyncMethodCallback<Boolean> getResultHandler(final AsyncFrameBuffer fb, final int seqid) {
        final org.apache.thrift.AsyncProcessFunction fcall = this;
        return new AsyncMethodCallback<Boolean>() { 
          public void onComplete(Boolean o) {
            changeJobSubmissionPriority_result result = new changeJobSubmissionPriority_result();
            result.success = o;
            result.setSuccessIsSet(true);
            try {
              fcall.sendResponse(fb,result, org.apache.thrift.protocol.TMessageType.REPLY,seqid);
              return;
            } catch (Exception e) {
              LOGGER.error("Exception writing to internal frame buffer", e);
            }
            fb.close();
          }
          public void onError(Exception e) {
            byte msgType = org.apache.thrift.protocol.TMessageType.REPLY;
            org.apache.thrift.TBase msg;
            changeJobSubmissionPriority_result result = new changeJobSubmissionPriority_result();
            if (e instanceof org.apache.airavata.model.error.InvalidRequestException) {
                        result.ire = (org.apache.airavata.model.error.InvalidRequestException) e;
                        result.setIreIsSet(true);
                        msg = result;
            }
            else             if (e instanceof org.apache.airavata.model.error.AiravataClientException) {
                        result.ace = (org.apache.airavata.model.error.AiravataClientException) e;
                        result.setAceIsSet(true);
                        msg = result;
            }
            else             if (e instanceof org.apache.airavata.model.error.AiravataSystemException) {
                        result.ase = (org.apache.airavata.model.error.AiravataSystemException) e;
                        result.setAseIsSet(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 
            {
              msgType = org.apache.thrift.protocol.TMessageType.EXCEPTION;
              msg = (org.apache.thrift.TBase)new org.apache.thrift.TApplicationException(org.apache.thrift.TApplicationException.INTERNAL_ERROR, e.getMessage());
            }
            try {
              fcall.sendResponse(fb,msg,msgType,seqid);
              return;
            } catch (Exception ex) {
              LOGGER.error("Exception writing to internal frame buffer", ex);
            }
            fb.close();
          }
        };
      }

      protected boolean isOneway() {
        return false;
      }

      public void start(I iface, changeJobSubmissionPriority_args args, org.apache.thrift.async.AsyncMethodCallback<Boolean> resultHandler) throws TException {
        iface.changeJobSubmissionPriority(args.authzToken, args.jobSubmissionInterfaceId, args.newPriorityOrder,resultHandler);
      }
    }

    public static class changeDataMovementPriority<I extends AsyncIface> extends org.apache.thrift.AsyncProcessFunction<I, changeDataMovementPriority_args, Boolean> {
      public changeDataMovementPriority() {
        super("changeDataMovementPriority");
      }

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

      public AsyncMethodCallback<Boolean> getResultHandler(final AsyncFrameBuffer fb, final int seqid) {
        final org.apache.thrift.AsyncProcessFunction fcall = this;
        return new AsyncMethodCallback<Boolean>() { 
          public void onComplete(Boolean o) {
            changeDataMovementPriority_result result = new changeDataMovementPriority_result();
            result.success = o;
            result.setSuccessIsSet(true);
            try {
              fcall.sendResponse(fb,result, org.apache.thrift.protocol.TMessageType.REPLY,seqid);
              return;
            } catch (Exception e) {
              LOGGER.error("Exception writing to internal frame buffer", e);
            }
            fb.close();
          }
          public void onError(Exception e) {
            byte msgType = org.apache.thrift.protocol.TMessageType.REPLY;
            org.apache.thrift.TBase msg;
            changeDataMovementPriority_result result = new changeDataMovementPriority_result();
            if (e instanceof org.apache.airavata.model.error.InvalidRequestException) {
                        result.ire = (org.apache.airavata.model.error.InvalidRequestException) e;
                        result.setIreIsSet(true);
                        msg = result;
            }
            else             if (e instanceof org.apache.airavata.model.error.AiravataClientException) {
                        result.ace = (org.apache.airavata.model.error.AiravataClientException) e;
                        result.setAceIsSet(true);
                        msg = result;
            }
            else             if (e instanceof org.apache.airavata.model.error.AiravataSystemException) {
                        result.ase = (org.apache.airavata.model.error.AiravataSystemException) e;
                        result.setAseIsSet(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 
            {
              msgType = org.apache.thrift.protocol.TMessageType.EXCEPTION;
              msg = (org.apache.thrift.TBase)new org.apache.thrift.TApplicationException(org.apache.thrift.TApplicationException.INTERNAL_ERROR, e.getMessage());
            }
            try {
              fcall.sendResponse(fb,msg,msgType,seqid);
              return;
            } catch (Exception ex) {
              LOGGER.error("Exception writing to internal frame buffer", ex);
            }
            fb.close();
          }
        };
      }

      protected boolean isOneway() {
        return false;
      }

      public void start(I iface, changeDataMovementPriority_args args, org.apache.thrift.async.AsyncMethodCallback<Boolean> resultHandler) throws TException {
        iface.changeDataMovementPriority(args.authzToken, args.dataMovementInterfaceId, args.newPriorityOrder,resultHandler);
      }
    }

    public static class changeJobSubmissionPriorities<I extends AsyncIface> extends org.apache.thrift.AsyncProcessFunction<I, changeJobSubmissionPriorities_args, Boolean> {
      public changeJobSubmissionPriorities() {
        super("changeJobSubmissionPriorities");
      }

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

      public AsyncMethodCallback<Boolean> getResultHandler(final AsyncFrameBuffer fb, final int seqid) {
        final org.apache.thrift.AsyncProcessFunction fcall = this;
        return new AsyncMethodCallback<Boolean>() { 
          public void onComplete(Boolean o) {
            changeJobSubmissionPriorities_result result = new changeJobSubmissionPriorities_result();
            result.success = o;
            result.setSuccessIsSet(true);
            try {
              fcall.sendResponse(fb,result, org.apache.thrift.protocol.TMessageType.REPLY,seqid);
              return;
            } catch (Exception e) {
              LOGGER.error("Exception writing to internal frame buffer", e);
            }
            fb.close();
          }
          public void onError(Exception e) {
            byte msgType = org.apache.thrift.protocol.TMessageType.REPLY;
            org.apache.thrift.TBase msg;
            changeJobSubmissionPriorities_result result = new changeJobSubmissionPriorities_result();
            if (e instanceof org.apache.airavata.model.error.InvalidRequestException) {
                        result.ire = (org.apache.airavata.model.error.InvalidRequestException) e;
                        result.setIreIsSet(true);
                        msg = result;
            }
            else             if (e instanceof org.apache.airavata.model.error.AiravataClientException) {
                        result.ace = (org.apache.airavata.model.error.AiravataClientException) e;
                        result.setAceIsSet(true);
                        msg = result;
            }
            else             if (e instanceof org.apache.airavata.model.error.AiravataSystemException) {
                        result.ase = (org.apache.airavata.model.error.AiravataSystemException) e;
                        result.setAseIsSet(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 
            {
              msgType = org.apache.thrift.protocol.TMessageType.EXCEPTION;
              msg = (org.apache.thrift.TBase)new org.apache.thrift.TApplicationException(org.apache.thrift.TApplicationException.INTERNAL_ERROR, e.getMessage());
            }
            try {
              fcall.sendResponse(fb,msg,msgType,seqid);
              return;
            } catch (Exception ex) {
              LOGGER.error("Exception writing to internal frame buffer", ex);
            }
            fb.close();
          }
        };
      }

      protected boolean isOneway() {
        return false;
      }

      public void start(I iface, changeJobSubmissionPriorities_args args, org.apache.thrift.async.AsyncMethodCallback<Boolean> resultHandler) throws TException {
        iface.changeJobSubmissionPriorities(args.authzToken, args.jobSubmissionPriorityMap,resultHandler);
      }
    }

    public static class changeDataMovementPriorities<I extends AsyncIface> extends org.apache.thrift.AsyncProcessFunction<I, changeDataMovementPriorities_args, Boolean> {
      public changeDataMovementPriorities() {
        super("changeDataMovementPriorities");
      }

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

      public AsyncMethodCallback<Boolean> getResultHandler(final AsyncFrameBuffer fb, final int seqid) {
        final org.apache.thrift.AsyncProcessFunction fcall = this;
        return new AsyncMethodCallback<Boolean>() { 
          public void onComplete(Boolean o) {
            changeDataMovementPriorities_result result = new changeDataMovementPriorities_result();
            result.success = o;
            result.setSuccessIsSet(true);
            try {
              fcall.sendResponse(fb,result, org.apache.thrift.protocol.TMessageType.REPLY,seqid);
              return;
            } catch (Exception e) {
              LOGGER.error("Exception writing to internal frame buffer", e);
            }
            fb.close();
          }
          public void onError(Exception e) {
            byte msgType = org.apache.thrift.protocol.TMessageType.REPLY;
            org.apache.thrift.TBase msg;
            changeDataMovementPriorities_result result = new changeDataMovementPriorities_result();
            if (e instanceof org.apache.airavata.model.error.InvalidRequestException) {
                        result.ire = (org.apache.airavata.model.error.InvalidRequestException) e;
                        result.setIreIsSet(true);
                        msg = result;
            }
            else             if (e instanceof org.apache.airavata.model.error.AiravataClientException) {
                        result.ace = (org.apache.airavata.model.error.AiravataClientException) e;
                        result.setAceIsSet(true);
                        msg = result;
            }
            else             if (e instanceof org.apache.airavata.model.error.AiravataSystemException) {
                        result.ase = (org.apache.airavata.model.error.AiravataSystemException) e;
                        result.setAseIsSet(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 
            {
              msgType = org.apache.thrift.protocol.TMessageType.EXCEPTION;
              msg = (org.apache.thrift.TBase)new org.apache.thrift.TApplicationException(org.apache.thrift.TApplicationException.INTERNAL_ERROR, e.getMessage());
            }
            try {
              fcall.sendResponse(fb,msg,msgType,seqid);
              return;
            } catch (Exception ex) {
              LOGGER.error("Exception writing to internal frame buffer", ex);
            }
            fb.close();
          }
        };
      }

      protected boolean isOneway() {
        return false;
      }

      public void start(I iface, changeDataMovementPriorities_args args, org.apache.thrift.async.AsyncMethodCallback<Boolean> resultHandler) throws TException {
        iface.changeDataMovementPriorities(args.authzToken, args.dataMovementPriorityMap,resultHandler);
      }
    }

    public static class deleteJobSubmissionInterface<I extends AsyncIface> extends org.apache.thrift.AsyncProcessFunction<I, deleteJobSubmissionInterface_args, Boolean> {
      public deleteJobSubmissionInterface() {
        super("deleteJobSubmissionInterface");
      }

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

      public AsyncMethodCallback<Boolean> getResultHandler(final AsyncFrameBuffer fb, final int seqid) {
        final org.apache.thrift.AsyncProcessFunction fcall = this;
        return new AsyncMethodCallback<Boolean>() { 
          public void onComplete(Boolean o) {
            deleteJobSubmissionInterface_result result = new deleteJobSubmissionInterface_result();
            result.success = o;
            result.setSuccessIsSet(true);
            try {
              fcall.sendResponse(fb,result, org.apache.thrift.protocol.TMessageType.REPLY,seqid);
              return;
            } catch (Exception e) {
              LOGGER.error("Exception writing to internal frame buffer", e);
            }
            fb.close();
          }
          public void onError(Exception e) {
            byte msgType = org.apache.thrift.protocol.TMessageType.REPLY;
            org.apache.thrift.TBase msg;
            deleteJobSubmissionInterface_result result = new deleteJobSubmissionInterface_result();
            if (e instanceof org.apache.airavata.model.error.InvalidRequestException) {
                        result.ire = (org.apache.airavata.model.error.InvalidRequestException) e;
                        result.setIreIsSet(true);
                        msg = result;
            }
            else             if (e instanceof org.apache.airavata.model.error.AiravataClientException) {
                        result.ace = (org.apache.airavata.model.error.AiravataClientException) e;
                        result.setAceIsSet(true);
                        msg = result;
            }
            else             if (e instanceof org.apache.airavata.model.error.AiravataSystemException) {
                        result.ase = (org.apache.airavata.model.error.AiravataSystemException) e;
                        result.setAseIsSet(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 
            {
              msgType = org.apache.thrift.protocol.TMessageType.EXCEPTION;
              msg = (org.apache.thrift.TBase)new org.apache.thrift.TApplicationException(org.apache.thrift.TApplicationException.INTERNAL_ERROR, e.getMessage());
            }
            try {
              fcall.sendResponse(fb,msg,msgType,seqid);
              return;
            } catch (Exception ex) {
              LOGGER.error("Exception writing to internal frame buffer", ex);
            }
            fb.close();
          }
        };
      }

      protected boolean isOneway() {
        return false;
      }

      public void start(I iface, deleteJobSubmissionInterface_args args, org.apache.thrift.async.AsyncMethodCallback<Boolean> resultHandler) throws TException {
        iface.deleteJobSubmissionInterface(args.authzToken, args.computeResourceId, args.jobSubmissionInterfaceId,resultHandler);
      }
    }

    public static class deleteDataMovementInterface<I extends AsyncIface> extends org.apache.thrift.AsyncProcessFunction<I, deleteDataMovementInterface_args, Boolean> {
      public deleteDataMovementInterface() {
        super("deleteDataMovementInterface");
      }

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

      public AsyncMethodCallback<Boolean> getResultHandler(final AsyncFrameBuffer fb, final int seqid) {
        final org.apache.thrift.AsyncProcessFunction fcall = this;
        return new AsyncMethodCallback<Boolean>() { 
          public void onComplete(Boolean o) {
            deleteDataMovementInterface_result result = new deleteDataMovementInterface_result();
            result.success = o;
            result.setSuccessIsSet(true);
            try {
              fcall.sendResponse(fb,result, org.apache.thrift.protocol.TMessageType.REPLY,seqid);
              return;
            } catch (Exception e) {
              LOGGER.error("Exception writing to internal frame buffer", e);
            }
            fb.close();
          }
          public void onError(Exception e) {
            byte msgType = org.apache.thrift.protocol.TMessageType.REPLY;
            org.apache.thrift.TBase msg;
            deleteDataMovementInterface_result result = new deleteDataMovementInterface_result();
            if (e instanceof org.apache.airavata.model.error.InvalidRequestException) {
                        result.ire = (org.apache.airavata.model.error.InvalidRequestException) e;
                        result.setIreIsSet(true);
                        msg = result;
            }
            else             if (e instanceof org.apache.airavata.model.error.AiravataClientException) {
                        result.ace = (org.apache.airavata.model.error.AiravataClientException) e;
                        result.setAceIsSet(true);
                        msg = result;
            }
            else             if (e instanceof org.apache.airavata.model.error.AiravataSystemException) {
                        result.ase = (org.apache.airavata.model.error.AiravataSystemException) e;
                        result.setAseIsSet(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 
            {
              msgType = org.apache.thrift.protocol.TMessageType.EXCEPTION;
              msg = (org.apache.thrift.TBase)new org.apache.thrift.TApplicationException(org.apache.thrift.TApplicationException.INTERNAL_ERROR, e.getMessage());
            }
            try {
              fcall.sendResponse(fb,msg,msgType,seqid);
              return;
            } catch (Exception ex) {
              LOGGER.error("Exception writing to internal frame buffer", ex);
            }
            fb.close();
          }
        };
      }

      protected boolean isOneway() {
        return false;
      }

      public void start(I iface, deleteDataMovementInterface_args args, org.apache.thrift.async.AsyncMethodCallback<Boolean> resultHandler) throws TException {
        iface.deleteDataMovementInterface(args.authzToken, args.computeResourceId, args.dataMovementInterfaceId,resultHandler);
      }
    }

    public static class registerResourceJobManager<I extends AsyncIface> extends org.apache.thrift.AsyncProcessFunction<I, registerResourceJobManager_args, String> {
      public registerResourceJobManager() {
        super("registerResourceJobManager");
      }

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

      public AsyncMethodCallback<String> getResultHandler(final AsyncFrameBuffer fb, final int seqid) {
        final org.apache.thrift.AsyncProcessFunction fcall = this;
        return new AsyncMethodCallback<String>() { 
          public void onComplete(String o) {
            registerResourceJobManager_result result = new registerResourceJobManager_result();
            result.success = o;
            try {
              fcall.sendResponse(fb,result, org.apache.thrift.protocol.TMessageType.REPLY,seqid);
              return;
            } catch (Exception e) {
              LOGGER.error("Exception writing to internal frame buffer", e);
            }
            fb.close();
          }
          public void onError(Exception e) {
            byte msgType = org.apache.thrift.protocol.TMessageType.REPLY;
            org.apache.thrift.TBase msg;
            registerResourceJobManager_result result = new registerResourceJobManager_result();
            if (e instanceof org.apache.airavata.model.error.InvalidRequestException) {
                        result.ire = (org.apache.airavata.model.error.InvalidRequestException) e;
                        result.setIreIsSet(true);
                        msg = result;
            }
            else             if (e instanceof org.apache.airavata.model.error.AiravataClientException) {
                        result.ace = (org.apache.airavata.model.error.AiravataClientException) e;
                        result.setAceIsSet(true);
                        msg = result;
            }
            else             if (e instanceof org.apache.airavata.model.error.AiravataSystemException) {
                        result.ase = (org.apache.airavata.model.error.AiravataSystemException) e;
                        result.setAseIsSet(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 
            {
              msgType = org.apache.thrift.protocol.TMessageType.EXCEPTION;
              msg = (org.apache.thrift.TBase)new org.apache.thrift.TApplicationException(org.apache.thrift.TApplicationException.INTERNAL_ERROR, e.getMessage());
            }
            try {
              fcall.sendResponse(fb,msg,msgType,seqid);
              return;
            } catch (Exception ex) {
              LOGGER.error("Exception writing to internal frame buffer", ex);
            }
            fb.close();
          }
        };
      }

      protected boolean isOneway() {
        return false;
      }

      public void start(I iface, registerResourceJobManager_args args, org.apache.thrift.async.AsyncMethodCallback<String> resultHandler) throws TException {
        iface.registerResourceJobManager(args.authzToken, args.resourceJobManager,resultHandler);
      }
    }

    public static class updateResourceJobManager<I extends AsyncIface> extends org.apache.thrift.AsyncProcessFunction<I, updateResourceJobManager_args, Boolean> {
      public updateResourceJobManager() {
        super("updateResourceJobManager");
      }

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

      public AsyncMethodCallback<Boolean> getResultHandler(final AsyncFrameBuffer fb, final int seqid) {
        final org.apache.thrift.AsyncProcessFunction fcall = this;
        return new AsyncMethodCallback<Boolean>() { 
          public void onComplete(Boolean o) {
            updateResourceJobManager_result result = new updateResourceJobManager_result();
            result.success = o;
            result.setSuccessIsSet(true);
            try {
              fcall.sendResponse(fb,result, org.apache.thrift.protocol.TMessageType.REPLY,seqid);
              return;
            } catch (Exception e) {
              LOGGER.error("Exception writing to internal frame buffer", e);
            }
            fb.close();
          }
          public void onError(Exception e) {
            byte msgType = org.apache.thrift.protocol.TMessageType.REPLY;
            org.apache.thrift.TBase msg;
            updateResourceJobManager_result result = new updateResourceJobManager_result();
            if (e instanceof org.apache.airavata.model.error.InvalidRequestException) {
                        result.ire = (org.apache.airavata.model.error.InvalidRequestException) e;
                        result.setIreIsSet(true);
                        msg = result;
            }
            else             if (e instanceof org.apache.airavata.model.error.AiravataClientException) {
                        result.ace = (org.apache.airavata.model.error.AiravataClientException) e;
                        result.setAceIsSet(true);
                        msg = result;
            }
            else             if (e instanceof org.apache.airavata.model.error.AiravataSystemException) {
                        result.ase = (org.apache.airavata.model.error.AiravataSystemException) e;
                        result.setAseIsSet(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 
            {
              msgType = org.apache.thrift.protocol.TMessageType.EXCEPTION;
              msg = (org.apache.thrift.TBase)new org.apache.thrift.TApplicationException(org.apache.thrift.TApplicationException.INTERNAL_ERROR, e.getMessage());
            }
            try {
              fcall.sendResponse(fb,msg,msgType,seqid);
              return;
            } catch (Exception ex) {
              LOGGER.error("Exception writing to internal frame buffer", ex);
            }
            fb.close();
          }
        };
      }

      protected boolean isOneway() {
        return false;
      }

      public void start(I iface, updateResourceJobManager_args args, org.apache.thrift.async.AsyncMethodCallback<Boolean> resultHandler) throws TException {
        iface.updateResourceJobManager(args.authzToken, args.resourceJobManagerId, args.updatedResourceJobManager,resultHandler);
      }
    }

    public static class getResourceJobManager<I extends AsyncIface> extends org.apache.thrift.AsyncProcessFunction<I, getResourceJobManager_args, org.apache.airavata.model.appcatalog.computeresource.ResourceJobManager> {
      public getResourceJobManager() {
        super("getResourceJobManager");
      }

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

      public AsyncMethodCallback<org.apache.airavata.model.appcatalog.computeresource.ResourceJobManager> getResultHandler(final AsyncFrameBuffer fb, final int seqid) {
        final org.apache.thrift.AsyncProcessFunction fcall = this;
        return new AsyncMethodCallback<org.apache.airavata.model.appcatalog.computeresource.ResourceJobManager>() { 
          public void onComplete(org.apache.airavata.model.appcatalog.computeresource.ResourceJobManager o) {
            getResourceJobManager_result result = new getResourceJobManager_result();
            result.success = o;
            try {
              fcall.sendResponse(fb,result, org.apache.thrift.protocol.TMessageType.REPLY,seqid);
              return;
            } catch (Exception e) {
              LOGGER.error("Exception writing to internal frame buffer", e);
            }
            fb.close();
          }
          public void onError(Exception e) {
            byte msgType = org.apache.thrift.protocol.TMessageType.REPLY;
            org.apache.thrift.TBase msg;
            getResourceJobManager_result result = new getResourceJobManager_result();
            if (e instanceof org.apache.airavata.model.error.InvalidRequestException) {
                        result.ire = (org.apache.airavata.model.error.InvalidRequestException) e;
                        result.setIreIsSet(true);
                        msg = result;
            }
            else             if (e instanceof org.apache.airavata.model.error.AiravataClientException) {
                        result.ace = (org.apache.airavata.model.error.AiravataClientException) e;
                        result.setAceIsSet(true);
                        msg = result;
            }
            else             if (e instanceof org.apache.airavata.model.error.AiravataSystemException) {
                        result.ase = (org.apache.airavata.model.error.AiravataSystemException) e;
                        result.setAseIsSet(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 
            {
              msgType = org.apache.thrift.protocol.TMessageType.EXCEPTION;
              msg = (org.apache.thrift.TBase)new org.apache.thrift.TApplicationException(org.apache.thrift.TApplicationException.INTERNAL_ERROR, e.getMessage());
            }
            try {
              fcall.sendResponse(fb,msg,msgType,seqid);
              return;
            } catch (Exception ex) {
              LOGGER.error("Exception writing to internal frame buffer", ex);
            }
            fb.close();
          }
        };
      }

      protected boolean isOneway() {
        return false;
      }

      public void start(I iface, getResourceJobManager_args args, org.apache.thrift.async.AsyncMethodCallback<org.apache.airavata.model.appcatalog.computeresource.ResourceJobManager> resultHandler) throws TException {
        iface.getResourceJobManager(args.authzToken, args.resourceJobManagerId,resultHandler);
      }
    }

    public static class deleteResourceJobManager<I extends AsyncIface> extends org.apache.thrift.AsyncProcessFunction<I, deleteResourceJobManager_args, Boolean> {
      public deleteResourceJobManager() {
        super("deleteResourceJobManager");
      }

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

      public AsyncMethodCallback<Boolean> getResultHandler(final AsyncFrameBuffer fb, final int seqid) {
        final org.apache.thrift.AsyncProcessFunction fcall = this;
        return new AsyncMethodCallback<Boolean>() { 
          public void onComplete(Boolean o) {
            deleteResourceJobManager_result result = new deleteResourceJobManager_result();
            result.success = o;
            result.setSuccessIsSet(true);
            try {
              fcall.sendResponse(fb,result, org.apache.thrift.protocol.TMessageType.REPLY,seqid);
              return;
            } catch (Exception e) {
              LOGGER.error("Exception writing to internal frame buffer", e);
            }
            fb.close();
          }
          public void onError(Exception e) {
            byte msgType = org.apache.thrift.protocol.TMessageType.REPLY;
            org.apache.thrift.TBase msg;
            deleteResourceJobManager_result result = new deleteResourceJobManager_result();
            if (e instanceof org.apache.airavata.model.error.InvalidRequestException) {
                        result.ire = (org.apache.airavata.model.error.InvalidRequestException) e;
                        result.setIreIsSet(true);
                        msg = result;
            }
            else             if (e instanceof org.apache.airavata.model.error.AiravataClientException) {
                        result.ace = (org.apache.airavata.model.error.AiravataClientException) e;
                        result.setAceIsSet(true);
                        msg = result;
            }
            else             if (e instanceof org.apache.airavata.model.error.AiravataSystemException) {
                        result.ase = (org.apache.airavata.model.error.AiravataSystemException) e;
                        result.setAseIsSet(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 
            {
              msgType = org.apache.thrift.protocol.TMessageType.EXCEPTION;
              msg = (org.apache.thrift.TBase)new org.apache.thrift.TApplicationException(org.apache.thrift.TApplicationException.INTERNAL_ERROR, e.getMessage());
            }
            try {
              fcall.sendResponse(fb,msg,msgType,seqid);
              return;
            } catch (Exception ex) {
              LOGGER.error("Exception writing to internal frame buffer", ex);
            }
            fb.close();
          }
        };
      }

      protected boolean isOneway() {
        return false;
      }

      public void start(I iface, deleteResourceJobManager_args args, org.apache.thrift.async.AsyncMethodCallback<Boolean> resultHandler) throws TException {
        iface.deleteResourceJobManager(args.authzToken, args.resourceJobManagerId,resultHandler);
      }
    }

    public static class deleteBatchQueue<I extends AsyncIface> extends org.apache.thrift.AsyncProcessFunction<I, deleteBatchQueue_args, Boolean> {
      public deleteBatchQueue() {
        super("deleteBatchQueue");
      }

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

      public AsyncMethodCallback<Boolean> getResultHandler(final AsyncFrameBuffer fb, final int seqid) {
        final org.apache.thrift.AsyncProcessFunction fcall = this;
        return new AsyncMethodCallback<Boolean>() { 
          public void onComplete(Boolean o) {
            deleteBatchQueue_result result = new deleteBatchQueue_result();
            result.success = o;
            result.setSuccessIsSet(true);
            try {
              fcall.sendResponse(fb,result, org.apache.thrift.protocol.TMessageType.REPLY,seqid);
              return;
            } catch (Exception e) {
              LOGGER.error("Exception writing to internal frame buffer", e);
            }
            fb.close();
          }
          public void onError(Exception e) {
            byte msgType = org.apache.thrift.protocol.TMessageType.REPLY;
            org.apache.thrift.TBase msg;
            deleteBatchQueue_result result = new deleteBatchQueue_result();
            if (e instanceof org.apache.airavata.model.error.InvalidRequestException) {
                        result.ire = (org.apache.airavata.model.error.InvalidRequestException) e;
                        result.setIreIsSet(true);
                        msg = result;
            }
            else             if (e instanceof org.apache.airavata.model.error.AiravataClientException) {
                        result.ace = (org.apache.airavata.model.error.AiravataClientException) e;
                        result.setAceIsSet(true);
                        msg = result;
            }
            else             if (e instanceof org.apache.airavata.model.error.AiravataSystemException) {
                        result.ase = (org.apache.airavata.model.error.AiravataSystemException) e;
                        result.setAseIsSet(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 
            {
              msgType = org.apache.thrift.protocol.TMessageType.EXCEPTION;
              msg = (org.apache.thrift.TBase)new org.apache.thrift.TApplicationException(org.apache.thrift.TApplicationException.INTERNAL_ERROR, e.getMessage());
            }
            try {
              fcall.sendResponse(fb,msg,msgType,seqid);
              return;
            } catch (Exception ex) {
              LOGGER.error("Exception writing to internal frame buffer", ex);
            }
            fb.close();
          }
        };
      }

      protected boolean isOneway() {
        return false;
      }

      public void start(I iface, deleteBatchQueue_args args, org.apache.thrift.async.AsyncMethodCallback<Boolean> resultHandler) throws TException {
        iface.deleteBatchQueue(args.authzToken, args.computeResourceId, args.queueName,resultHandler);
      }
    }

    public static class registerGatewayResourceProfile<I extends AsyncIface> extends org.apache.thrift.AsyncProcessFunction<I, registerGatewayResourceProfile_args, String> {
      public registerGatewayResourceProfile() {
        super("registerGatewayResourceProfile");
      }

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

      public AsyncMethodCallback<String> getResultHandler(final AsyncFrameBuffer fb, final int seqid) {
        final org.apache.thrift.AsyncProcessFunction fcall = this;
        return new AsyncMethodCallback<String>() { 
          public void onComplete(String o) {
            registerGatewayResourceProfile_result result = new registerGatewayResourceProfile_result();
            result.success = o;
            try {
              fcall.sendResponse(fb,result, org.apache.thrift.protocol.TMessageType.REPLY,seqid);
              return;
            } catch (Exception e) {
              LOGGER.error("Exception writing to internal frame buffer", e);
            }
            fb.close();
          }
          public void onError(Exception e) {
            byte msgType = org.apache.thrift.protocol.TMessageType.REPLY;
            org.apache.thrift.TBase msg;
            registerGatewayResourceProfile_result result = new registerGatewayResourceProfile_result();
            if (e instanceof org.apache.airavata.model.error.InvalidRequestException) {
                        result.ire = (org.apache.airavata.model.error.InvalidRequestException) e;
                        result.setIreIsSet(true);
                        msg = result;
            }
            else             if (e instanceof org.apache.airavata.model.error.AiravataClientException) {
                        result.ace = (org.apache.airavata.model.error.AiravataClientException) e;
                        result.setAceIsSet(true);
                        msg = result;
            }
            else             if (e instanceof org.apache.airavata.model.error.AiravataSystemException) {
                        result.ase = (org.apache.airavata.model.error.AiravataSystemException) e;
                        result.setAseIsSet(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 
            {
              msgType = org.apache.thrift.protocol.TMessageType.EXCEPTION;
              msg = (org.apache.thrift.TBase)new org.apache.thrift.TApplicationException(org.apache.thrift.TApplicationException.INTERNAL_ERROR, e.getMessage());
            }
            try {
              fcall.sendResponse(fb,msg,msgType,seqid);
              return;
            } catch (Exception ex) {
              LOGGER.error("Exception writing to internal frame buffer", ex);
            }
            fb.close();
          }
        };
      }

      protected boolean isOneway() {
        return false;
      }

      public void start(I iface, registerGatewayResourceProfile_args args, org.apache.thrift.async.AsyncMethodCallback<String> resultHandler) throws TException {
        iface.registerGatewayResourceProfile(args.authzToken, args.gatewayResourceProfile,resultHandler);
      }
    }

    public static class getGatewayResourceProfile<I extends AsyncIface> extends org.apache.thrift.AsyncProcessFunction<I, getGatewayResourceProfile_args, org.apache.airavata.model.appcatalog.gatewayprofile.GatewayResourceProfile> {
      public getGatewayResourceProfile() {
        super("getGatewayResourceProfile");
      }

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

      public AsyncMethodCallback<org.apache.airavata.model.appcatalog.gatewayprofile.GatewayResourceProfile> getResultHandler(final AsyncFrameBuffer fb, final int seqid) {
        final org.apache.thrift.AsyncProcessFunction fcall = this;
        return new AsyncMethodCallback<org.apache.airavata.model.appcatalog.gatewayprofile.GatewayResourceProfile>() { 
          public void onComplete(org.apache.airavata.model.appcatalog.gatewayprofile.GatewayResourceProfile o) {
            getGatewayResourceProfile_result result = new getGatewayResourceProfile_result();
            result.success = o;
            try {
              fcall.sendResponse(fb,result, org.apache.thrift.protocol.TMessageType.REPLY,seqid);
              return;
            } catch (Exception e) {
              LOGGER.error("Exception writing to internal frame buffer", e);
            }
            fb.close();
          }
          public void onError(Exception e) {
            byte msgType = org.apache.thrift.protocol.TMessageType.REPLY;
            org.apache.thrift.TBase msg;
            getGatewayResourceProfile_result result = new getGatewayResourceProfile_result();
            if (e instanceof org.apache.airavata.model.error.InvalidRequestException) {
                        result.ire = (org.apache.airavata.model.error.InvalidRequestException) e;
                        result.setIreIsSet(true);
                        msg = result;
            }
            else             if (e instanceof org.apache.airavata.model.error.AiravataClientException) {
                        result.ace = (org.apache.airavata.model.error.AiravataClientException) e;
                        result.setAceIsSet(true);
                        msg = result;
            }
            else             if (e instanceof org.apache.airavata.model.error.AiravataSystemException) {
                        result.ase = (org.apache.airavata.model.error.AiravataSystemException) e;
                        result.setAseIsSet(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 
            {
              msgType = org.apache.thrift.protocol.TMessageType.EXCEPTION;
              msg = (org.apache.thrift.TBase)new org.apache.thrift.TApplicationException(org.apache.thrift.TApplicationException.INTERNAL_ERROR, e.getMessage());
            }
            try {
              fcall.sendResponse(fb,msg,msgType,seqid);
              return;
            } catch (Exception ex) {
              LOGGER.error("Exception writing to internal frame buffer", ex);
            }
            fb.close();
          }
        };
      }

      protected boolean isOneway() {
        return false;
      }

      public void start(I iface, getGatewayResourceProfile_args args, org.apache.thrift.async.AsyncMethodCallback<org.apache.airavata.model.appcatalog.gatewayprofile.GatewayResourceProfile> resultHandler) throws TException {
        iface.getGatewayResourceProfile(args.authzToken, args.gatewayID,resultHandler);
      }
    }

    public static class updateGatewayResourceProfile<I extends AsyncIface> extends org.apache.thrift.AsyncProcessFunction<I, updateGatewayResourceProfile_args, Boolean> {
      public updateGatewayResourceProfile() {
        super("updateGatewayResourceProfile");
      }

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

      public AsyncMethodCallback<Boolean> getResultHandler(final AsyncFrameBuffer fb, final int seqid) {
        final org.apache.thrift.AsyncProcessFunction fcall = this;
        return new AsyncMethodCallback<Boolean>() { 
          public void onComplete(Boolean o) {
            updateGatewayResourceProfile_result result = new updateGatewayResourceProfile_result();
            result.success = o;
            result.setSuccessIsSet(true);
            try {
              fcall.sendResponse(fb,result, org.apache.thrift.protocol.TMessageType.REPLY,seqid);
              return;
            } catch (Exception e) {
              LOGGER.error("Exception writing to internal frame buffer", e);
            }
            fb.close();
          }
          public void onError(Exception e) {
            byte msgType = org.apache.thrift.protocol.TMessageType.REPLY;
            org.apache.thrift.TBase msg;
            updateGatewayResourceProfile_result result = new updateGatewayResourceProfile_result();
            if (e instanceof org.apache.airavata.model.error.InvalidRequestException) {
                        result.ire = (org.apache.airavata.model.error.InvalidRequestException) e;
                        result.setIreIsSet(true);
                        msg = result;
            }
            else             if (e instanceof org.apache.airavata.model.error.AiravataClientException) {
                        result.ace = (org.apache.airavata.model.error.AiravataClientException) e;
                        result.setAceIsSet(true);
                        msg = result;
            }
            else             if (e instanceof org.apache.airavata.model.error.AiravataSystemException) {
                        result.ase = (org.apache.airavata.model.error.AiravataSystemException) e;
                        result.setAseIsSet(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 
            {
              msgType = org.apache.thrift.protocol.TMessageType.EXCEPTION;
              msg = (org.apache.thrift.TBase)new org.apache.thrift.TApplicationException(org.apache.thrift.TApplicationException.INTERNAL_ERROR, e.getMessage());
            }
            try {
              fcall.sendResponse(fb,msg,msgType,seqid);
              return;
            } catch (Exception ex) {
              LOGGER.error("Exception writing to internal frame buffer", ex);
            }
            fb.close();
          }
        };
      }

      protected boolean isOneway() {
        return false;
      }

      public void start(I iface, updateGatewayResourceProfile_args args, org.apache.thrift.async.AsyncMethodCallback<Boolean> resultHandler) throws TException {
        iface.updateGatewayResourceProfile(args.authzToken, args.gatewayID, args.gatewayResourceProfile,resultHandler);
      }
    }

    public static class deleteGatewayResourceProfile<I extends AsyncIface> extends org.apache.thrift.AsyncProcessFunction<I, deleteGatewayResourceProfile_args, Boolean> {
      public deleteGatewayResourceProfile() {
        super("deleteGatewayResourceProfile");
      }

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

      public AsyncMethodCallback<Boolean> getResultHandler(final AsyncFrameBuffer fb, final int seqid) {
        final org.apache.thrift.AsyncProcessFunction fcall = this;
        return new AsyncMethodCallback<Boolean>() { 
          public void onComplete(Boolean o) {
            deleteGatewayResourceProfile_result result = new deleteGatewayResourceProfile_result();
            result.success = o;
            result.setSuccessIsSet(true);
            try {
              fcall.sendResponse(fb,result, org.apache.thrift.protocol.TMessageType.REPLY,seqid);
              return;
            } catch (Exception e) {
              LOGGER.error("Exception writing to internal frame buffer", e);
            }
            fb.close();
          }
          public void onError(Exception e) {
            byte msgType = org.apache.thrift.protocol.TMessageType.REPLY;
            org.apache.thrift.TBase msg;
            deleteGatewayResourceProfile_result result = new deleteGatewayResourceProfile_result();
            if (e instanceof org.apache.airavata.model.error.InvalidRequestException) {
                        result.ire = (org.apache.airavata.model.error.InvalidRequestException) e;
                        result.setIreIsSet(true);
                        msg = result;
            }
            else             if (e instanceof org.apache.airavata.model.error.AiravataClientException) {
                        result.ace = (org.apache.airavata.model.error.AiravataClientException) e;
                        result.setAceIsSet(true);
                        msg = result;
            }
            else             if (e instanceof org.apache.airavata.model.error.AiravataSystemException) {
                        result.ase = (org.apache.airavata.model.error.AiravataSystemException) e;
                        result.setAseIsSet(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 
            {
              msgType = org.apache.thrift.protocol.TMessageType.EXCEPTION;
              msg = (org.apache.thrift.TBase)new org.apache.thrift.TApplicationException(org.apache.thrift.TApplicationException.INTERNAL_ERROR, e.getMessage());
            }
            try {
              fcall.sendResponse(fb,msg,msgType,seqid);
              return;
            } catch (Exception ex) {
              LOGGER.error("Exception writing to internal frame buffer", ex);
            }
            fb.close();
          }
        };
      }

      protected boolean isOneway() {
        return false;
      }

      public void start(I iface, deleteGatewayResourceProfile_args args, org.apache.thrift.async.AsyncMethodCallback<Boolean> resultHandler) throws TException {
        iface.deleteGatewayResourceProfile(args.authzToken, args.gatewayID,resultHandler);
      }
    }

    public static class addGatewayComputeResourcePreference<I extends AsyncIface> extends org.apache.thrift.AsyncProcessFunction<I, addGatewayComputeResourcePreference_args, Boolean> {
      public addGatewayComputeResourcePreference() {
        super("addGatewayComputeResourcePreference");
      }

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

      public AsyncMethodCallback<Boolean> getResultHandler(final AsyncFrameBuffer fb, final int seqid) {
        final org.apache.thrift.AsyncProcessFunction fcall = this;
        return new AsyncMethodCallback<Boolean>() { 
          public void onComplete(Boolean o) {
            addGatewayComputeResourcePreference_result result = new addGatewayComputeResourcePreference_result();
            result.success = o;
            result.setSuccessIsSet(true);
            try {
              fcall.sendResponse(fb,result, org.apache.thrift.protocol.TMessageType.REPLY,seqid);
              return;
            } catch (Exception e) {
              LOGGER.error("Exception writing to internal frame buffer", e);
            }
            fb.close();
          }
          public void onError(Exception e) {
            byte msgType = org.apache.thrift.protocol.TMessageType.REPLY;
            org.apache.thrift.TBase msg;
            addGatewayComputeResourcePreference_result result = new addGatewayComputeResourcePreference_result();
            if (e instanceof org.apache.airavata.model.error.InvalidRequestException) {
                        result.ire = (org.apache.airavata.model.error.InvalidRequestException) e;
                        result.setIreIsSet(true);
                        msg = result;
            }
            else             if (e instanceof org.apache.airavata.model.error.AiravataClientException) {
                        result.ace = (org.apache.airavata.model.error.AiravataClientException) e;
                        result.setAceIsSet(true);
                        msg = result;
            }
            else             if (e instanceof org.apache.airavata.model.error.AiravataSystemException) {
                        result.ase = (org.apache.airavata.model.error.AiravataSystemException) e;
                        result.setAseIsSet(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 
            {
              msgType = org.apache.thrift.protocol.TMessageType.EXCEPTION;
              msg = (org.apache.thrift.TBase)new org.apache.thrift.TApplicationException(org.apache.thrift.TApplicationException.INTERNAL_ERROR, e.getMessage());
            }
            try {
              fcall.sendResponse(fb,msg,msgType,seqid);
              return;
            } catch (Exception ex) {
              LOGGER.error("Exception writing to internal frame buffer", ex);
            }
            fb.close();
          }
        };
      }

      protected boolean isOneway() {
        return false;
      }

      public void start(I iface, addGatewayComputeResourcePreference_args args, org.apache.thrift.async.AsyncMethodCallback<Boolean> resultHandler) throws TException {
        iface.addGatewayComputeResourcePreference(args.authzToken, args.gatewayID, args.computeResourceId, args.computeResourcePreference,resultHandler);
      }
    }

    public static class addGatewayDataStoragePreference<I extends AsyncIface> extends org.apache.thrift.AsyncProcessFunction<I, addGatewayDataStoragePreference_args, Boolean> {
      public addGatewayDataStoragePreference() {
        super("addGatewayDataStoragePreference");
      }

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

      public AsyncMethodCallback<Boolean> getResultHandler(final AsyncFrameBuffer fb, final int seqid) {
        final org.apache.thrift.AsyncProcessFunction fcall = this;
        return new AsyncMethodCallback<Boolean>() { 
          public void onComplete(Boolean o) {
            addGatewayDataStoragePreference_result result = new addGatewayDataStoragePreference_result();
            result.success = o;
            result.setSuccessIsSet(true);
            try {
              fcall.sendResponse(fb,result, org.apache.thrift.protocol.TMessageType.REPLY,seqid);
              return;
            } catch (Exception e) {
              LOGGER.error("Exception writing to internal frame buffer", e);
            }
            fb.close();
          }
          public void onError(Exception e) {
            byte msgType = org.apache.thrift.protocol.TMessageType.REPLY;
            org.apache.thrift.TBase msg;
            addGatewayDataStoragePreference_result result = new addGatewayDataStoragePreference_result();
            if (e instanceof org.apache.airavata.model.error.InvalidRequestException) {
                        result.ire = (org.apache.airavata.model.error.InvalidRequestException) e;
                        result.setIreIsSet(true);
                        msg = result;
            }
            else             if (e instanceof org.apache.airavata.model.error.AiravataClientException) {
                        result.ace = (org.apache.airavata.model.error.AiravataClientException) e;
                        result.setAceIsSet(true);
                        msg = result;
            }
            else             if (e instanceof org.apache.airavata.model.error.AiravataSystemException) {
                        result.ase = (org.apache.airavata.model.error.AiravataSystemException) e;
                        result.setAseIsSet(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 
            {
              msgType = org.apache.thrift.protocol.TMessageType.EXCEPTION;
              msg = (org.apache.thrift.TBase)new org.apache.thrift.TApplicationException(org.apache.thrift.TApplicationException.INTERNAL_ERROR, e.getMessage());
            }
            try {
              fcall.sendResponse(fb,msg,msgType,seqid);
              return;
            } catch (Exception ex) {
              LOGGER.error("Exception writing to internal frame buffer", ex);
            }
            fb.close();
          }
        };
      }

      protected boolean isOneway() {
        return false;
      }

      public void start(I iface, addGatewayDataStoragePreference_args args, org.apache.thrift.async.AsyncMethodCallback<Boolean> resultHandler) throws TException {
        iface.addGatewayDataStoragePreference(args.authzToken, args.gatewayID, args.dataMoveId, args.dataStoragePreference,resultHandler);
      }
    }

    public static class getGatewayComputeResourcePreference<I extends AsyncIface> extends org.apache.thrift.AsyncProcessFunction<I, getGatewayComputeResourcePreference_args, org.apache.airavata.model.appcatalog.gatewayprofile.ComputeResourcePreference> {
      public getGatewayComputeResourcePreference() {
        super("getGatewayComputeResourcePreference");
      }

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

      public AsyncMethodCallback<org.apache.airavata.model.appcatalog.gatewayprofile.ComputeResourcePreference> getResultHandler(final AsyncFrameBuffer fb, final int seqid) {
        final org.apache.thrift.AsyncProcessFunction fcall = this;
        return new AsyncMethodCallback<org.apache.airavata.model.appcatalog.gatewayprofile.ComputeResourcePreference>() { 
          public void onComplete(org.apache.airavata.model.appcatalog.gatewayprofile.ComputeResourcePreference o) {
            getGatewayComputeResourcePreference_result result = new getGatewayComputeResourcePreference_result();
            result.success = o;
            try {
              fcall.sendResponse(fb,result, org.apache.thrift.protocol.TMessageType.REPLY,seqid);
              return;
            } catch (Exception e) {
              LOGGER.error("Exception writing to internal frame buffer", e);
            }
            fb.close();
          }
          public void onError(Exception e) {
            byte msgType = org.apache.thrift.protocol.TMessageType.REPLY;
            org.apache.thrift.TBase msg;
            getGatewayComputeResourcePreference_result result = new getGatewayComputeResourcePreference_result();
            if (e instanceof org.apache.airavata.model.error.InvalidRequestException) {
                        result.ire = (org.apache.airavata.model.error.InvalidRequestException) e;
                        result.setIreIsSet(true);
                        msg = result;
            }
            else             if (e instanceof org.apache.airavata.model.error.AiravataClientException) {
                        result.ace = (org.apache.airavata.model.error.AiravataClientException) e;
                        result.setAceIsSet(true);
                        msg = result;
            }
            else             if (e instanceof org.apache.airavata.model.error.AiravataSystemException) {
                        result.ase = (org.apache.airavata.model.error.AiravataSystemException) e;
                        result.setAseIsSet(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 
            {
              msgType = org.apache.thrift.protocol.TMessageType.EXCEPTION;
              msg = (org.apache.thrift.TBase)new org.apache.thrift.TApplicationException(org.apache.thrift.TApplicationException.INTERNAL_ERROR, e.getMessage());
            }
            try {
              fcall.sendResponse(fb,msg,msgType,seqid);
              return;
            } catch (Exception ex) {
              LOGGER.error("Exception writing to internal frame buffer", ex);
            }
            fb.close();
          }
        };
      }

      protected boolean isOneway() {
        return false;
      }

      public void start(I iface, getGatewayComputeResourcePreference_args args, org.apache.thrift.async.AsyncMethodCallback<org.apache.airavata.model.appcatalog.gatewayprofile.ComputeResourcePreference> resultHandler) throws TException {
        iface.getGatewayComputeResourcePreference(args.authzToken, args.gatewayID, args.computeResourceId,resultHandler);
      }
    }

    public static class getGatewayDataStoragePreference<I extends AsyncIface> extends org.apache.thrift.AsyncProcessFunction<I, getGatewayDataStoragePreference_args, org.apache.airavata.model.appcatalog.gatewayprofile.DataStoragePreference> {
      public getGatewayDataStoragePreference() {
        super("getGatewayDataStoragePreference");
      }

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

      public AsyncMethodCallback<org.apache.airavata.model.appcatalog.gatewayprofile.DataStoragePreference> getResultHandler(final AsyncFrameBuffer fb, final int seqid) {
        final org.apache.thrift.AsyncProcessFunction fcall = this;
        return new AsyncMethodCallback<org.apache.airavata.model.appcatalog.gatewayprofile.DataStoragePreference>() { 
          public void onComplete(org.apache.airavata.model.appcatalog.gatewayprofile.DataStoragePreference o) {
            getGatewayDataStoragePreference_result result = new getGatewayDataStoragePreference_result();
            result.success = o;
            try {
              fcall.sendResponse(fb,result, org.apache.thrift.protocol.TMessageType.REPLY,seqid);
              return;
            } catch (Exception e) {
              LOGGER.error("Exception writing to internal frame buffer", e);
            }
            fb.close();
          }
          public void onError(Exception e) {
            byte msgType = org.apache.thrift.protocol.TMessageType.REPLY;
            org.apache.thrift.TBase msg;
            getGatewayDataStoragePreference_result result = new getGatewayDataStoragePreference_result();
            if (e instanceof org.apache.airavata.model.error.InvalidRequestException) {
                        result.ire = (org.apache.airavata.model.error.InvalidRequestException) e;
                        result.setIreIsSet(true);
                        msg = result;
            }
            else             if (e instanceof org.apache.airavata.model.error.AiravataClientException) {
                        result.ace = (org.apache.airavata.model.error.AiravataClientException) e;
                        result.setAceIsSet(true);
                        msg = result;
            }
            else             if (e instanceof org.apache.airavata.model.error.AiravataSystemException) {
                        result.ase = (org.apache.airavata.model.error.AiravataSystemException) e;
                        result.setAseIsSet(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 
            {
              msgType = org.apache.thrift.protocol.TMessageType.EXCEPTION;
              msg = (org.apache.thrift.TBase)new org.apache.thrift.TApplicationException(org.apache.thrift.TApplicationException.INTERNAL_ERROR, e.getMessage());
            }
            try {
              fcall.sendResponse(fb,msg,msgType,seqid);
              return;
            } catch (Exception ex) {
              LOGGER.error("Exception writing to internal frame buffer", ex);
            }
            fb.close();
          }
        };
      }

      protected boolean isOneway() {
        return false;
      }

      public void start(I iface, getGatewayDataStoragePreference_args args, org.apache.thrift.async.AsyncMethodCallback<org.apache.airavata.model.appcatalog.gatewayprofile.DataStoragePreference> resultHandler) throws TException {
        iface.getGatewayDataStoragePreference(args.authzToken, args.gatewayID, args.dataMoveId,resultHandler);
      }
    }

    public static class getAllGatewayComputeResourcePreferences<I extends AsyncIface> extends org.apache.thrift.AsyncProcessFunction<I, getAllGatewayComputeResourcePreferences_args, List<org.apache.airavata.model.appcatalog.gatewayprofile.ComputeResourcePreference>> {
      public getAllGatewayComputeResourcePreferences() {
        super("getAllGatewayComputeResourcePreferences");
      }

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

      public AsyncMethodCallback<List<org.apache.airavata.model.appcatalog.gatewayprofile.ComputeResourcePreference>> getResultHandler(final AsyncFrameBuffer fb, final int seqid) {
        final org.apache.thrift.AsyncProcessFunction fcall = this;
        return new AsyncMethodCallback<List<org.apache.airavata.model.appcatalog.gatewayprofile.ComputeResourcePreference>>() { 
          public void onComplete(List<org.apache.airavata.model.appcatalog.gatewayprofile.ComputeResourcePreference> o) {
            getAllGatewayComputeResourcePreferences_result result = new getAllGatewayComputeResourcePreferences_result();
            result.success = o;
            try {
              fcall.sendResponse(fb,result, org.apache.thrift.protocol.TMessageType.REPLY,seqid);
              return;
            } catch (Exception e) {
              LOGGER.error("Exception writing to internal frame buffer", e);
            }
            fb.close();
          }
          public void onError(Exception e) {
            byte msgType = org.apache.thrift.protocol.TMessageType.REPLY;
            org.apache.thrift.TBase msg;
            getAllGatewayComputeResourcePreferences_result result = new getAllGatewayComputeResourcePreferences_result();
            if (e instanceof org.apache.airavata.model.error.InvalidRequestException) {
                        result.ire = (org.apache.airavata.model.error.InvalidRequestException) e;
                        result.setIreIsSet(true);
                        msg = result;
            }
            else             if (e instanceof org.apache.airavata.model.error.AiravataClientException) {
                        result.ace = (org.apache.airavata.model.error.AiravataClientException) e;
                        result.setAceIsSet(true);
                        msg = result;
            }
            else             if (e instanceof org.apache.airavata.model.error.AiravataSystemException) {
                        result.ase = (org.apache.airavata.model.error.AiravataSystemException) e;
                        result.setAseIsSet(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 
            {
              msgType = org.apache.thrift.protocol.TMessageType.EXCEPTION;
              msg = (org.apache.thrift.TBase)new org.apache.thrift.TApplicationException(org.apache.thrift.TApplicationException.INTERNAL_ERROR, e.getMessage());
            }
            try {
              fcall.sendResponse(fb,msg,msgType,seqid);
              return;
            } catch (Exception ex) {
              LOGGER.error("Exception writing to internal frame buffer", ex);
            }
            fb.close();
          }
        };
      }

      protected boolean isOneway() {
        return false;
      }

      public void start(I iface, getAllGatewayComputeResourcePreferences_args args, org.apache.thrift.async.AsyncMethodCallback<List<org.apache.airavata.model.appcatalog.gatewayprofile.ComputeResourcePreference>> resultHandler) throws TException {
        iface.getAllGatewayComputeResourcePreferences(args.authzToken, args.gatewayID,resultHandler);
      }
    }

    public static class getAllGatewayDataStoragePreferences<I extends AsyncIface> extends org.apache.thrift.AsyncProcessFunction<I, getAllGatewayDataStoragePreferences_args, List<org.apache.airavata.model.appcatalog.gatewayprofile.DataStoragePreference>> {
      public getAllGatewayDataStoragePreferences() {
        super("getAllGatewayDataStoragePreferences");
      }

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

      public AsyncMethodCallback<List<org.apache.airavata.model.appcatalog.gatewayprofile.DataStoragePreference>> getResultHandler(final AsyncFrameBuffer fb, final int seqid) {
        final org.apache.thrift.AsyncProcessFunction fcall = this;
        return new AsyncMethodCallback<List<org.apache.airavata.model.appcatalog.gatewayprofile.DataStoragePreference>>() { 
          public void onComplete(List<org.apache.airavata.model.appcatalog.gatewayprofile.DataStoragePreference> o) {
            getAllGatewayDataStoragePreferences_result result = new getAllGatewayDataStoragePreferences_result();
            result.success = o;
            try {
              fcall.sendResponse(fb,result, org.apache.thrift.protocol.TMessageType.REPLY,seqid);
              return;
            } catch (Exception e) {
              LOGGER.error("Exception writing to internal frame buffer", e);
            }
            fb.close();
          }
          public void onError(Exception e) {
            byte msgType = org.apache.thrift.protocol.TMessageType.REPLY;
            org.apache.thrift.TBase msg;
            getAllGatewayDataStoragePreferences_result result = new getAllGatewayDataStoragePreferences_result();
            if (e instanceof org.apache.airavata.model.error.InvalidRequestException) {
                        result.ire = (org.apache.airavata.model.error.InvalidRequestException) e;
                        result.setIreIsSet(true);
                        msg = result;
            }
            else             if (e instanceof org.apache.airavata.model.error.AiravataClientException) {
                        result.ace = (org.apache.airavata.model.error.AiravataClientException) e;
                        result.setAceIsSet(true);
                        msg = result;
            }
            else             if (e instanceof org.apache.airavata.model.error.AiravataSystemException) {
                        result.ase = (org.apache.airavata.model.error.AiravataSystemException) e;
                        result.setAseIsSet(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 
            {
              msgType = org.apache.thrift.protocol.TMessageType.EXCEPTION;
              msg = (org.apache.thrift.TBase)new org.apache.thrift.TApplicationException(org.apache.thrift.TApplicationException.INTERNAL_ERROR, e.getMessage());
            }
            try {
              fcall.sendResponse(fb,msg,msgType,seqid);
              return;
            } catch (Exception ex) {
              LOGGER.error("Exception writing to internal frame buffer", ex);
            }
            fb.close();
          }
        };
      }

      protected boolean isOneway() {
        return false;
      }

      public void start(I iface, getAllGatewayDataStoragePreferences_args args, org.apache.thrift.async.AsyncMethodCallback<List<org.apache.airavata.model.appcatalog.gatewayprofile.DataStoragePreference>> resultHandler) throws TException {
        iface.getAllGatewayDataStoragePreferences(args.authzToken, args.gatewayID,resultHandler);
      }
    }

    public static class getAllGatewayResourceProfiles<I extends AsyncIface> extends org.apache.thrift.AsyncProcessFunction<I, getAllGatewayResourceProfiles_args, List<org.apache.airavata.model.appcatalog.gatewayprofile.GatewayResourceProfile>> {
      public getAllGatewayResourceProfiles() {
        super("getAllGatewayResourceProfiles");
      }

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

      public AsyncMethodCallback<List<org.apache.airavata.model.appcatalog.gatewayprofile.GatewayResourceProfile>> getResultHandler(final AsyncFrameBuffer fb, final int seqid) {
        final org.apache.thrift.AsyncProcessFunction fcall = this;
        return new AsyncMethodCallback<List<org.apache.airavata.model.appcatalog.gatewayprofile.GatewayResourceProfile>>() { 
          public void onComplete(List<org.apache.airavata.model.appcatalog.gatewayprofile.GatewayResourceProfile> o) {
            getAllGatewayResourceProfiles_result result = new getAllGatewayResourceProfiles_result();
            result.success = o;
            try {
              fcall.sendResponse(fb,result, org.apache.thrift.protocol.TMessageType.REPLY,seqid);
              return;
            } catch (Exception e) {
              LOGGER.error("Exception writing to internal frame buffer", e);
            }
            fb.close();
          }
          public void onError(Exception e) {
            byte msgType = org.apache.thrift.protocol.TMessageType.REPLY;
            org.apache.thrift.TBase msg;
            getAllGatewayResourceProfiles_result result = new getAllGatewayResourceProfiles_result();
            if (e instanceof org.apache.airavata.model.error.InvalidRequestException) {
                        result.ire = (org.apache.airavata.model.error.InvalidRequestException) e;
                        result.setIreIsSet(true);
                        msg = result;
            }
            else             if (e instanceof org.apache.airavata.model.error.AiravataClientException) {
                        result.ace = (org.apache.airavata.model.error.AiravataClientException) e;
                        result.setAceIsSet(true);
                        msg = result;
            }
            else             if (e instanceof org.apache.airavata.model.error.AiravataSystemException) {
                        result.ase = (org.apache.airavata.model.error.AiravataSystemException) e;
                        result.setAseIsSet(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 
            {
              msgType = org.apache.thrift.protocol.TMessageType.EXCEPTION;
              msg = (org.apache.thrift.TBase)new org.apache.thrift.TApplicationException(org.apache.thrift.TApplicationException.INTERNAL_ERROR, e.getMessage());
            }
            try {
              fcall.sendResponse(fb,msg,msgType,seqid);
              return;
            } catch (Exception ex) {
              LOGGER.error("Exception writing to internal frame buffer", ex);
            }
            fb.close();
          }
        };
      }

      protected boolean isOneway() {
        return false;
      }

      public void start(I iface, getAllGatewayResourceProfiles_args args, org.apache.thrift.async.AsyncMethodCallback<List<org.apache.airavata.model.appcatalog.gatewayprofile.GatewayResourceProfile>> resultHandler) throws TException {
        iface.getAllGatewayResourceProfiles(args.authzToken,resultHandler);
      }
    }

    public static class updateGatewayComputeResourcePreference<I extends AsyncIface> extends org.apache.thrift.AsyncProcessFunction<I, updateGatewayComputeResourcePreference_args, Boolean> {
      public updateGatewayComputeResourcePreference() {
        super("updateGatewayComputeResourcePreference");
      }

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

      public AsyncMethodCallback<Boolean> getResultHandler(final AsyncFrameBuffer fb, final int seqid) {
        final org.apache.thrift.AsyncProcessFunction fcall = this;
        return new AsyncMethodCallback<Boolean>() { 
          public void onComplete(Boolean o) {
            updateGatewayComputeResourcePreference_result result = new updateGatewayComputeResourcePreference_result();
            result.success = o;
            result.setSuccessIsSet(true);
            try {
              fcall.sendResponse(fb,result, org.apache.thrift.protocol.TMessageType.REPLY,seqid);
              return;
            } catch (Exception e) {
              LOGGER.error("Exception writing to internal frame buffer", e);
            }
            fb.close();
          }
          public void onError(Exception e) {
            byte msgType = org.apache.thrift.protocol.TMessageType.REPLY;
            org.apache.thrift.TBase msg;
            updateGatewayComputeResourcePreference_result result = new updateGatewayComputeResourcePreference_result();
            if (e instanceof org.apache.airavata.model.error.InvalidRequestException) {
                        result.ire = (org.apache.airavata.model.error.InvalidRequestException) e;
                        result.setIreIsSet(true);
                        msg = result;
            }
            else             if (e instanceof org.apache.airavata.model.error.AiravataClientException) {
                        result.ace = (org.apache.airavata.model.error.AiravataClientException) e;
                        result.setAceIsSet(true);
                        msg = result;
            }
            else             if (e instanceof org.apache.airavata.model.error.AiravataSystemException) {
                        result.ase = (org.apache.airavata.model.error.AiravataSystemException) e;
                        result.setAseIsSet(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 
            {
              msgType = org.apache.thrift.protocol.TMessageType.EXCEPTION;
              msg = (org.apache.thrift.TBase)new org.apache.thrift.TApplicationException(org.apache.thrift.TApplicationException.INTERNAL_ERROR, e.getMessage());
            }
            try {
              fcall.sendResponse(fb,msg,msgType,seqid);
              return;
            } catch (Exception ex) {
              LOGGER.error("Exception writing to internal frame buffer", ex);
            }
            fb.close();
          }
        };
      }

      protected boolean isOneway() {
        return false;
      }

      public void start(I iface, updateGatewayComputeResourcePreference_args args, org.apache.thrift.async.AsyncMethodCallback<Boolean> resultHandler) throws TException {
        iface.updateGatewayComputeResourcePreference(args.authzToken, args.gatewayID, args.computeResourceId, args.computeResourcePreference,resultHandler);
      }
    }

    public static class updateGatewayDataStoragePreference<I extends AsyncIface> extends org.apache.thrift.AsyncProcessFunction<I, updateGatewayDataStoragePreference_args, Boolean> {
      public updateGatewayDataStoragePreference() {
        super("updateGatewayDataStoragePreference");
      }

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

      public AsyncMethodCallback<Boolean> getResultHandler(final AsyncFrameBuffer fb, final int seqid) {
        final org.apache.thrift.AsyncProcessFunction fcall = this;
        return new AsyncMethodCallback<Boolean>() { 
          public void onComplete(Boolean o) {
            updateGatewayDataStoragePreference_result result = new updateGatewayDataStoragePreference_result();
            result.success = o;
            result.setSuccessIsSet(true);
            try {
              fcall.sendResponse(fb,result, org.apache.thrift.protocol.TMessageType.REPLY,seqid);
              return;
            } catch (Exception e) {
              LOGGER.error("Exception writing to internal frame buffer", e);
            }
            fb.close();
          }
          public void onError(Exception e) {
            byte msgType = org.apache.thrift.protocol.TMessageType.REPLY;
            org.apache.thrift.TBase msg;
            updateGatewayDataStoragePreference_result result = new updateGatewayDataStoragePreference_result();
            if (e instanceof org.apache.airavata.model.error.InvalidRequestException) {
                        result.ire = (org.apache.airavata.model.error.InvalidRequestException) e;
                        result.setIreIsSet(true);
                        msg = result;
            }
            else             if (e instanceof org.apache.airavata.model.error.AiravataClientException) {
                        result.ace = (org.apache.airavata.model.error.AiravataClientException) e;
                        result.setAceIsSet(true);
                        msg = result;
            }
            else             if (e instanceof org.apache.airavata.model.error.AiravataSystemException) {
                        result.ase = (org.apache.airavata.model.error.AiravataSystemException) e;
                        result.setAseIsSet(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 
            {
              msgType = org.apache.thrift.protocol.TMessageType.EXCEPTION;
              msg = (org.apache.thrift.TBase)new org.apache.thrift.TApplicationException(org.apache.thrift.TApplicationException.INTERNAL_ERROR, e.getMessage());
            }
            try {
              fcall.sendResponse(fb,msg,msgType,seqid);
              return;
            } catch (Exception ex) {
              LOGGER.error("Exception writing to internal frame buffer", ex);
            }
            fb.close();
          }
        };
      }

      protected boolean isOneway() {
        return false;
      }

      public void start(I iface, updateGatewayDataStoragePreference_args args, org.apache.thrift.async.AsyncMethodCallback<Boolean> resultHandler) throws TException {
        iface.updateGatewayDataStoragePreference(args.authzToken, args.gatewayID, args.dataMoveId, args.dataStoragePreference,resultHandler);
      }
    }

    public static class deleteGatewayComputeResourcePreference<I extends AsyncIface> extends org.apache.thrift.AsyncProcessFunction<I, deleteGatewayComputeResourcePreference_args, Boolean> {
      public deleteGatewayComputeResourcePreference() {
        super("deleteGatewayComputeResourcePreference");
      }

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

      public AsyncMethodCallback<Boolean> getResultHandler(final AsyncFrameBuffer fb, final int seqid) {
        final org.apache.thrift.AsyncProcessFunction fcall = this;
        return new AsyncMethodCallback<Boolean>() { 
          public void onComplete(Boolean o) {
            deleteGatewayComputeResourcePreference_result result = new deleteGatewayComputeResourcePreference_result();
            result.success = o;
            result.setSuccessIsSet(true);
            try {
              fcall.sendResponse(fb,result, org.apache.thrift.protocol.TMessageType.REPLY,seqid);
              return;
            } catch (Exception e) {
              LOGGER.error("Exception writing to internal frame buffer", e);
            }
            fb.close();
          }
          public void onError(Exception e) {
            byte msgType = org.apache.thrift.protocol.TMessageType.REPLY;
            org.apache.thrift.TBase msg;
            deleteGatewayComputeResourcePreference_result result = new deleteGatewayComputeResourcePreference_result();
            if (e instanceof org.apache.airavata.model.error.InvalidRequestException) {
                        result.ire = (org.apache.airavata.model.error.InvalidRequestException) e;
                        result.setIreIsSet(true);
                        msg = result;
            }
            else             if (e instanceof org.apache.airavata.model.error.AiravataClientException) {
                        result.ace = (org.apache.airavata.model.error.AiravataClientException) e;
                        result.setAceIsSet(true);
                        msg = result;
            }
            else             if (e instanceof org.apache.airavata.model.error.AiravataSystemException) {
                        result.ase = (org.apache.airavata.model.error.AiravataSystemException) e;
                        result.setAseIsSet(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 
            {
              msgType = org.apache.thrift.protocol.TMessageType.EXCEPTION;
              msg = (org.apache.thrift.TBase)new org.apache.thrift.TApplicationException(org.apache.thrift.TApplicationException.INTERNAL_ERROR, e.getMessage());
            }
            try {
              fcall.sendResponse(fb,msg,msgType,seqid);
              return;
            } catch (Exception ex) {
              LOGGER.error("Exception writing to internal frame buffer", ex);
            }
            fb.close();
          }
        };
      }

      protected boolean isOneway() {
        return false;
      }

      public void start(I iface, deleteGatewayComputeResourcePreference_args args, org.apache.thrift.async.AsyncMethodCallback<Boolean> resultHandler) throws TException {
        iface.deleteGatewayComputeResourcePreference(args.authzToken, args.gatewayID, args.computeResourceId,resultHandler);
      }
    }

    public static class deleteGatewayDataStoragePreference<I extends AsyncIface> extends org.apache.thrift.AsyncProcessFunction<I, deleteGatewayDataStoragePreference_args, Boolean> {
      public deleteGatewayDataStoragePreference() {
        super("deleteGatewayDataStoragePreference");
      }

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

      public AsyncMethodCallback<Boolean> getResultHandler(final AsyncFrameBuffer fb, final int seqid) {
        final org.apache.thrift.AsyncProcessFunction fcall = this;
        return new AsyncMethodCallback<Boolean>() { 
          public void onComplete(Boolean o) {
            deleteGatewayDataStoragePreference_result result = new deleteGatewayDataStoragePreference_result();
            result.success = o;
            result.setSuccessIsSet(true);
            try {
              fcall.sendResponse(fb,result, org.apache.thrift.protocol.TMessageType.REPLY,seqid);
              return;
            } catch (Exception e) {
              LOGGER.error("Exception writing to internal frame buffer", e);
            }
            fb.close();
          }
          public void onError(Exception e) {
            byte msgType = org.apache.thrift.protocol.TMessageType.REPLY;
            org.apache.thrift.TBase msg;
            deleteGatewayDataStoragePreference_result result = new deleteGatewayDataStoragePreference_result();
            if (e instanceof org.apache.airavata.model.error.InvalidRequestException) {
                        result.ire = (org.apache.airavata.model.error.InvalidRequestException) e;
                        result.setIreIsSet(true);
                        msg = result;
            }
            else             if (e instanceof org.apache.airavata.model.error.AiravataClientException) {
                        result.ace = (org.apache.airavata.model.error.AiravataClientException) e;
                        result.setAceIsSet(true);
                        msg = result;
            }
            else             if (e instanceof org.apache.airavata.model.error.AiravataSystemException) {
                        result.ase = (org.apache.airavata.model.error.AiravataSystemException) e;
                        result.setAseIsSet(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 
            {
              msgType = org.apache.thrift.protocol.TMessageType.EXCEPTION;
              msg = (org.apache.thrift.TBase)new org.apache.thrift.TApplicationException(org.apache.thrift.TApplicationException.INTERNAL_ERROR, e.getMessage());
            }
            try {
              fcall.sendResponse(fb,msg,msgType,seqid);
              return;
            } catch (Exception ex) {
              LOGGER.error("Exception writing to internal frame buffer", ex);
            }
            fb.close();
          }
        };
      }

      protected boolean isOneway() {
        return false;
      }

      public void start(I iface, deleteGatewayDataStoragePreference_args args, org.apache.thrift.async.AsyncMethodCallback<Boolean> resultHandler) throws TException {
        iface.deleteGatewayDataStoragePreference(args.authzToken, args.gatewayID, args.dataMoveId,resultHandler);
      }
    }

    public static class getAllWorkflows<I extends AsyncIface> extends org.apache.thrift.AsyncProcessFunction<I, getAllWorkflows_args, List<String>> {
      public getAllWorkflows() {
        super("getAllWorkflows");
      }

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

      public AsyncMethodCallback<List<String>> getResultHandler(final AsyncFrameBuffer fb, final int seqid) {
        final org.apache.thrift.AsyncProcessFunction fcall = this;
        return new AsyncMethodCallback<List<String>>() { 
          public void onComplete(List<String> o) {
            getAllWorkflows_result result = new getAllWorkflows_result();
            result.success = o;
            try {
              fcall.sendResponse(fb,result, org.apache.thrift.protocol.TMessageType.REPLY,seqid);
              return;
            } catch (Exception e) {
              LOGGER.error("Exception writing to internal frame buffer", e);
            }
            fb.close();
          }
          public void onError(Exception e) {
            byte msgType = org.apache.thrift.protocol.TMessageType.REPLY;
            org.apache.thrift.TBase msg;
            getAllWorkflows_result result = new getAllWorkflows_result();
            if (e instanceof org.apache.airavata.model.error.InvalidRequestException) {
                        result.ire = (org.apache.airavata.model.error.InvalidRequestException) e;
                        result.setIreIsSet(true);
                        msg = result;
            }
            else             if (e instanceof org.apache.airavata.model.error.AiravataClientException) {
                        result.ace = (org.apache.airavata.model.error.AiravataClientException) e;
                        result.setAceIsSet(true);
                        msg = result;
            }
            else             if (e instanceof org.apache.airavata.model.error.AiravataSystemException) {
                        result.ase = (org.apache.airavata.model.error.AiravataSystemException) e;
                        result.setAseIsSet(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 
            {
              msgType = org.apache.thrift.protocol.TMessageType.EXCEPTION;
              msg = (org.apache.thrift.TBase)new org.apache.thrift.TApplicationException(org.apache.thrift.TApplicationException.INTERNAL_ERROR, e.getMessage());
            }
            try {
              fcall.sendResponse(fb,msg,msgType,seqid);
              return;
            } catch (Exception ex) {
              LOGGER.error("Exception writing to internal frame buffer", ex);
            }
            fb.close();
          }
        };
      }

      protected boolean isOneway() {
        return false;
      }

      public void start(I iface, getAllWorkflows_args args, org.apache.thrift.async.AsyncMethodCallback<List<String>> resultHandler) throws TException {
        iface.getAllWorkflows(args.authzToken, args.gatewayId,resultHandler);
      }
    }

    public static class getWorkflow<I extends AsyncIface> extends org.apache.thrift.AsyncProcessFunction<I, getWorkflow_args, org.apache.airavata.model.Workflow> {
      public getWorkflow() {
        super("getWorkflow");
      }

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

      public AsyncMethodCallback<org.apache.airavata.model.Workflow> getResultHandler(final AsyncFrameBuffer fb, final int seqid) {
        final org.apache.thrift.AsyncProcessFunction fcall = this;
        return new AsyncMethodCallback<org.apache.airavata.model.Workflow>() { 
          public void onComplete(org.apache.airavata.model.Workflow o) {
            getWorkflow_result result = new getWorkflow_result();
            result.success = o;
            try {
              fcall.sendResponse(fb,result, org.apache.thrift.protocol.TMessageType.REPLY,seqid);
              return;
            } catch (Exception e) {
              LOGGER.error("Exception writing to internal frame buffer", e);
            }
            fb.close();
          }
          public void onError(Exception e) {
            byte msgType = org.apache.thrift.protocol.TMessageType.REPLY;
            org.apache.thrift.TBase msg;
            getWorkflow_result result = new getWorkflow_result();
            if (e instanceof org.apache.airavata.model.error.InvalidRequestException) {
                        result.ire = (org.apache.airavata.model.error.InvalidRequestException) e;
                        result.setIreIsSet(true);
                        msg = result;
            }
            else             if (e instanceof org.apache.airavata.model.error.AiravataClientException) {
                        result.ace = (org.apache.airavata.model.error.AiravataClientException) e;
                        result.setAceIsSet(true);
                        msg = result;
            }
            else             if (e instanceof org.apache.airavata.model.error.AiravataSystemException) {
                        result.ase = (org.apache.airavata.model.error.AiravataSystemException) e;
                        result.setAseIsSet(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 
            {
              msgType = org.apache.thrift.protocol.TMessageType.EXCEPTION;
              msg = (org.apache.thrift.TBase)new org.apache.thrift.TApplicationException(org.apache.thrift.TApplicationException.INTERNAL_ERROR, e.getMessage());
            }
            try {
              fcall.sendResponse(fb,msg,msgType,seqid);
              return;
            } catch (Exception ex) {
              LOGGER.error("Exception writing to internal frame buffer", ex);
            }
            fb.close();
          }
        };
      }

      protected boolean isOneway() {
        return false;
      }

      public void start(I iface, getWorkflow_args args, org.apache.thrift.async.AsyncMethodCallback<org.apache.airavata.model.Workflow> resultHandler) throws TException {
        iface.getWorkflow(args.authzToken, args.workflowTemplateId,resultHandler);
      }
    }

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

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

      public AsyncMethodCallback<Void> getResultHandler(final AsyncFrameBuffer fb, final int seqid) {
        final org.apache.thrift.AsyncProcessFunction fcall = this;
        return new AsyncMethodCallback<Void>() { 
          public void onComplete(Void o) {
            deleteWorkflow_result result = new deleteWorkflow_result();
            try {
              fcall.sendResponse(fb,result, org.apache.thrift.protocol.TMessageType.REPLY,seqid);
              return;
            } catch (Exception e) {
              LOGGER.error("Exception writing to internal frame buffer", e);
            }
            fb.close();
          }
          public void onError(Exception e) {
            byte msgType = org.apache.thrift.protocol.TMessageType.REPLY;
            org.apache.thrift.TBase msg;
            deleteWorkflow_result result = new deleteWorkflow_result();
            if (e instanceof org.apache.airavata.model.error.InvalidRequestException) {
                        result.ire = (org.apache.airavata.model.error.InvalidRequestException) e;
                        result.setIreIsSet(true);
                        msg = result;
            }
            else             if (e instanceof org.apache.airavata.model.error.AiravataClientException) {
                        result.ace = (org.apache.airavata.model.error.AiravataClientException) e;
                        result.setAceIsSet(true);
                        msg = result;
            }
            else             if (e instanceof org.apache.airavata.model.error.AiravataSystemException) {
                        result.ase = (org.apache.airavata.model.error.AiravataSystemException) e;
                        result.setAseIsSet(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 
            {
              msgType = org.apache.thrift.protocol.TMessageType.EXCEPTION;
              msg = (org.apache.thrift.TBase)new org.apache.thrift.TApplicationException(org.apache.thrift.TApplicationException.INTERNAL_ERROR, e.getMessage());
            }
            try {
              fcall.sendResponse(fb,msg,msgType,seqid);
              return;
            } catch (Exception ex) {
              LOGGER.error("Exception writing to internal frame buffer", ex);
            }
            fb.close();
          }
        };
      }

      protected boolean isOneway() {
        return false;
      }

      public void start(I iface, deleteWorkflow_args args, org.apache.thrift.async.AsyncMethodCallback<Void> resultHandler) throws TException {
        iface.deleteWorkflow(args.authzToken, args.workflowTemplateId,resultHandler);
      }
    }

    public static class registerWorkflow<I extends AsyncIface> extends org.apache.thrift.AsyncProcessFunction<I, registerWorkflow_args, String> {
      public registerWorkflow() {
        super("registerWorkflow");
      }

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

      public AsyncMethodCallback<String> getResultHandler(final AsyncFrameBuffer fb, final int seqid) {
        final org.apache.thrift.AsyncProcessFunction fcall = this;
        return new AsyncMethodCallback<String>() { 
          public void onComplete(String o) {
            registerWorkflow_result result = new registerWorkflow_result();
            result.success = o;
            try {
              fcall.sendResponse(fb,result, org.apache.thrift.protocol.TMessageType.REPLY,seqid);
              return;
            } catch (Exception e) {
              LOGGER.error("Exception writing to internal frame buffer", e);
            }
            fb.close();
          }
          public void onError(Exception e) {
            byte msgType = org.apache.thrift.protocol.TMessageType.REPLY;
            org.apache.thrift.TBase msg;
            registerWorkflow_result result = new registerWorkflow_result();
            if (e instanceof org.apache.airavata.model.error.InvalidRequestException) {
                        result.ire = (org.apache.airavata.model.error.InvalidRequestException) e;
                        result.setIreIsSet(true);
                        msg = result;
            }
            else             if (e instanceof org.apache.airavata.model.error.AiravataClientException) {
                        result.ace = (org.apache.airavata.model.error.AiravataClientException) e;
                        result.setAceIsSet(true);
                        msg = result;
            }
            else             if (e instanceof org.apache.airavata.model.error.AiravataSystemException) {
                        result.ase = (org.apache.airavata.model.error.AiravataSystemException) e;
                        result.setAseIsSet(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 
            {
              msgType = org.apache.thrift.protocol.TMessageType.EXCEPTION;
              msg = (org.apache.thrift.TBase)new org.apache.thrift.TApplicationException(org.apache.thrift.TApplicationException.INTERNAL_ERROR, e.getMessage());
            }
            try {
              fcall.sendResponse(fb,msg,msgType,seqid);
              return;
            } catch (Exception ex) {
              LOGGER.error("Exception writing to internal frame buffer", ex);
            }
            fb.close();
          }
        };
      }

      protected boolean isOneway() {
        return false;
      }

      public void start(I iface, registerWorkflow_args args, org.apache.thrift.async.AsyncMethodCallback<String> resultHandler) throws TException {
        iface.registerWorkflow(args.authzToken, args.gatewayId, args.workflow,resultHandler);
      }
    }

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

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

      public AsyncMethodCallback<Void> getResultHandler(final AsyncFrameBuffer fb, final int seqid) {
        final org.apache.thrift.AsyncProcessFunction fcall = this;
        return new AsyncMethodCallback<Void>() { 
          public void onComplete(Void o) {
            updateWorkflow_result result = new updateWorkflow_result();
            try {
              fcall.sendResponse(fb,result, org.apache.thrift.protocol.TMessageType.REPLY,seqid);
              return;
            } catch (Exception e) {
              LOGGER.error("Exception writing to internal frame buffer", e);
            }
            fb.close();
          }
          public void onError(Exception e) {
            byte msgType = org.apache.thrift.protocol.TMessageType.REPLY;
            org.apache.thrift.TBase msg;
            updateWorkflow_result result = new updateWorkflow_result();
            if (e instanceof org.apache.airavata.model.error.InvalidRequestException) {
                        result.ire = (org.apache.airavata.model.error.InvalidRequestException) e;
                        result.setIreIsSet(true);
                        msg = result;
            }
            else             if (e instanceof org.apache.airavata.model.error.AiravataClientException) {
                        result.ace = (org.apache.airavata.model.error.AiravataClientException) e;
                        result.setAceIsSet(true);
                        msg = result;
            }
            else             if (e instanceof org.apache.airavata.model.error.AiravataSystemException) {
                        result.ase = (org.apache.airavata.model.error.AiravataSystemException) e;
                        result.setAseIsSet(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 
            {
              msgType = org.apache.thrift.protocol.TMessageType.EXCEPTION;
              msg = (org.apache.thrift.TBase)new org.apache.thrift.TApplicationException(org.apache.thrift.TApplicationException.INTERNAL_ERROR, e.getMessage());
            }
            try {
              fcall.sendResponse(fb,msg,msgType,seqid);
              return;
            } catch (Exception ex) {
              LOGGER.error("Exception writing to internal frame buffer", ex);
            }
            fb.close();
          }
        };
      }

      protected boolean isOneway() {
        return false;
      }

      public void start(I iface, updateWorkflow_args args, org.apache.thrift.async.AsyncMethodCallback<Void> resultHandler) throws TException {
        iface.updateWorkflow(args.authzToken, args.workflowTemplateId, args.workflow,resultHandler);
      }
    }

    public static class getWorkflowTemplateId<I extends AsyncIface> extends org.apache.thrift.AsyncProcessFunction<I, getWorkflowTemplateId_args, String> {
      public getWorkflowTemplateId() {
        super("getWorkflowTemplateId");
      }

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

      public AsyncMethodCallback<String> getResultHandler(final AsyncFrameBuffer fb, final int seqid) {
        final org.apache.thrift.AsyncProcessFunction fcall = this;
        return new AsyncMethodCallback<String>() { 
          public void onComplete(String o) {
            getWorkflowTemplateId_result result = new getWorkflowTemplateId_result();
            result.success = o;
            try {
              fcall.sendResponse(fb,result, org.apache.thrift.protocol.TMessageType.REPLY,seqid);
              return;
            } catch (Exception e) {
              LOGGER.error("Exception writing to internal frame buffer", e);
            }
            fb.close();
          }
          public void onError(Exception e) {
            byte msgType = org.apache.thrift.protocol.TMessageType.REPLY;
            org.apache.thrift.TBase msg;
            getWorkflowTemplateId_result result = new getWorkflowTemplateId_result();
            if (e instanceof org.apache.airavata.model.error.InvalidRequestException) {
                        result.ire = (org.apache.airavata.model.error.InvalidRequestException) e;
                        result.setIreIsSet(true);
                        msg = result;
            }
            else             if (e instanceof org.apache.airavata.model.error.AiravataClientException) {
                        result.ace = (org.apache.airavata.model.error.AiravataClientException) e;
                        result.setAceIsSet(true);
                        msg = result;
            }
            else             if (e instanceof org.apache.airavata.model.error.AiravataSystemException) {
                        result.ase = (org.apache.airavata.model.error.AiravataSystemException) e;
                        result.setAseIsSet(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 
            {
              msgType = org.apache.thrift.protocol.TMessageType.EXCEPTION;
              msg = (org.apache.thrift.TBase)new org.apache.thrift.TApplicationException(org.apache.thrift.TApplicationException.INTERNAL_ERROR, e.getMessage());
            }
            try {
              fcall.sendResponse(fb,msg,msgType,seqid);
              return;
            } catch (Exception ex) {
              LOGGER.error("Exception writing to internal frame buffer", ex);
            }
            fb.close();
          }
        };
      }

      protected boolean isOneway() {
        return false;
      }

      public void start(I iface, getWorkflowTemplateId_args args, org.apache.thrift.async.AsyncMethodCallback<String> resultHandler) throws TException {
        iface.getWorkflowTemplateId(args.authzToken, args.workflowName,resultHandler);
      }
    }

    public static class isWorkflowExistWithName<I extends AsyncIface> extends org.apache.thrift.AsyncProcessFunction<I, isWorkflowExistWithName_args, Boolean> {
      public isWorkflowExistWithName() {
        super("isWorkflowExistWithName");
      }

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

      public AsyncMethodCallback<Boolean> getResultHandler(final AsyncFrameBuffer fb, final int seqid) {
        final org.apache.thrift.AsyncProcessFunction fcall = this;
        return new AsyncMethodCallback<Boolean>() { 
          public void onComplete(Boolean o) {
            isWorkflowExistWithName_result result = new isWorkflowExistWithName_result();
            result.success = o;
            result.setSuccessIsSet(true);
            try {
              fcall.sendResponse(fb,result, org.apache.thrift.protocol.TMessageType.REPLY,seqid);
              return;
            } catch (Exception e) {
              LOGGER.error("Exception writing to internal frame buffer", e);
            }
            fb.close();
          }
          public void onError(Exception e) {
            byte msgType = org.apache.thrift.protocol.TMessageType.REPLY;
            org.apache.thrift.TBase msg;
            isWorkflowExistWithName_result result = new isWorkflowExistWithName_result();
            if (e instanceof org.apache.airavata.model.error.InvalidRequestException) {
                        result.ire = (org.apache.airavata.model.error.InvalidRequestException) e;
                        result.setIreIsSet(true);
                        msg = result;
            }
            else             if (e instanceof org.apache.airavata.model.error.AiravataClientException) {
                        result.ace = (org.apache.airavata.model.error.AiravataClientException) e;
                        result.setAceIsSet(true);
                        msg = result;
            }
            else             if (e instanceof org.apache.airavata.model.error.AiravataSystemException) {
                        result.ase = (org.apache.airavata.model.error.AiravataSystemException) e;
                        result.setAseIsSet(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 
            {
              msgType = org.apache.thrift.protocol.TMessageType.EXCEPTION;
              msg = (org.apache.thrift.TBase)new org.apache.thrift.TApplicationException(org.apache.thrift.TApplicationException.INTERNAL_ERROR, e.getMessage());
            }
            try {
              fcall.sendResponse(fb,msg,msgType,seqid);
              return;
            } catch (Exception ex) {
              LOGGER.error("Exception writing to internal frame buffer", ex);
            }
            fb.close();
          }
        };
      }

      protected boolean isOneway() {
        return false;
      }

      public void start(I iface, isWorkflowExistWithName_args args, org.apache.thrift.async.AsyncMethodCallback<Boolean> resultHandler) throws TException {
        iface.isWorkflowExistWithName(args.authzToken, args.workflowName,resultHandler);
      }
    }

  }

  public static class getAPIVersion_args implements org.apache.thrift.TBase<getAPIVersion_args, getAPIVersion_args._Fields>, java.io.Serializable, Cloneable, Comparable<getAPIVersion_args>   {
    private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("getAPIVersion_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 Map<Class<? extends IScheme>, SchemeFactory> schemes = new HashMap<Class<? extends IScheme>, SchemeFactory>();
    static {
      schemes.put(StandardScheme.class, new getAPIVersion_argsStandardSchemeFactory());
      schemes.put(TupleScheme.class, new getAPIVersion_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 Map<String, _Fields> byName = new HashMap<String, _Fields>();

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

      /**
       * Find the _Fields constant that matches fieldId, or null if its not found.
       */
      public static _Fields findByThriftId(int fieldId) {
        switch(fieldId) {
          case 1: // 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 IllegalArgumentException("Field " + fieldId + " doesn't exist!");
        return fields;
      }

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

      private final short _thriftId;
      private final String _fieldName;

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

      public short getThriftFieldId() {
        return _thriftId;
      }

      public String getFieldName() {
        return _fieldName;
      }
    }

    // isset id assignments
    public static final Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
    static {
      Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new EnumMap<_Fields, org.apache.thrift.meta_data.FieldMetaData>(_Fields.class);
      tmpMap.put(_Fields.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 = Collections.unmodifiableMap(tmpMap);
      org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(getAPIVersion_args.class, metaDataMap);
    }

    public getAPIVersion_args() {
    }

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

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

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

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

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

    public getAPIVersion_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, Object value) {
      switch (field) {
      case AUTHZ_TOKEN:
        if (value == null) {
          unsetAuthzToken();
        } else {
          setAuthzToken((org.apache.airavata.model.security.AuthzToken)value);
        }
        break;

      }
    }

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

      }
      throw new IllegalStateException();
    }

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

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

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

    public boolean equals(getAPIVersion_args that) {
      if (that == null)
        return false;

      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() {
      List<Object> list = new ArrayList<Object>();

      boolean present_authzToken = true && (isSetAuthzToken());
      list.add(present_authzToken);
      if (present_authzToken)
        list.add(authzToken);

      return list.hashCode();
    }

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

      int lastComparison = 0;

      lastComparison = 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 {
      schemes.get(iprot.getScheme()).getScheme().read(iprot, this);
    }

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

    @Override
    public String toString() {
      StringBuilder sb = new StringBuilder("getAPIVersion_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, 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 getAPIVersion_argsStandardSchemeFactory implements SchemeFactory {
      public getAPIVersion_argsStandardScheme getScheme() {
        return new getAPIVersion_argsStandardScheme();
      }
    }

    private static class getAPIVersion_argsStandardScheme extends StandardScheme<getAPIVersion_args> {

      public void read(org.apache.thrift.protocol.TProtocol iprot, getAPIVersion_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, getAPIVersion_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 getAPIVersion_argsTupleSchemeFactory implements SchemeFactory {
      public getAPIVersion_argsTupleScheme getScheme() {
        return new getAPIVersion_argsTupleScheme();
      }
    }

    private static class getAPIVersion_argsTupleScheme extends TupleScheme<getAPIVersion_args> {

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

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

  }

  public static class getAPIVersion_result implements org.apache.thrift.TBase<getAPIVersion_result, getAPIVersion_result._Fields>, java.io.Serializable, Cloneable, Comparable<getAPIVersion_result>   {
    private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("getAPIVersion_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 IRE_FIELD_DESC = new org.apache.thrift.protocol.TField("ire", org.apache.thrift.protocol.TType.STRUCT, (short)1);
    private static final org.apache.thrift.protocol.TField ACE_FIELD_DESC = new org.apache.thrift.protocol.TField("ace", org.apache.thrift.protocol.TType.STRUCT, (short)2);
    private static final org.apache.thrift.protocol.TField ASE_FIELD_DESC = new org.apache.thrift.protocol.TField("ase", org.apache.thrift.protocol.TType.STRUCT, (short)3);
    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)4);

    private static final Map<Class<? extends IScheme>, SchemeFactory> schemes = new HashMap<Class<? extends IScheme>, SchemeFactory>();
    static {
      schemes.put(StandardScheme.class, new getAPIVersion_resultStandardSchemeFactory());
      schemes.put(TupleScheme.class, new getAPIVersion_resultTupleSchemeFactory());
    }

    public String success; // required
    public org.apache.airavata.model.error.InvalidRequestException ire; // required
    public org.apache.airavata.model.error.AiravataClientException ace; // required
    public org.apache.airavata.model.error.AiravataSystemException ase; // 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"),
      IRE((short)1, "ire"),
      ACE((short)2, "ace"),
      ASE((short)3, "ase"),
      AE((short)4, "ae");

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

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

      /**
       * Find the _Fields constant that matches fieldId, or null if its not found.
       */
      public static _Fields findByThriftId(int fieldId) {
        switch(fieldId) {
          case 0: // SUCCESS
            return SUCCESS;
          case 1: // IRE
            return IRE;
          case 2: // ACE
            return ACE;
          case 3: // ASE
            return ASE;
          case 4: // 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 IllegalArgumentException("Field " + fieldId + " doesn't exist!");
        return fields;
      }

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

      private final short _thriftId;
      private final String _fieldName;

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

      public short getThriftFieldId() {
        return _thriftId;
      }

      public String getFieldName() {
        return _fieldName;
      }
    }

    // isset id assignments
    public static final Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
    static {
      Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new EnumMap<_Fields, org.apache.thrift.meta_data.FieldMetaData>(_Fields.class);
      tmpMap.put(_Fields.SUCCESS, new org.apache.thrift.meta_data.FieldMetaData("success", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING)));
      tmpMap.put(_Fields.IRE, new org.apache.thrift.meta_data.FieldMetaData("ire", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRUCT)));
      tmpMap.put(_Fields.ACE, new org.apache.thrift.meta_data.FieldMetaData("ace", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRUCT)));
      tmpMap.put(_Fields.ASE, new org.apache.thrift.meta_data.FieldMetaData("ase", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRUCT)));
      tmpMap.put(_Fields.AE, new org.apache.thrift.meta_data.FieldMetaData("ae", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRUCT)));
      metaDataMap = Collections.unmodifiableMap(tmpMap);
      org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(getAPIVersion_result.class, metaDataMap);
    }

    public getAPIVersion_result() {
    }

    public getAPIVersion_result(
      String success,
      org.apache.airavata.model.error.InvalidRequestException ire,
      org.apache.airavata.model.error.AiravataClientException ace,
      org.apache.airavata.model.error.AiravataSystemException ase,
      org.apache.airavata.model.error.AuthorizationException ae)
    {
      this();
      this.success = success;
      this.ire = ire;
      this.ace = ace;
      this.ase = ase;
      this.ae = ae;
    }

    /**
     * Performs a deep copy on <i>other</i>.
     */
    public getAPIVersion_result(getAPIVersion_result other) {
      if (other.isSetSuccess()) {
        this.success = other.success;
      }
      if (other.isSetIre()) {
        this.ire = new org.apache.airavata.model.error.InvalidRequestException(other.ire);
      }
      if (other.isSetAce()) {
        this.ace = new org.apache.airavata.model.error.AiravataClientException(other.ace);
      }
      if (other.isSetAse()) {
        this.ase = new org.apache.airavata.model.error.AiravataSystemException(other.ase);
      }
      if (other.isSetAe()) {
        this.ae = new org.apache.airavata.model.error.AuthorizationException(other.ae);
      }
    }

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

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

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

    public getAPIVersion_result setSuccess(String success) {
      this.success = success;
      return this;
    }

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

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

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

    public org.apache.airavata.model.error.InvalidRequestException getIre() {
      return this.ire;
    }

    public getAPIVersion_result setIre(org.apache.airavata.model.error.InvalidRequestException ire) {
      this.ire = ire;
      return this;
    }

    public void unsetIre() {
      this.ire = null;
    }

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

    public void setIreIsSet(boolean value) {
      if (!value) {
        this.ire = null;
      }
    }

    public org.apache.airavata.model.error.AiravataClientException getAce() {
      return this.ace;
    }

    public getAPIVersion_result setAce(org.apache.airavata.model.error.AiravataClientException ace) {
      this.ace = ace;
      return this;
    }

    public void unsetAce() {
      this.ace = null;
    }

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

    public void setAceIsSet(boolean value) {
      if (!value) {
        this.ace = null;
      }
    }

    public org.apache.airavata.model.error.AiravataSystemException getAse() {
      return this.ase;
    }

    public getAPIVersion_result setAse(org.apache.airavata.model.error.AiravataSystemException ase) {
      this.ase = ase;
      return this;
    }

    public void unsetAse() {
      this.ase = null;
    }

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

    public void setAseIsSet(boolean value) {
      if (!value) {
        this.ase = null;
      }
    }

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

    public getAPIVersion_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, Object value) {
      switch (field) {
      case SUCCESS:
        if (value == null) {
          unsetSuccess();
        } else {
          setSuccess((String)value);
        }
        break;

      case IRE:
        if (value == null) {
          unsetIre();
        } else {
          setIre((org.apache.airavata.model.error.InvalidRequestException)value);
        }
        break;

      case ACE:
        if (value == null) {
          unsetAce();
        } else {
          setAce((org.apache.airavata.model.error.AiravataClientException)value);
        }
        break;

      case ASE:
        if (value == null) {
          unsetAse();
        } else {
          setAse((org.apache.airavata.model.error.AiravataSystemException)value);
        }
        break;

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

      }
    }

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

      case IRE:
        return getIre();

      case ACE:
        return getAce();

      case ASE:
        return getAse();

      case AE:
        return getAe();

      }
      throw new IllegalStateException();
    }

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

      switch (field) {
      case SUCCESS:
        return isSetSuccess();
      case IRE:
        return isSetIre();
      case ACE:
        return isSetAce();
      case ASE:
        return isSetAse();
      case AE:
        return isSetAe();
      }
      throw new IllegalStateException();
    }

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

    public boolean equals(getAPIVersion_result that) {
      if (that == null)
        return false;

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

      boolean this_present_ire = true && this.isSetIre();
      boolean that_present_ire = true && that.isSetIre();
      if (this_present_ire || that_present_ire) {
        if (!(this_present_ire && that_present_ire))
          return false;
        if (!this.ire.equals(that.ire))
          return false;
      }

      boolean this_present_ace = true && this.isSetAce();
      boolean that_present_ace = true && that.isSetAce();
      if (this_present_ace || that_present_ace) {
        if (!(this_present_ace && that_present_ace))
          return false;
        if (!this.ace.equals(that.ace))
          return false;
      }

      boolean this_present_ase = true && this.isSetAse();
      boolean that_present_ase = true && that.isSetAse();
      if (this_present_ase || that_present_ase) {
        if (!(this_present_ase && that_present_ase))
          return false;
        if (!this.ase.equals(that.ase))
          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() {
      List<Object> list = new ArrayList<Object>();

      boolean present_success = true && (isSetSuccess());
      list.add(present_success);
      if (present_success)
        list.add(success);

      boolean present_ire = true && (isSetIre());
      list.add(present_ire);
      if (present_ire)
        list.add(ire);

      boolean present_ace = true && (isSetAce());
      list.add(present_ace);
      if (present_ace)
        list.add(ace);

      boolean present_ase = true && (isSetAse());
      list.add(present_ase);
      if (present_ase)
        list.add(ase);

      boolean present_ae = true && (isSetAe());
      list.add(present_ae);
      if (present_ae)
        list.add(ae);

      return list.hashCode();
    }

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

      int lastComparison = 0;

      lastComparison = Boolean.valueOf(isSetSuccess()).compareTo(other.isSetSuccess());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetSuccess()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.success, other.success);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = Boolean.valueOf(isSetIre()).compareTo(other.isSetIre());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetIre()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.ire, other.ire);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = Boolean.valueOf(isSetAce()).compareTo(other.isSetAce());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetAce()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.ace, other.ace);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = Boolean.valueOf(isSetAse()).compareTo(other.isSetAse());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetAse()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.ase, other.ase);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = 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 {
      schemes.get(iprot.getScheme()).getScheme().read(iprot, this);
    }

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

    @Override
    public String toString() {
      StringBuilder sb = new StringBuilder("getAPIVersion_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("ire:");
      if (this.ire == null) {
        sb.append("null");
      } else {
        sb.append(this.ire);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("ace:");
      if (this.ace == null) {
        sb.append("null");
      } else {
        sb.append(this.ace);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("ase:");
      if (this.ase == null) {
        sb.append("null");
      } else {
        sb.append(this.ase);
      }
      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, 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 getAPIVersion_resultStandardSchemeFactory implements SchemeFactory {
      public getAPIVersion_resultStandardScheme getScheme() {
        return new getAPIVersion_resultStandardScheme();
      }
    }

    private static class getAPIVersion_resultStandardScheme extends StandardScheme<getAPIVersion_result> {

      public void read(org.apache.thrift.protocol.TProtocol iprot, getAPIVersion_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: // IRE
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.ire = new org.apache.airavata.model.error.InvalidRequestException();
                struct.ire.read(iprot);
                struct.setIreIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 2: // ACE
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.ace = new org.apache.airavata.model.error.AiravataClientException();
                struct.ace.read(iprot);
                struct.setAceIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 3: // ASE
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.ase = new org.apache.airavata.model.error.AiravataSystemException();
                struct.ase.read(iprot);
                struct.setAseIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 4: // 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, getAPIVersion_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.ire != null) {
          oprot.writeFieldBegin(IRE_FIELD_DESC);
          struct.ire.write(oprot);
          oprot.writeFieldEnd();
        }
        if (struct.ace != null) {
          oprot.writeFieldBegin(ACE_FIELD_DESC);
          struct.ace.write(oprot);
          oprot.writeFieldEnd();
        }
        if (struct.ase != null) {
          oprot.writeFieldBegin(ASE_FIELD_DESC);
          struct.ase.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 getAPIVersion_resultTupleSchemeFactory implements SchemeFactory {
      public getAPIVersion_resultTupleScheme getScheme() {
        return new getAPIVersion_resultTupleScheme();
      }
    }

    private static class getAPIVersion_resultTupleScheme extends TupleScheme<getAPIVersion_result> {

      @Override
      public void write(org.apache.thrift.protocol.TProtocol prot, getAPIVersion_result struct) throws org.apache.thrift.TException {
        TTupleProtocol oprot = (TTupleProtocol) prot;
        BitSet optionals = new BitSet();
        if (struct.isSetSuccess()) {
          optionals.set(0);
        }
        if (struct.isSetIre()) {
          optionals.set(1);
        }
        if (struct.isSetAce()) {
          optionals.set(2);
        }
        if (struct.isSetAse()) {
          optionals.set(3);
        }
        if (struct.isSetAe()) {
          optionals.set(4);
        }
        oprot.writeBitSet(optionals, 5);
        if (struct.isSetSuccess()) {
          oprot.writeString(struct.success);
        }
        if (struct.isSetIre()) {
          struct.ire.write(oprot);
        }
        if (struct.isSetAce()) {
          struct.ace.write(oprot);
        }
        if (struct.isSetAse()) {
          struct.ase.write(oprot);
        }
        if (struct.isSetAe()) {
          struct.ae.write(oprot);
        }
      }

      @Override
      public void read(org.apache.thrift.protocol.TProtocol prot, getAPIVersion_result struct) throws org.apache.thrift.TException {
        TTupleProtocol iprot = (TTupleProtocol) prot;
        BitSet incoming = iprot.readBitSet(5);
        if (incoming.get(0)) {
          struct.success = iprot.readString();
          struct.setSuccessIsSet(true);
        }
        if (incoming.get(1)) {
          struct.ire = new org.apache.airavata.model.error.InvalidRequestException();
          struct.ire.read(iprot);
          struct.setIreIsSet(true);
        }
        if (incoming.get(2)) {
          struct.ace = new org.apache.airavata.model.error.AiravataClientException();
          struct.ace.read(iprot);
          struct.setAceIsSet(true);
        }
        if (incoming.get(3)) {
          struct.ase = new org.apache.airavata.model.error.AiravataSystemException();
          struct.ase.read(iprot);
          struct.setAseIsSet(true);
        }
        if (incoming.get(4)) {
          struct.ae = new org.apache.airavata.model.error.AuthorizationException();
          struct.ae.read(iprot);
          struct.setAeIsSet(true);
        }
      }
    }

  }

  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 Map<Class<? extends IScheme>, SchemeFactory> schemes = new HashMap<Class<? extends IScheme>, SchemeFactory>();
    static {
      schemes.put(StandardScheme.class, new addGateway_argsStandardSchemeFactory());
      schemes.put(TupleScheme.class, 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 Map<String, _Fields> byName = new HashMap<String, _Fields>();

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

      /**
       * Find the _Fields constant that matches fieldId, or null if its not found.
       */
      public static _Fields findByThriftId(int fieldId) {
        switch(fieldId) {
          case 1: // 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 IllegalArgumentException("Field " + fieldId + " doesn't exist!");
        return fields;
      }

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

      private final short _thriftId;
      private final String _fieldName;

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

      public short getThriftFieldId() {
        return _thriftId;
      }

      public String getFieldName() {
        return _fieldName;
      }
    }

    // isset id assignments
    public static final Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
    static {
      Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new EnumMap<_Fields, org.apache.thrift.meta_data.FieldMetaData>(_Fields.class);
      tmpMap.put(_Fields.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 = 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, 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 Object getFieldValue(_Fields field) {
      switch (field) {
      case AUTHZ_TOKEN:
        return getAuthzToken();

      case GATEWAY:
        return getGateway();

      }
      throw new IllegalStateException();
    }

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

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

    @Override
    public boolean equals(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;

      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() {
      List<Object> list = new ArrayList<Object>();

      boolean present_authzToken = true && (isSetAuthzToken());
      list.add(present_authzToken);
      if (present_authzToken)
        list.add(authzToken);

      boolean present_gateway = true && (isSetGateway());
      list.add(present_gateway);
      if (present_gateway)
        list.add(gateway);

      return list.hashCode();
    }

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

      int lastComparison = 0;

      lastComparison = 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 = 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 {
      schemes.get(iprot.getScheme()).getScheme().read(iprot, this);
    }

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

    @Override
    public String toString() {
      StringBuilder sb = new StringBuilder("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, 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 SchemeFactory {
      public addGateway_argsStandardScheme getScheme() {
        return new addGateway_argsStandardScheme();
      }
    }

    private static class addGateway_argsStandardScheme extends 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 SchemeFactory {
      public addGateway_argsTupleScheme getScheme() {
        return new addGateway_argsTupleScheme();
      }
    }

    private static class addGateway_argsTupleScheme extends TupleScheme<addGateway_args> {

      @Override
      public void write(org.apache.thrift.protocol.TProtocol prot, addGateway_args struct) throws org.apache.thrift.TException {
        TTupleProtocol oprot = (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 {
        TTupleProtocol iprot = (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);
      }
    }

  }

  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 IRE_FIELD_DESC = new org.apache.thrift.protocol.TField("ire", org.apache.thrift.protocol.TType.STRUCT, (short)1);
    private static final org.apache.thrift.protocol.TField ACE_FIELD_DESC = new org.apache.thrift.protocol.TField("ace", org.apache.thrift.protocol.TType.STRUCT, (short)2);
    private static final org.apache.thrift.protocol.TField ASE_FIELD_DESC = new org.apache.thrift.protocol.TField("ase", org.apache.thrift.protocol.TType.STRUCT, (short)3);
    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)4);

    private static final Map<Class<? extends IScheme>, SchemeFactory> schemes = new HashMap<Class<? extends IScheme>, SchemeFactory>();
    static {
      schemes.put(StandardScheme.class, new addGateway_resultStandardSchemeFactory());
      schemes.put(TupleScheme.class, new addGateway_resultTupleSchemeFactory());
    }

    public String success; // required
    public org.apache.airavata.model.error.InvalidRequestException ire; // required
    public org.apache.airavata.model.error.AiravataClientException ace; // required
    public org.apache.airavata.model.error.AiravataSystemException ase; // 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"),
      IRE((short)1, "ire"),
      ACE((short)2, "ace"),
      ASE((short)3, "ase"),
      AE((short)4, "ae");

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

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

      /**
       * Find the _Fields constant that matches fieldId, or null if its not found.
       */
      public static _Fields findByThriftId(int fieldId) {
        switch(fieldId) {
          case 0: // SUCCESS
            return SUCCESS;
          case 1: // IRE
            return IRE;
          case 2: // ACE
            return ACE;
          case 3: // ASE
            return ASE;
          case 4: // 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 IllegalArgumentException("Field " + fieldId + " doesn't exist!");
        return fields;
      }

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

      private final short _thriftId;
      private final String _fieldName;

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

      public short getThriftFieldId() {
        return _thriftId;
      }

      public String getFieldName() {
        return _fieldName;
      }
    }

    // isset id assignments
    public static final Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
    static {
      Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new EnumMap<_Fields, org.apache.thrift.meta_data.FieldMetaData>(_Fields.class);
      tmpMap.put(_Fields.SUCCESS, new org.apache.thrift.meta_data.FieldMetaData("success", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING)));
      tmpMap.put(_Fields.IRE, new org.apache.thrift.meta_data.FieldMetaData("ire", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRUCT)));
      tmpMap.put(_Fields.ACE, new org.apache.thrift.meta_data.FieldMetaData("ace", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRUCT)));
      tmpMap.put(_Fields.ASE, new org.apache.thrift.meta_data.FieldMetaData("ase", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRUCT)));
      tmpMap.put(_Fields.AE, new org.apache.thrift.meta_data.FieldMetaData("ae", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRUCT)));
      metaDataMap = Collections.unmodifiableMap(tmpMap);
      org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(addGateway_result.class, metaDataMap);
    }

    public addGateway_result() {
    }

    public addGateway_result(
      String success,
      org.apache.airavata.model.error.InvalidRequestException ire,
      org.apache.airavata.model.error.AiravataClientException ace,
      org.apache.airavata.model.error.AiravataSystemException ase,
      org.apache.airavata.model.error.AuthorizationException ae)
    {
      this();
      this.success = success;
      this.ire = ire;
      this.ace = ace;
      this.ase = ase;
      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.isSetIre()) {
        this.ire = new org.apache.airavata.model.error.InvalidRequestException(other.ire);
      }
      if (other.isSetAce()) {
        this.ace = new org.apache.airavata.model.error.AiravataClientException(other.ace);
      }
      if (other.isSetAse()) {
        this.ase = new org.apache.airavata.model.error.AiravataSystemException(other.ase);
      }
      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.ire = null;
      this.ace = null;
      this.ase = null;
      this.ae = null;
    }

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

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

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

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

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

    public org.apache.airavata.model.error.InvalidRequestException getIre() {
      return this.ire;
    }

    public addGateway_result setIre(org.apache.airavata.model.error.InvalidRequestException ire) {
      this.ire = ire;
      return this;
    }

    public void unsetIre() {
      this.ire = null;
    }

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

    public void setIreIsSet(boolean value) {
      if (!value) {
        this.ire = null;
      }
    }

    public org.apache.airavata.model.error.AiravataClientException getAce() {
      return this.ace;
    }

    public addGateway_result setAce(org.apache.airavata.model.error.AiravataClientException ace) {
      this.ace = ace;
      return this;
    }

    public void unsetAce() {
      this.ace = null;
    }

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

    public void setAceIsSet(boolean value) {
      if (!value) {
        this.ace = null;
      }
    }

    public org.apache.airavata.model.error.AiravataSystemException getAse() {
      return this.ase;
    }

    public addGateway_result setAse(org.apache.airavata.model.error.AiravataSystemException ase) {
      this.ase = ase;
      return this;
    }

    public void unsetAse() {
      this.ase = null;
    }

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

    public void setAseIsSet(boolean value) {
      if (!value) {
        this.ase = 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, Object value) {
      switch (field) {
      case SUCCESS:
        if (value == null) {
          unsetSuccess();
        } else {
          setSuccess((String)value);
        }
        break;

      case IRE:
        if (value == null) {
          unsetIre();
        } else {
          setIre((org.apache.airavata.model.error.InvalidRequestException)value);
        }
        break;

      case ACE:
        if (value == null) {
          unsetAce();
        } else {
          setAce((org.apache.airavata.model.error.AiravataClientException)value);
        }
        break;

      case ASE:
        if (value == null) {
          unsetAse();
        } else {
          setAse((org.apache.airavata.model.error.AiravataSystemException)value);
        }
        break;

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

      }
    }

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

      case IRE:
        return getIre();

      case ACE:
        return getAce();

      case ASE:
        return getAse();

      case AE:
        return getAe();

      }
      throw new IllegalStateException();
    }

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

      switch (field) {
      case SUCCESS:
        return isSetSuccess();
      case IRE:
        return isSetIre();
      case ACE:
        return isSetAce();
      case ASE:
        return isSetAse();
      case AE:
        return isSetAe();
      }
      throw new IllegalStateException();
    }

    @Override
    public boolean equals(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;

      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_ire = true && this.isSetIre();
      boolean that_present_ire = true && that.isSetIre();
      if (this_present_ire || that_present_ire) {
        if (!(this_present_ire && that_present_ire))
          return false;
        if (!this.ire.equals(that.ire))
          return false;
      }

      boolean this_present_ace = true && this.isSetAce();
      boolean that_present_ace = true && that.isSetAce();
      if (this_present_ace || that_present_ace) {
        if (!(this_present_ace && that_present_ace))
          return false;
        if (!this.ace.equals(that.ace))
          return false;
      }

      boolean this_present_ase = true && this.isSetAse();
      boolean that_present_ase = true && that.isSetAse();
      if (this_present_ase || that_present_ase) {
        if (!(this_present_ase && that_present_ase))
          return false;
        if (!this.ase.equals(that.ase))
          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() {
      List<Object> list = new ArrayList<Object>();

      boolean present_success = true && (isSetSuccess());
      list.add(present_success);
      if (present_success)
        list.add(success);

      boolean present_ire = true && (isSetIre());
      list.add(present_ire);
      if (present_ire)
        list.add(ire);

      boolean present_ace = true && (isSetAce());
      list.add(present_ace);
      if (present_ace)
        list.add(ace);

      boolean present_ase = true && (isSetAse());
      list.add(present_ase);
      if (present_ase)
        list.add(ase);

      boolean present_ae = true && (isSetAe());
      list.add(present_ae);
      if (present_ae)
        list.add(ae);

      return list.hashCode();
    }

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

      int lastComparison = 0;

      lastComparison = Boolean.valueOf(isSetSuccess()).compareTo(other.isSetSuccess());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetSuccess()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.success, other.success);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = Boolean.valueOf(isSetIre()).compareTo(other.isSetIre());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetIre()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.ire, other.ire);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = Boolean.valueOf(isSetAce()).compareTo(other.isSetAce());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetAce()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.ace, other.ace);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = Boolean.valueOf(isSetAse()).compareTo(other.isSetAse());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetAse()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.ase, other.ase);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = 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 {
      schemes.get(iprot.getScheme()).getScheme().read(iprot, this);
    }

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

    @Override
    public String toString() {
      StringBuilder sb = new StringBuilder("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("ire:");
      if (this.ire == null) {
        sb.append("null");
      } else {
        sb.append(this.ire);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("ace:");
      if (this.ace == null) {
        sb.append("null");
      } else {
        sb.append(this.ace);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("ase:");
      if (this.ase == null) {
        sb.append("null");
      } else {
        sb.append(this.ase);
      }
      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, 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 SchemeFactory {
      public addGateway_resultStandardScheme getScheme() {
        return new addGateway_resultStandardScheme();
      }
    }

    private static class addGateway_resultStandardScheme extends 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: // IRE
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.ire = new org.apache.airavata.model.error.InvalidRequestException();
                struct.ire.read(iprot);
                struct.setIreIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 2: // ACE
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.ace = new org.apache.airavata.model.error.AiravataClientException();
                struct.ace.read(iprot);
                struct.setAceIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 3: // ASE
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.ase = new org.apache.airavata.model.error.AiravataSystemException();
                struct.ase.read(iprot);
                struct.setAseIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 4: // 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.ire != null) {
          oprot.writeFieldBegin(IRE_FIELD_DESC);
          struct.ire.write(oprot);
          oprot.writeFieldEnd();
        }
        if (struct.ace != null) {
          oprot.writeFieldBegin(ACE_FIELD_DESC);
          struct.ace.write(oprot);
          oprot.writeFieldEnd();
        }
        if (struct.ase != null) {
          oprot.writeFieldBegin(ASE_FIELD_DESC);
          struct.ase.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 SchemeFactory {
      public addGateway_resultTupleScheme getScheme() {
        return new addGateway_resultTupleScheme();
      }
    }

    private static class addGateway_resultTupleScheme extends TupleScheme<addGateway_result> {

      @Override
      public void write(org.apache.thrift.protocol.TProtocol prot, addGateway_result struct) throws org.apache.thrift.TException {
        TTupleProtocol oprot = (TTupleProtocol) prot;
        BitSet optionals = new BitSet();
        if (struct.isSetSuccess()) {
          optionals.set(0);
        }
        if (struct.isSetIre()) {
          optionals.set(1);
        }
        if (struct.isSetAce()) {
          optionals.set(2);
        }
        if (struct.isSetAse()) {
          optionals.set(3);
        }
        if (struct.isSetAe()) {
          optionals.set(4);
        }
        oprot.writeBitSet(optionals, 5);
        if (struct.isSetSuccess()) {
          oprot.writeString(struct.success);
        }
        if (struct.isSetIre()) {
          struct.ire.write(oprot);
        }
        if (struct.isSetAce()) {
          struct.ace.write(oprot);
        }
        if (struct.isSetAse()) {
          struct.ase.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 {
        TTupleProtocol iprot = (TTupleProtocol) prot;
        BitSet incoming = iprot.readBitSet(5);
        if (incoming.get(0)) {
          struct.success = iprot.readString();
          struct.setSuccessIsSet(true);
        }
        if (incoming.get(1)) {
          struct.ire = new org.apache.airavata.model.error.InvalidRequestException();
          struct.ire.read(iprot);
          struct.setIreIsSet(true);
        }
        if (incoming.get(2)) {
          struct.ace = new org.apache.airavata.model.error.AiravataClientException();
          struct.ace.read(iprot);
          struct.setAceIsSet(true);
        }
        if (incoming.get(3)) {
          struct.ase = new org.apache.airavata.model.error.AiravataSystemException();
          struct.ase.read(iprot);
          struct.setAseIsSet(true);
        }
        if (incoming.get(4)) {
          struct.ae = new org.apache.airavata.model.error.AuthorizationException();
          struct.ae.read(iprot);
          struct.setAeIsSet(true);
        }
      }
    }

  }

  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 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.protocol.TField UPDATED_GATEWAY_FIELD_DESC = new org.apache.thrift.protocol.TField("updatedGateway", org.apache.thrift.protocol.TType.STRUCT, (short)3);

    private static final Map<Class<? extends IScheme>, SchemeFactory> schemes = new HashMap<Class<? extends IScheme>, SchemeFactory>();
    static {
      schemes.put(StandardScheme.class, new updateGateway_argsStandardSchemeFactory());
      schemes.put(TupleScheme.class, new updateGateway_argsTupleSchemeFactory());
    }

    public org.apache.airavata.model.security.AuthzToken authzToken; // required
    public String gatewayId; // 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"),
      GATEWAY_ID((short)2, "gatewayId"),
      UPDATED_GATEWAY((short)3, "updatedGateway");

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

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

      /**
       * Find the _Fields constant that matches fieldId, or null if its not found.
       */
      public static _Fields findByThriftId(int fieldId) {
        switch(fieldId) {
          case 1: // AUTHZ_TOKEN
            return AUTHZ_TOKEN;
          case 2: // GATEWAY_ID
            return GATEWAY_ID;
          case 3: // 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 IllegalArgumentException("Field " + fieldId + " doesn't exist!");
        return fields;
      }

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

      private final short _thriftId;
      private final String _fieldName;

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

      public short getThriftFieldId() {
        return _thriftId;
      }

      public String getFieldName() {
        return _fieldName;
      }
    }

    // isset id assignments
    public static final Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
    static {
      Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new EnumMap<_Fields, org.apache.thrift.meta_data.FieldMetaData>(_Fields.class);
      tmpMap.put(_Fields.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)));
      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 = 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,
      String gatewayId,
      org.apache.airavata.model.workspace.Gateway updatedGateway)
    {
      this();
      this.authzToken = authzToken;
      this.gatewayId = gatewayId;
      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.isSetGatewayId()) {
        this.gatewayId = other.gatewayId;
      }
      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.gatewayId = 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 String getGatewayId() {
      return this.gatewayId;
    }

    public updateGateway_args setGatewayId(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 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, 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((String)value);
        }
        break;

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

      }
    }

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

      case GATEWAY_ID:
        return getGatewayId();

      case UPDATED_GATEWAY:
        return getUpdatedGateway();

      }
      throw new IllegalStateException();
    }

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

      switch (field) {
      case AUTHZ_TOKEN:
        return isSetAuthzToken();
      case GATEWAY_ID:
        return isSetGatewayId();
      case UPDATED_GATEWAY:
        return isSetUpdatedGateway();
      }
      throw new IllegalStateException();
    }

    @Override
    public boolean equals(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;

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

      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() {
      List<Object> list = new ArrayList<Object>();

      boolean present_authzToken = true && (isSetAuthzToken());
      list.add(present_authzToken);
      if (present_authzToken)
        list.add(authzToken);

      boolean present_gatewayId = true && (isSetGatewayId());
      list.add(present_gatewayId);
      if (present_gatewayId)
        list.add(gatewayId);

      boolean present_updatedGateway = true && (isSetUpdatedGateway());
      list.add(present_updatedGateway);
      if (present_updatedGateway)
        list.add(updatedGateway);

      return list.hashCode();
    }

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

      int lastComparison = 0;

      lastComparison = 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 = 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;
        }
      }
      lastComparison = 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 {
      schemes.get(iprot.getScheme()).getScheme().read(iprot, this);
    }

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

    @Override
    public String toString() {
      StringBuilder sb = new StringBuilder("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("gatewayId:");
      if (this.gatewayId == null) {
        sb.append("null");
      } else {
        sb.append(this.gatewayId);
      }
      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 (gatewayId == null) {
        throw new org.apache.thrift.protocol.TProtocolException("Required field 'gatewayId' 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, 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 SchemeFactory {
      public updateGateway_argsStandardScheme getScheme() {
        return new updateGateway_argsStandardScheme();
      }
    }

    private static class updateGateway_argsStandardScheme extends 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: // 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;
            case 3: // 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.gatewayId != null) {
          oprot.writeFieldBegin(GATEWAY_ID_FIELD_DESC);
          oprot.writeString(struct.gatewayId);
          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 SchemeFactory {
      public updateGateway_argsTupleScheme getScheme() {
        return new updateGateway_argsTupleScheme();
      }
    }

    private static class updateGateway_argsTupleScheme extends TupleScheme<updateGateway_args> {

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

      @Override
      public void read(org.apache.thrift.protocol.TProtocol prot, updateGateway_args struct) throws org.apache.thrift.TException {
        TTupleProtocol iprot = (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);
        struct.updatedGateway = new org.apache.airavata.model.workspace.Gateway();
        struct.updatedGateway.read(iprot);
        struct.setUpdatedGatewayIsSet(true);
      }
    }

  }

  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 IRE_FIELD_DESC = new org.apache.thrift.protocol.TField("ire", org.apache.thrift.protocol.TType.STRUCT, (short)1);
    private static final org.apache.thrift.protocol.TField ACE_FIELD_DESC = new org.apache.thrift.protocol.TField("ace", org.apache.thrift.protocol.TType.STRUCT, (short)2);
    private static final org.apache.thrift.protocol.TField ASE_FIELD_DESC = new org.apache.thrift.protocol.TField("ase", org.apache.thrift.protocol.TType.STRUCT, (short)3);
    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)4);

    private static final Map<Class<? extends IScheme>, SchemeFactory> schemes = new HashMap<Class<? extends IScheme>, SchemeFactory>();
    static {
      schemes.put(StandardScheme.class, new updateGateway_resultStandardSchemeFactory());
      schemes.put(TupleScheme.class, new updateGateway_resultTupleSchemeFactory());
    }

    public org.apache.airavata.model.error.InvalidRequestException ire; // required
    public org.apache.airavata.model.error.AiravataClientException ace; // required
    public org.apache.airavata.model.error.AiravataSystemException ase; // 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 {
      IRE((short)1, "ire"),
      ACE((short)2, "ace"),
      ASE((short)3, "ase"),
      AE((short)4, "ae");

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

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

      /**
       * Find the _Fields constant that matches fieldId, or null if its not found.
       */
      public static _Fields findByThriftId(int fieldId) {
        switch(fieldId) {
          case 1: // IRE
            return IRE;
          case 2: // ACE
            return ACE;
          case 3: // ASE
            return ASE;
          case 4: // 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 IllegalArgumentException("Field " + fieldId + " doesn't exist!");
        return fields;
      }

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

      private final short _thriftId;
      private final String _fieldName;

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

      public short getThriftFieldId() {
        return _thriftId;
      }

      public String getFieldName() {
        return _fieldName;
      }
    }

    // isset id assignments
    public static final Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
    static {
      Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new EnumMap<_Fields, org.apache.thrift.meta_data.FieldMetaData>(_Fields.class);
      tmpMap.put(_Fields.IRE, new org.apache.thrift.meta_data.FieldMetaData("ire", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRUCT)));
      tmpMap.put(_Fields.ACE, new org.apache.thrift.meta_data.FieldMetaData("ace", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRUCT)));
      tmpMap.put(_Fields.ASE, new org.apache.thrift.meta_data.FieldMetaData("ase", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRUCT)));
      tmpMap.put(_Fields.AE, new org.apache.thrift.meta_data.FieldMetaData("ae", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRUCT)));
      metaDataMap = Collections.unmodifiableMap(tmpMap);
      org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(updateGateway_result.class, metaDataMap);
    }

    public updateGateway_result() {
    }

    public updateGateway_result(
      org.apache.airavata.model.error.InvalidRequestException ire,
      org.apache.airavata.model.error.AiravataClientException ace,
      org.apache.airavata.model.error.AiravataSystemException ase,
      org.apache.airavata.model.error.AuthorizationException ae)
    {
      this();
      this.ire = ire;
      this.ace = ace;
      this.ase = ase;
      this.ae = ae;
    }

    /**
     * Performs a deep copy on <i>other</i>.
     */
    public updateGateway_result(updateGateway_result other) {
      if (other.isSetIre()) {
        this.ire = new org.apache.airavata.model.error.InvalidRequestException(other.ire);
      }
      if (other.isSetAce()) {
        this.ace = new org.apache.airavata.model.error.AiravataClientException(other.ace);
      }
      if (other.isSetAse()) {
        this.ase = new org.apache.airavata.model.error.AiravataSystemException(other.ase);
      }
      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() {
      this.ire = null;
      this.ace = null;
      this.ase = null;
      this.ae = null;
    }

    public org.apache.airavata.model.error.InvalidRequestException getIre() {
      return this.ire;
    }

    public updateGateway_result setIre(org.apache.airavata.model.error.InvalidRequestException ire) {
      this.ire = ire;
      return this;
    }

    public void unsetIre() {
      this.ire = null;
    }

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

    public void setIreIsSet(boolean value) {
      if (!value) {
        this.ire = null;
      }
    }

    public org.apache.airavata.model.error.AiravataClientException getAce() {
      return this.ace;
    }

    public updateGateway_result setAce(org.apache.airavata.model.error.AiravataClientException ace) {
      this.ace = ace;
      return this;
    }

    public void unsetAce() {
      this.ace = null;
    }

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

    public void setAceIsSet(boolean value) {
      if (!value) {
        this.ace = null;
      }
    }

    public org.apache.airavata.model.error.AiravataSystemException getAse() {
      return this.ase;
    }

    public updateGateway_result setAse(org.apache.airavata.model.error.AiravataSystemException ase) {
      this.ase = ase;
      return this;
    }

    public void unsetAse() {
      this.ase = null;
    }

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

    public void setAseIsSet(boolean value) {
      if (!value) {
        this.ase = 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, Object value) {
      switch (field) {
      case IRE:
        if (value == null) {
          unsetIre();
        } else {
          setIre((org.apache.airavata.model.error.InvalidRequestException)value);
        }
        break;

      case ACE:
        if (value == null) {
          unsetAce();
        } else {
          setAce((org.apache.airavata.model.error.AiravataClientException)value);
        }
        break;

      case ASE:
        if (value == null) {
          unsetAse();
        } else {
          setAse((org.apache.airavata.model.error.AiravataSystemException)value);
        }
        break;

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

      }
    }

    public Object getFieldValue(_Fields field) {
      switch (field) {
      case IRE:
        return getIre();

      case ACE:
        return getAce();

      case ASE:
        return getAse();

      case AE:
        return getAe();

      }
      throw new IllegalStateException();
    }

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

      switch (field) {
      case IRE:
        return isSetIre();
      case ACE:
        return isSetAce();
      case ASE:
        return isSetAse();
      case AE:
        return isSetAe();
      }
      throw new IllegalStateException();
    }

    @Override
    public boolean equals(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;

      boolean this_present_ire = true && this.isSetIre();
      boolean that_present_ire = true && that.isSetIre();
      if (this_present_ire || that_present_ire) {
        if (!(this_present_ire && that_present_ire))
          return false;
        if (!this.ire.equals(that.ire))
          return false;
      }

      boolean this_present_ace = true && this.isSetAce();
      boolean that_present_ace = true && that.isSetAce();
      if (this_present_ace || that_present_ace) {
        if (!(this_present_ace && that_present_ace))
          return false;
        if (!this.ace.equals(that.ace))
          return false;
      }

      boolean this_present_ase = true && this.isSetAse();
      boolean that_present_ase = true && that.isSetAse();
      if (this_present_ase || that_present_ase) {
        if (!(this_present_ase && that_present_ase))
          return false;
        if (!this.ase.equals(that.ase))
          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() {
      List<Object> list = new ArrayList<Object>();

      boolean present_ire = true && (isSetIre());
      list.add(present_ire);
      if (present_ire)
        list.add(ire);

      boolean present_ace = true && (isSetAce());
      list.add(present_ace);
      if (present_ace)
        list.add(ace);

      boolean present_ase = true && (isSetAse());
      list.add(present_ase);
      if (present_ase)
        list.add(ase);

      boolean present_ae = true && (isSetAe());
      list.add(present_ae);
      if (present_ae)
        list.add(ae);

      return list.hashCode();
    }

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

      int lastComparison = 0;

      lastComparison = Boolean.valueOf(isSetIre()).compareTo(other.isSetIre());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetIre()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.ire, other.ire);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = Boolean.valueOf(isSetAce()).compareTo(other.isSetAce());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetAce()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.ace, other.ace);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = Boolean.valueOf(isSetAse()).compareTo(other.isSetAse());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetAse()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.ase, other.ase);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = 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 {
      schemes.get(iprot.getScheme()).getScheme().read(iprot, this);
    }

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

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

      sb.append("ire:");
      if (this.ire == null) {
        sb.append("null");
      } else {
        sb.append(this.ire);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("ace:");
      if (this.ace == null) {
        sb.append("null");
      } else {
        sb.append(this.ace);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("ase:");
      if (this.ase == null) {
        sb.append("null");
      } else {
        sb.append(this.ase);
      }
      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, 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_resultStandardSchemeFactory implements SchemeFactory {
      public updateGateway_resultStandardScheme getScheme() {
        return new updateGateway_resultStandardScheme();
      }
    }

    private static class updateGateway_resultStandardScheme extends 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 1: // IRE
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.ire = new org.apache.airavata.model.error.InvalidRequestException();
                struct.ire.read(iprot);
                struct.setIreIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 2: // ACE
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.ace = new org.apache.airavata.model.error.AiravataClientException();
                struct.ace.read(iprot);
                struct.setAceIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 3: // ASE
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.ase = new org.apache.airavata.model.error.AiravataSystemException();
                struct.ase.read(iprot);
                struct.setAseIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 4: // 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.ire != null) {
          oprot.writeFieldBegin(IRE_FIELD_DESC);
          struct.ire.write(oprot);
          oprot.writeFieldEnd();
        }
        if (struct.ace != null) {
          oprot.writeFieldBegin(ACE_FIELD_DESC);
          struct.ace.write(oprot);
          oprot.writeFieldEnd();
        }
        if (struct.ase != null) {
          oprot.writeFieldBegin(ASE_FIELD_DESC);
          struct.ase.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 SchemeFactory {
      public updateGateway_resultTupleScheme getScheme() {
        return new updateGateway_resultTupleScheme();
      }
    }

    private static class updateGateway_resultTupleScheme extends TupleScheme<updateGateway_result> {

      @Override
      public void write(org.apache.thrift.protocol.TProtocol prot, updateGateway_result struct) throws org.apache.thrift.TException {
        TTupleProtocol oprot = (TTupleProtocol) prot;
        BitSet optionals = new BitSet();
        if (struct.isSetIre()) {
          optionals.set(0);
        }
        if (struct.isSetAce()) {
          optionals.set(1);
        }
        if (struct.isSetAse()) {
          optionals.set(2);
        }
        if (struct.isSetAe()) {
          optionals.set(3);
        }
        oprot.writeBitSet(optionals, 4);
        if (struct.isSetIre()) {
          struct.ire.write(oprot);
        }
        if (struct.isSetAce()) {
          struct.ace.write(oprot);
        }
        if (struct.isSetAse()) {
          struct.ase.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 {
        TTupleProtocol iprot = (TTupleProtocol) prot;
        BitSet incoming = iprot.readBitSet(4);
        if (incoming.get(0)) {
          struct.ire = new org.apache.airavata.model.error.InvalidRequestException();
          struct.ire.read(iprot);
          struct.setIreIsSet(true);
        }
        if (incoming.get(1)) {
          struct.ace = new org.apache.airavata.model.error.AiravataClientException();
          struct.ace.read(iprot);
          struct.setAceIsSet(true);
        }
        if (incoming.get(2)) {
          struct.ase = new org.apache.airavata.model.error.AiravataSystemException();
          struct.ase.read(iprot);
          struct.setAseIsSet(true);
        }
        if (incoming.get(3)) {
          struct.ae = new org.apache.airavata.model.error.AuthorizationException();
          struct.ae.read(iprot);
          struct.setAeIsSet(true);
        }
      }
    }

  }

  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 GATEWAY_ID_FIELD_DESC = new org.apache.thrift.protocol.TField("gatewayId", org.apache.thrift.protocol.TType.STRING, (short)2);

    private static final Map<Class<? extends IScheme>, SchemeFactory> schemes = new HashMap<Class<? extends IScheme>, SchemeFactory>();
    static {
      schemes.put(StandardScheme.class, new getGateway_argsStandardSchemeFactory());
      schemes.put(TupleScheme.class, new getGateway_argsTupleSchemeFactory());
    }

    public org.apache.airavata.model.security.AuthzToken authzToken; // required
    public 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 Map<String, _Fields> byName = new HashMap<String, _Fields>();

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

      /**
       * Find the _Fields constant that matches fieldId, or null if its not found.
       */
      public static _Fields findByThriftId(int fieldId) {
        switch(fieldId) {
          case 1: // 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 IllegalArgumentException("Field " + fieldId + " doesn't exist!");
        return fields;
      }

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

      private final short _thriftId;
      private final String _fieldName;

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

      public short getThriftFieldId() {
        return _thriftId;
      }

      public String getFieldName() {
        return _fieldName;
      }
    }

    // isset id assignments
    public static final Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
    static {
      Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new EnumMap<_Fields, org.apache.thrift.meta_data.FieldMetaData>(_Fields.class);
      tmpMap.put(_Fields.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 = 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,
      String gatewayId)
    {
      this();
      this.authzToken = authzToken;
      this.gatewayId = gatewayId;
    }

    /**
     * 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.isSetGatewayId()) {
        this.gatewayId = other.gatewayId;
      }
    }

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

    @Override
    public void clear() {
      this.authzToken = null;
      this.gatewayId = 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 String getGatewayId() {
      return this.gatewayId;
    }

    public getGateway_args setGatewayId(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, 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((String)value);
        }
        break;

      }
    }

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

      case GATEWAY_ID:
        return getGatewayId();

      }
      throw new IllegalStateException();
    }

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

      switch (field) {
      case AUTHZ_TOKEN:
        return isSetAuthzToken();
      case GATEWAY_ID:
        return isSetGatewayId();
      }
      throw new IllegalStateException();
    }

    @Override
    public boolean equals(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;

      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() {
      List<Object> list = new ArrayList<Object>();

      boolean present_authzToken = true && (isSetAuthzToken());
      list.add(present_authzToken);
      if (present_authzToken)
        list.add(authzToken);

      boolean present_gatewayId = true && (isSetGatewayId());
      list.add(present_gatewayId);
      if (present_gatewayId)
        list.add(gatewayId);

      return list.hashCode();
    }

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

      int lastComparison = 0;

      lastComparison = 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 = 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 {
      schemes.get(iprot.getScheme()).getScheme().read(iprot, this);
    }

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

    @Override
    public String toString() {
      StringBuilder sb = new StringBuilder("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("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, 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 SchemeFactory {
      public getGateway_argsStandardScheme getScheme() {
        return new getGateway_argsStandardScheme();
      }
    }

    private static class getGateway_argsStandardScheme extends 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: // 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, 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.gatewayId != null) {
          oprot.writeFieldBegin(GATEWAY_ID_FIELD_DESC);
          oprot.writeString(struct.gatewayId);
          oprot.writeFieldEnd();
        }
        oprot.writeFieldStop();
        oprot.writeStructEnd();
      }

    }

    private static class getGateway_argsTupleSchemeFactory implements SchemeFactory {
      public getGateway_argsTupleScheme getScheme() {
        return new getGateway_argsTupleScheme();
      }
    }

    private static class getGateway_argsTupleScheme extends TupleScheme<getGateway_args> {

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

      @Override
      public void read(org.apache.thrift.protocol.TProtocol prot, getGateway_args struct) throws org.apache.thrift.TException {
        TTupleProtocol iprot = (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);
      }
    }

  }

  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 IRE_FIELD_DESC = new org.apache.thrift.protocol.TField("ire", org.apache.thrift.protocol.TType.STRUCT, (short)1);
    private static final org.apache.thrift.protocol.TField ACE_FIELD_DESC = new org.apache.thrift.protocol.TField("ace", org.apache.thrift.protocol.TType.STRUCT, (short)2);
    private static final org.apache.thrift.protocol.TField ASE_FIELD_DESC = new org.apache.thrift.protocol.TField("ase", org.apache.thrift.protocol.TType.STRUCT, (short)3);
    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)4);

    private static final Map<Class<? extends IScheme>, SchemeFactory> schemes = new HashMap<Class<? extends IScheme>, SchemeFactory>();
    static {
      schemes.put(StandardScheme.class, new getGateway_resultStandardSchemeFactory());
      schemes.put(TupleScheme.class, new getGateway_resultTupleSchemeFactory());
    }

    public org.apache.airavata.model.workspace.Gateway success; // required
    public org.apache.airavata.model.error.InvalidRequestException ire; // required
    public org.apache.airavata.model.error.AiravataClientException ace; // required
    public org.apache.airavata.model.error.AiravataSystemException ase; // 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"),
      IRE((short)1, "ire"),
      ACE((short)2, "ace"),
      ASE((short)3, "ase"),
      AE((short)4, "ae");

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

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

      /**
       * Find the _Fields constant that matches fieldId, or null if its not found.
       */
      public static _Fields findByThriftId(int fieldId) {
        switch(fieldId) {
          case 0: // SUCCESS
            return SUCCESS;
          case 1: // IRE
            return IRE;
          case 2: // ACE
            return ACE;
          case 3: // ASE
            return ASE;
          case 4: // 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 IllegalArgumentException("Field " + fieldId + " doesn't exist!");
        return fields;
      }

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

      private final short _thriftId;
      private final String _fieldName;

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

      public short getThriftFieldId() {
        return _thriftId;
      }

      public String getFieldName() {
        return _fieldName;
      }
    }

    // isset id assignments
    public static final Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
    static {
      Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new EnumMap<_Fields, org.apache.thrift.meta_data.FieldMetaData>(_Fields.class);
      tmpMap.put(_Fields.SUCCESS, new org.apache.thrift.meta_data.FieldMetaData("success", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.StructMetaData(org.apache.thrift.protocol.TType.STRUCT, org.apache.airavata.model.workspace.Gateway.class)));
      tmpMap.put(_Fields.IRE, new org.apache.thrift.meta_data.FieldMetaData("ire", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRUCT)));
      tmpMap.put(_Fields.ACE, new org.apache.thrift.meta_data.FieldMetaData("ace", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRUCT)));
      tmpMap.put(_Fields.ASE, new org.apache.thrift.meta_data.FieldMetaData("ase", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRUCT)));
      tmpMap.put(_Fields.AE, new org.apache.thrift.meta_data.FieldMetaData("ae", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRUCT)));
      metaDataMap = Collections.unmodifiableMap(tmpMap);
      org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(getGateway_result.class, metaDataMap);
    }

    public getGateway_result() {
    }

    public getGateway_result(
      org.apache.airavata.model.workspace.Gateway success,
      org.apache.airavata.model.error.InvalidRequestException ire,
      org.apache.airavata.model.error.AiravataClientException ace,
      org.apache.airavata.model.error.AiravataSystemException ase,
      org.apache.airavata.model.error.AuthorizationException ae)
    {
      this();
      this.success = success;
      this.ire = ire;
      this.ace = ace;
      this.ase = ase;
      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.isSetIre()) {
        this.ire = new org.apache.airavata.model.error.InvalidRequestException(other.ire);
      }
      if (other.isSetAce()) {
        this.ace = new org.apache.airavata.model.error.AiravataClientException(other.ace);
      }
      if (other.isSetAse()) {
        this.ase = new org.apache.airavata.model.error.AiravataSystemException(other.ase);
      }
      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.ire = null;
      this.ace = null;
      this.ase = 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.model.error.InvalidRequestException getIre() {
      return this.ire;
    }

    public getGateway_result setIre(org.apache.airavata.model.error.InvalidRequestException ire) {
      this.ire = ire;
      return this;
    }

    public void unsetIre() {
      this.ire = null;
    }

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

    public void setIreIsSet(boolean value) {
      if (!value) {
        this.ire = null;
      }
    }

    public org.apache.airavata.model.error.AiravataClientException getAce() {
      return this.ace;
    }

    public getGateway_result setAce(org.apache.airavata.model.error.AiravataClientException ace) {
      this.ace = ace;
      return this;
    }

    public void unsetAce() {
      this.ace = null;
    }

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

    public void setAceIsSet(boolean value) {
      if (!value) {
        this.ace = null;
      }
    }

    public org.apache.airavata.model.error.AiravataSystemException getAse() {
      return this.ase;
    }

    public getGateway_result setAse(org.apache.airavata.model.error.AiravataSystemException ase) {
      this.ase = ase;
      return this;
    }

    public void unsetAse() {
      this.ase = null;
    }

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

    public void setAseIsSet(boolean value) {
      if (!value) {
        this.ase = 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, Object value) {
      switch (field) {
      case SUCCESS:
        if (value == null) {
          unsetSuccess();
        } else {
          setSuccess((org.apache.airavata.model.workspace.Gateway)value);
        }
        break;

      case IRE:
        if (value == null) {
          unsetIre();
        } else {
          setIre((org.apache.airavata.model.error.InvalidRequestException)value);
        }
        break;

      case ACE:
        if (value == null) {
          unsetAce();
        } else {
          setAce((org.apache.airavata.model.error.AiravataClientException)value);
        }
        break;

      case ASE:
        if (value == null) {
          unsetAse();
        } else {
          setAse((org.apache.airavata.model.error.AiravataSystemException)value);
        }
        break;

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

      }
    }

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

      case IRE:
        return getIre();

      case ACE:
        return getAce();

      case ASE:
        return getAse();

      case AE:
        return getAe();

      }
      throw new IllegalStateException();
    }

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

      switch (field) {
      case SUCCESS:
        return isSetSuccess();
      case IRE:
        return isSetIre();
      case ACE:
        return isSetAce();
      case ASE:
        return isSetAse();
      case AE:
        return isSetAe();
      }
      throw new IllegalStateException();
    }

    @Override
    public boolean equals(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;

      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_ire = true && this.isSetIre();
      boolean that_present_ire = true && that.isSetIre();
      if (this_present_ire || that_present_ire) {
        if (!(this_present_ire && that_present_ire))
          return false;
        if (!this.ire.equals(that.ire))
          return false;
      }

      boolean this_present_ace = true && this.isSetAce();
      boolean that_present_ace = true && that.isSetAce();
      if (this_present_ace || that_present_ace) {
        if (!(this_present_ace && that_present_ace))
          return false;
        if (!this.ace.equals(that.ace))
          return false;
      }

      boolean this_present_ase = true && this.isSetAse();
      boolean that_present_ase = true && that.isSetAse();
      if (this_present_ase || that_present_ase) {
        if (!(this_present_ase && that_present_ase))
          return false;
        if (!this.ase.equals(that.ase))
          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() {
      List<Object> list = new ArrayList<Object>();

      boolean present_success = true && (isSetSuccess());
      list.add(present_success);
      if (present_success)
        list.add(success);

      boolean present_ire = true && (isSetIre());
      list.add(present_ire);
      if (present_ire)
        list.add(ire);

      boolean present_ace = true && (isSetAce());
      list.add(present_ace);
      if (present_ace)
        list.add(ace);

      boolean present_ase = true && (isSetAse());
      list.add(present_ase);
      if (present_ase)
        list.add(ase);

      boolean present_ae = true && (isSetAe());
      list.add(present_ae);
      if (present_ae)
        list.add(ae);

      return list.hashCode();
    }

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

      int lastComparison = 0;

      lastComparison = Boolean.valueOf(isSetSuccess()).compareTo(other.isSetSuccess());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetSuccess()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.success, other.success);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = Boolean.valueOf(isSetIre()).compareTo(other.isSetIre());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetIre()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.ire, other.ire);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = Boolean.valueOf(isSetAce()).compareTo(other.isSetAce());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetAce()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.ace, other.ace);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = Boolean.valueOf(isSetAse()).compareTo(other.isSetAse());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetAse()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.ase, other.ase);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = 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 {
      schemes.get(iprot.getScheme()).getScheme().read(iprot, this);
    }

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

    @Override
    public String toString() {
      StringBuilder sb = new StringBuilder("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("ire:");
      if (this.ire == null) {
        sb.append("null");
      } else {
        sb.append(this.ire);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("ace:");
      if (this.ace == null) {
        sb.append("null");
      } else {
        sb.append(this.ace);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("ase:");
      if (this.ase == null) {
        sb.append("null");
      } else {
        sb.append(this.ase);
      }
      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, 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 SchemeFactory {
      public getGateway_resultStandardScheme getScheme() {
        return new getGateway_resultStandardScheme();
      }
    }

    private static class getGateway_resultStandardScheme extends 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: // IRE
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.ire = new org.apache.airavata.model.error.InvalidRequestException();
                struct.ire.read(iprot);
                struct.setIreIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 2: // ACE
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.ace = new org.apache.airavata.model.error.AiravataClientException();
                struct.ace.read(iprot);
                struct.setAceIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 3: // ASE
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.ase = new org.apache.airavata.model.error.AiravataSystemException();
                struct.ase.read(iprot);
                struct.setAseIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 4: // 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.ire != null) {
          oprot.writeFieldBegin(IRE_FIELD_DESC);
          struct.ire.write(oprot);
          oprot.writeFieldEnd();
        }
        if (struct.ace != null) {
          oprot.writeFieldBegin(ACE_FIELD_DESC);
          struct.ace.write(oprot);
          oprot.writeFieldEnd();
        }
        if (struct.ase != null) {
          oprot.writeFieldBegin(ASE_FIELD_DESC);
          struct.ase.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 SchemeFactory {
      public getGateway_resultTupleScheme getScheme() {
        return new getGateway_resultTupleScheme();
      }
    }

    private static class getGateway_resultTupleScheme extends TupleScheme<getGateway_result> {

      @Override
      public void write(org.apache.thrift.protocol.TProtocol prot, getGateway_result struct) throws org.apache.thrift.TException {
        TTupleProtocol oprot = (TTupleProtocol) prot;
        BitSet optionals = new BitSet();
        if (struct.isSetSuccess()) {
          optionals.set(0);
        }
        if (struct.isSetIre()) {
          optionals.set(1);
        }
        if (struct.isSetAce()) {
          optionals.set(2);
        }
        if (struct.isSetAse()) {
          optionals.set(3);
        }
        if (struct.isSetAe()) {
          optionals.set(4);
        }
        oprot.writeBitSet(optionals, 5);
        if (struct.isSetSuccess()) {
          struct.success.write(oprot);
        }
        if (struct.isSetIre()) {
          struct.ire.write(oprot);
        }
        if (struct.isSetAce()) {
          struct.ace.write(oprot);
        }
        if (struct.isSetAse()) {
          struct.ase.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 {
        TTupleProtocol iprot = (TTupleProtocol) prot;
        BitSet incoming = iprot.readBitSet(5);
        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.ire = new org.apache.airavata.model.error.InvalidRequestException();
          struct.ire.read(iprot);
          struct.setIreIsSet(true);
        }
        if (incoming.get(2)) {
          struct.ace = new org.apache.airavata.model.error.AiravataClientException();
          struct.ace.read(iprot);
          struct.setAceIsSet(true);
        }
        if (incoming.get(3)) {
          struct.ase = new org.apache.airavata.model.error.AiravataSystemException();
          struct.ase.read(iprot);
          struct.setAseIsSet(true);
        }
        if (incoming.get(4)) {
          struct.ae = new org.apache.airavata.model.error.AuthorizationException();
          struct.ae.read(iprot);
          struct.setAeIsSet(true);
        }
      }
    }

  }

  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 GATEWAY_ID_FIELD_DESC = new org.apache.thrift.protocol.TField("gatewayId", org.apache.thrift.protocol.TType.STRING, (short)2);

    private static final Map<Class<? extends IScheme>, SchemeFactory> schemes = new HashMap<Class<? extends IScheme>, SchemeFactory>();
    static {
      schemes.put(StandardScheme.class, new deleteGateway_argsStandardSchemeFactory());
      schemes.put(TupleScheme.class, new deleteGateway_argsTupleSchemeFactory());
    }

    public org.apache.airavata.model.security.AuthzToken authzToken; // required
    public 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 Map<String, _Fields> byName = new HashMap<String, _Fields>();

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

      /**
       * Find the _Fields constant that matches fieldId, or null if its not found.
       */
      public static _Fields findByThriftId(int fieldId) {
        switch(fieldId) {
          case 1: // 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 IllegalArgumentException("Field " + fieldId + " doesn't exist!");
        return fields;
      }

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

      private final short _thriftId;
      private final String _fieldName;

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

      public short getThriftFieldId() {
        return _thriftId;
      }

      public String getFieldName() {
        return _fieldName;
      }
    }

    // isset id assignments
    public static final Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
    static {
      Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new EnumMap<_Fields, org.apache.thrift.meta_data.FieldMetaData>(_Fields.class);
      tmpMap.put(_Fields.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 = 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,
      String gatewayId)
    {
      this();
      this.authzToken = authzToken;
      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.isSetGatewayId()) {
        this.gatewayId = other.gatewayId;
      }
    }

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

    @Override
    public void clear() {
      this.authzToken = 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 String getGatewayId() {
      return this.gatewayId;
    }

    public deleteGateway_args setGatewayId(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, 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((String)value);
        }
        break;

      }
    }

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

      case GATEWAY_ID:
        return getGatewayId();

      }
      throw new IllegalStateException();
    }

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

      switch (field) {
      case AUTHZ_TOKEN:
        return isSetAuthzToken();
      case GATEWAY_ID:
        return isSetGatewayId();
      }
      throw new IllegalStateException();
    }

    @Override
    public boolean equals(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;

      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() {
      List<Object> list = new ArrayList<Object>();

      boolean present_authzToken = true && (isSetAuthzToken());
      list.add(present_authzToken);
      if (present_authzToken)
        list.add(authzToken);

      boolean present_gatewayId = true && (isSetGatewayId());
      list.add(present_gatewayId);
      if (present_gatewayId)
        list.add(gatewayId);

      return list.hashCode();
    }

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

      int lastComparison = 0;

      lastComparison = 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 = 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 {
      schemes.get(iprot.getScheme()).getScheme().read(iprot, this);
    }

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

    @Override
    public String toString() {
      StringBuilder sb = new StringBuilder("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("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, 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 SchemeFactory {
      public deleteGateway_argsStandardScheme getScheme() {
        return new deleteGateway_argsStandardScheme();
      }
    }

    private static class deleteGateway_argsStandardScheme extends 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: // 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.gatewayId != null) {
          oprot.writeFieldBegin(GATEWAY_ID_FIELD_DESC);
          oprot.writeString(struct.gatewayId);
          oprot.writeFieldEnd();
        }
        oprot.writeFieldStop();
        oprot.writeStructEnd();
      }

    }

    private static class deleteGateway_argsTupleSchemeFactory implements SchemeFactory {
      public deleteGateway_argsTupleScheme getScheme() {
        return new deleteGateway_argsTupleScheme();
      }
    }

    private static class deleteGateway_argsTupleScheme extends TupleScheme<deleteGateway_args> {

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

      @Override
      public void read(org.apache.thrift.protocol.TProtocol prot, deleteGateway_args struct) throws org.apache.thrift.TException {
        TTupleProtocol iprot = (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);
      }
    }

  }

  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 IRE_FIELD_DESC = new org.apache.thrift.protocol.TField("ire", org.apache.thrift.protocol.TType.STRUCT, (short)1);
    private static final org.apache.thrift.protocol.TField ACE_FIELD_DESC = new org.apache.thrift.protocol.TField("ace", org.apache.thrift.protocol.TType.STRUCT, (short)2);
    private static final org.apache.thrift.protocol.TField ASE_FIELD_DESC = new org.apache.thrift.protocol.TField("ase", org.apache.thrift.protocol.TType.STRUCT, (short)3);
    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)4);

    private static final Map<Class<? extends IScheme>, SchemeFactory> schemes = new HashMap<Class<? extends IScheme>, SchemeFactory>();
    static {
      schemes.put(StandardScheme.class, new deleteGateway_resultStandardSchemeFactory());
      schemes.put(TupleScheme.class, new deleteGateway_resultTupleSchemeFactory());
    }

    public boolean success; // required
    public org.apache.airavata.model.error.InvalidRequestException ire; // required
    public org.apache.airavata.model.error.AiravataClientException ace; // required
    public org.apache.airavata.model.error.AiravataSystemException ase; // 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"),
      IRE((short)1, "ire"),
      ACE((short)2, "ace"),
      ASE((short)3, "ase"),
      AE((short)4, "ae");

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

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

      /**
       * Find the _Fields constant that matches fieldId, or null if its not found.
       */
      public static _Fields findByThriftId(int fieldId) {
        switch(fieldId) {
          case 0: // SUCCESS
            return SUCCESS;
          case 1: // IRE
            return IRE;
          case 2: // ACE
            return ACE;
          case 3: // ASE
            return ASE;
          case 4: // 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 IllegalArgumentException("Field " + fieldId + " doesn't exist!");
        return fields;
      }

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

      private final short _thriftId;
      private final String _fieldName;

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

      public short getThriftFieldId() {
        return _thriftId;
      }

      public String getFieldName() {
        return _fieldName;
      }
    }

    // isset id assignments
    private static final int __SUCCESS_ISSET_ID = 0;
    private byte __isset_bitfield = 0;
    public static final Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
    static {
      Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new EnumMap<_Fields, org.apache.thrift.meta_data.FieldMetaData>(_Fields.class);
      tmpMap.put(_Fields.SUCCESS, new org.apache.thrift.meta_data.FieldMetaData("success", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.BOOL)));
      tmpMap.put(_Fields.IRE, new org.apache.thrift.meta_data.FieldMetaData("ire", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRUCT)));
      tmpMap.put(_Fields.ACE, new org.apache.thrift.meta_data.FieldMetaData("ace", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRUCT)));
      tmpMap.put(_Fields.ASE, new org.apache.thrift.meta_data.FieldMetaData("ase", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRUCT)));
      tmpMap.put(_Fields.AE, new org.apache.thrift.meta_data.FieldMetaData("ae", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRUCT)));
      metaDataMap = Collections.unmodifiableMap(tmpMap);
      org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(deleteGateway_result.class, metaDataMap);
    }

    public deleteGateway_result() {
    }

    public deleteGateway_result(
      boolean success,
      org.apache.airavata.model.error.InvalidRequestException ire,
      org.apache.airavata.model.error.AiravataClientException ace,
      org.apache.airavata.model.error.AiravataSystemException ase,
      org.apache.airavata.model.error.AuthorizationException ae)
    {
      this();
      this.success = success;
      setSuccessIsSet(true);
      this.ire = ire;
      this.ace = ace;
      this.ase = ase;
      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.isSetIre()) {
        this.ire = new org.apache.airavata.model.error.InvalidRequestException(other.ire);
      }
      if (other.isSetAce()) {
        this.ace = new org.apache.airavata.model.error.AiravataClientException(other.ace);
      }
      if (other.isSetAse()) {
        this.ase = new org.apache.airavata.model.error.AiravataSystemException(other.ase);
      }
      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.ire = null;
      this.ace = null;
      this.ase = 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 = EncodingUtils.clearBit(__isset_bitfield, __SUCCESS_ISSET_ID);
    }

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

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

    public org.apache.airavata.model.error.InvalidRequestException getIre() {
      return this.ire;
    }

    public deleteGateway_result setIre(org.apache.airavata.model.error.InvalidRequestException ire) {
      this.ire = ire;
      return this;
    }

    public void unsetIre() {
      this.ire = null;
    }

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

    public void setIreIsSet(boolean value) {
      if (!value) {
        this.ire = null;
      }
    }

    public org.apache.airavata.model.error.AiravataClientException getAce() {
      return this.ace;
    }

    public deleteGateway_result setAce(org.apache.airavata.model.error.AiravataClientException ace) {
      this.ace = ace;
      return this;
    }

    public void unsetAce() {
      this.ace = null;
    }

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

    public void setAceIsSet(boolean value) {
      if (!value) {
        this.ace = null;
      }
    }

    public org.apache.airavata.model.error.AiravataSystemException getAse() {
      return this.ase;
    }

    public deleteGateway_result setAse(org.apache.airavata.model.error.AiravataSystemException ase) {
      this.ase = ase;
      return this;
    }

    public void unsetAse() {
      this.ase = null;
    }

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

    public void setAseIsSet(boolean value) {
      if (!value) {
        this.ase = 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, Object value) {
      switch (field) {
      case SUCCESS:
        if (value == null) {
          unsetSuccess();
        } else {
          setSuccess((Boolean)value);
        }
        break;

      case IRE:
        if (value == null) {
          unsetIre();
        } else {
          setIre((org.apache.airavata.model.error.InvalidRequestException)value);
        }
        break;

      case ACE:
        if (value == null) {
          unsetAce();
        } else {
          setAce((org.apache.airavata.model.error.AiravataClientException)value);
        }
        break;

      case ASE:
        if (value == null) {
          unsetAse();
        } else {
          setAse((org.apache.airavata.model.error.AiravataSystemException)value);
        }
        break;

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

      }
    }

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

      case IRE:
        return getIre();

      case ACE:
        return getAce();

      case ASE:
        return getAse();

      case AE:
        return getAe();

      }
      throw new IllegalStateException();
    }

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

      switch (field) {
      case SUCCESS:
        return isSetSuccess();
      case IRE:
        return isSetIre();
      case ACE:
        return isSetAce();
      case ASE:
        return isSetAse();
      case AE:
        return isSetAe();
      }
      throw new IllegalStateException();
    }

    @Override
    public boolean equals(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;

      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_ire = true && this.isSetIre();
      boolean that_present_ire = true && that.isSetIre();
      if (this_present_ire || that_present_ire) {
        if (!(this_present_ire && that_present_ire))
          return false;
        if (!this.ire.equals(that.ire))
          return false;
      }

      boolean this_present_ace = true && this.isSetAce();
      boolean that_present_ace = true && that.isSetAce();
      if (this_present_ace || that_present_ace) {
        if (!(this_present_ace && that_present_ace))
          return false;
        if (!this.ace.equals(that.ace))
          return false;
      }

      boolean this_present_ase = true && this.isSetAse();
      boolean that_present_ase = true && that.isSetAse();
      if (this_present_ase || that_present_ase) {
        if (!(this_present_ase && that_present_ase))
          return false;
        if (!this.ase.equals(that.ase))
          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() {
      List<Object> list = new ArrayList<Object>();

      boolean present_success = true;
      list.add(present_success);
      if (present_success)
        list.add(success);

      boolean present_ire = true && (isSetIre());
      list.add(present_ire);
      if (present_ire)
        list.add(ire);

      boolean present_ace = true && (isSetAce());
      list.add(present_ace);
      if (present_ace)
        list.add(ace);

      boolean present_ase = true && (isSetAse());
      list.add(present_ase);
      if (present_ase)
        list.add(ase);

      boolean present_ae = true && (isSetAe());
      list.add(present_ae);
      if (present_ae)
        list.add(ae);

      return list.hashCode();
    }

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

      int lastComparison = 0;

      lastComparison = Boolean.valueOf(isSetSuccess()).compareTo(other.isSetSuccess());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetSuccess()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.success, other.success);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = Boolean.valueOf(isSetIre()).compareTo(other.isSetIre());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetIre()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.ire, other.ire);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = Boolean.valueOf(isSetAce()).compareTo(other.isSetAce());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetAce()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.ace, other.ace);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = Boolean.valueOf(isSetAse()).compareTo(other.isSetAse());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetAse()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.ase, other.ase);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = 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 {
      schemes.get(iprot.getScheme()).getScheme().read(iprot, this);
    }

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

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

      sb.append("success:");
      sb.append(this.success);
      first = false;
      if (!first) sb.append(", ");
      sb.append("ire:");
      if (this.ire == null) {
        sb.append("null");
      } else {
        sb.append(this.ire);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("ace:");
      if (this.ace == null) {
        sb.append("null");
      } else {
        sb.append(this.ace);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("ase:");
      if (this.ase == null) {
        sb.append("null");
      } else {
        sb.append(this.ase);
      }
      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, 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 SchemeFactory {
      public deleteGateway_resultStandardScheme getScheme() {
        return new deleteGateway_resultStandardScheme();
      }
    }

    private static class deleteGateway_resultStandardScheme extends 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: // IRE
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.ire = new org.apache.airavata.model.error.InvalidRequestException();
                struct.ire.read(iprot);
                struct.setIreIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 2: // ACE
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.ace = new org.apache.airavata.model.error.AiravataClientException();
                struct.ace.read(iprot);
                struct.setAceIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 3: // ASE
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.ase = new org.apache.airavata.model.error.AiravataSystemException();
                struct.ase.read(iprot);
                struct.setAseIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 4: // 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.ire != null) {
          oprot.writeFieldBegin(IRE_FIELD_DESC);
          struct.ire.write(oprot);
          oprot.writeFieldEnd();
        }
        if (struct.ace != null) {
          oprot.writeFieldBegin(ACE_FIELD_DESC);
          struct.ace.write(oprot);
          oprot.writeFieldEnd();
        }
        if (struct.ase != null) {
          oprot.writeFieldBegin(ASE_FIELD_DESC);
          struct.ase.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 SchemeFactory {
      public deleteGateway_resultTupleScheme getScheme() {
        return new deleteGateway_resultTupleScheme();
      }
    }

    private static class deleteGateway_resultTupleScheme extends TupleScheme<deleteGateway_result> {

      @Override
      public void write(org.apache.thrift.protocol.TProtocol prot, deleteGateway_result struct) throws org.apache.thrift.TException {
        TTupleProtocol oprot = (TTupleProtocol) prot;
        BitSet optionals = new BitSet();
        if (struct.isSetSuccess()) {
          optionals.set(0);
        }
        if (struct.isSetIre()) {
          optionals.set(1);
        }
        if (struct.isSetAce()) {
          optionals.set(2);
        }
        if (struct.isSetAse()) {
          optionals.set(3);
        }
        if (struct.isSetAe()) {
          optionals.set(4);
        }
        oprot.writeBitSet(optionals, 5);
        if (struct.isSetSuccess()) {
          oprot.writeBool(struct.success);
        }
        if (struct.isSetIre()) {
          struct.ire.write(oprot);
        }
        if (struct.isSetAce()) {
          struct.ace.write(oprot);
        }
        if (struct.isSetAse()) {
          struct.ase.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 {
        TTupleProtocol iprot = (TTupleProtocol) prot;
        BitSet incoming = iprot.readBitSet(5);
        if (incoming.get(0)) {
          struct.success = iprot.readBool();
          struct.setSuccessIsSet(true);
        }
        if (incoming.get(1)) {
          struct.ire = new org.apache.airavata.model.error.InvalidRequestException();
          struct.ire.read(iprot);
          struct.setIreIsSet(true);
        }
        if (incoming.get(2)) {
          struct.ace = new org.apache.airavata.model.error.AiravataClientException();
          struct.ace.read(iprot);
          struct.setAceIsSet(true);
        }
        if (incoming.get(3)) {
          struct.ase = new org.apache.airavata.model.error.AiravataSystemException();
          struct.ase.read(iprot);
          struct.setAseIsSet(true);
        }
        if (incoming.get(4)) {
          struct.ae = new org.apache.airavata.model.error.AuthorizationException();
          struct.ae.read(iprot);
          struct.setAeIsSet(true);
        }
      }
    }

  }

  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 Map<Class<? extends IScheme>, SchemeFactory> schemes = new HashMap<Class<? extends IScheme>, SchemeFactory>();
    static {
      schemes.put(StandardScheme.class, new getAllGateways_argsStandardSchemeFactory());
      schemes.put(TupleScheme.class, 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 Map<String, _Fields> byName = new HashMap<String, _Fields>();

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

      /**
       * Find the _Fields constant that matches fieldId, or null if its not found.
       */
      public static _Fields findByThriftId(int fieldId) {
        switch(fieldId) {
          case 1: // 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 IllegalArgumentException("Field " + fieldId + " doesn't exist!");
        return fields;
      }

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

      private final short _thriftId;
      private final String _fieldName;

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

      public short getThriftFieldId() {
        return _thriftId;
      }

      public String getFieldName() {
        return _fieldName;
      }
    }

    // isset id assignments
    public static final Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
    static {
      Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new EnumMap<_Fields, org.apache.thrift.meta_data.FieldMetaData>(_Fields.class);
      tmpMap.put(_Fields.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 = 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, Object value) {
      switch (field) {
      case AUTHZ_TOKEN:
        if (value == null) {
          unsetAuthzToken();
        } else {
          setAuthzToken((org.apache.airavata.model.security.AuthzToken)value);
        }
        break;

      }
    }

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

      }
      throw new IllegalStateException();
    }

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

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

    @Override
    public boolean equals(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;

      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() {
      List<Object> list = new ArrayList<Object>();

      boolean present_authzToken = true && (isSetAuthzToken());
      list.add(present_authzToken);
      if (present_authzToken)
        list.add(authzToken);

      return list.hashCode();
    }

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

      int lastComparison = 0;

      lastComparison = 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 {
      schemes.get(iprot.getScheme()).getScheme().read(iprot, this);
    }

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

    @Override
    public String toString() {
      StringBuilder sb = new StringBuilder("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, 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 SchemeFactory {
      public getAllGateways_argsStandardScheme getScheme() {
        return new getAllGateways_argsStandardScheme();
      }
    }

    private static class getAllGateways_argsStandardScheme extends 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 SchemeFactory {
      public getAllGateways_argsTupleScheme getScheme() {
        return new getAllGateways_argsTupleScheme();
      }
    }

    private static class getAllGateways_argsTupleScheme extends TupleScheme<getAllGateways_args> {

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

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

  }

  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 IRE_FIELD_DESC = new org.apache.thrift.protocol.TField("ire", org.apache.thrift.protocol.TType.STRUCT, (short)1);
    private static final org.apache.thrift.protocol.TField ACE_FIELD_DESC = new org.apache.thrift.protocol.TField("ace", org.apache.thrift.protocol.TType.STRUCT, (short)2);
    private static final org.apache.thrift.protocol.TField ASE_FIELD_DESC = new org.apache.thrift.protocol.TField("ase", org.apache.thrift.protocol.TType.STRUCT, (short)3);
    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)4);

    private static final Map<Class<? extends IScheme>, SchemeFactory> schemes = new HashMap<Class<? extends IScheme>, SchemeFactory>();
    static {
      schemes.put(StandardScheme.class, new getAllGateways_resultStandardSchemeFactory());
      schemes.put(TupleScheme.class, new getAllGateways_resultTupleSchemeFactory());
    }

    public List<org.apache.airavata.model.workspace.Gateway> success; // required
    public org.apache.airavata.model.error.InvalidRequestException ire; // required
    public org.apache.airavata.model.error.AiravataClientException ace; // required
    public org.apache.airavata.model.error.AiravataSystemException ase; // 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"),
      IRE((short)1, "ire"),
      ACE((short)2, "ace"),
      ASE((short)3, "ase"),
      AE((short)4, "ae");

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

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

      /**
       * Find the _Fields constant that matches fieldId, or null if its not found.
       */
      public static _Fields findByThriftId(int fieldId) {
        switch(fieldId) {
          case 0: // SUCCESS
            return SUCCESS;
          case 1: // IRE
            return IRE;
          case 2: // ACE
            return ACE;
          case 3: // ASE
            return ASE;
          case 4: // 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 IllegalArgumentException("Field " + fieldId + " doesn't exist!");
        return fields;
      }

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

      private final short _thriftId;
      private final String _fieldName;

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

      public short getThriftFieldId() {
        return _thriftId;
      }

      public String getFieldName() {
        return _fieldName;
      }
    }

    // isset id assignments
    public static final Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
    static {
      Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new EnumMap<_Fields, org.apache.thrift.meta_data.FieldMetaData>(_Fields.class);
      tmpMap.put(_Fields.SUCCESS, new org.apache.thrift.meta_data.FieldMetaData("success", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.ListMetaData(org.apache.thrift.protocol.TType.LIST, 
              new org.apache.thrift.meta_data.StructMetaData(org.apache.thrift.protocol.TType.STRUCT, org.apache.airavata.model.workspace.Gateway.class))));
      tmpMap.put(_Fields.IRE, new org.apache.thrift.meta_data.FieldMetaData("ire", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRUCT)));
      tmpMap.put(_Fields.ACE, new org.apache.thrift.meta_data.FieldMetaData("ace", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRUCT)));
      tmpMap.put(_Fields.ASE, new org.apache.thrift.meta_data.FieldMetaData("ase", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRUCT)));
      tmpMap.put(_Fields.AE, new org.apache.thrift.meta_data.FieldMetaData("ae", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRUCT)));
      metaDataMap = Collections.unmodifiableMap(tmpMap);
      org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(getAllGateways_result.class, metaDataMap);
    }

    public getAllGateways_result() {
    }

    public getAllGateways_result(
      List<org.apache.airavata.model.workspace.Gateway> success,
      org.apache.airavata.model.error.InvalidRequestException ire,
      org.apache.airavata.model.error.AiravataClientException ace,
      org.apache.airavata.model.error.AiravataSystemException ase,
      org.apache.airavata.model.error.AuthorizationException ae)
    {
      this();
      this.success = success;
      this.ire = ire;
      this.ace = ace;
      this.ase = ase;
      this.ae = ae;
    }

    /**
     * Performs a deep copy on <i>other</i>.
     */
    public getAllGateways_result(getAllGateways_result other) {
      if (other.isSetSuccess()) {
        List<org.apache.airavata.model.workspace.Gateway> __this__success = new 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.isSetIre()) {
        this.ire = new org.apache.airavata.model.error.InvalidRequestException(other.ire);
      }
      if (other.isSetAce()) {
        this.ace = new org.apache.airavata.model.error.AiravataClientException(other.ace);
      }
      if (other.isSetAse()) {
        this.ase = new org.apache.airavata.model.error.AiravataSystemException(other.ase);
      }
      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.ire = null;
      this.ace = null;
      this.ase = 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 ArrayList<org.apache.airavata.model.workspace.Gateway>();
      }
      this.success.add(elem);
    }

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

    public getAllGateways_result setSuccess(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.model.error.InvalidRequestException getIre() {
      return this.ire;
    }

    public getAllGateways_result setIre(org.apache.airavata.model.error.InvalidRequestException ire) {
      this.ire = ire;
      return this;
    }

    public void unsetIre() {
      this.ire = null;
    }

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

    public void setIreIsSet(boolean value) {
      if (!value) {
        this.ire = null;
      }
    }

    public org.apache.airavata.model.error.AiravataClientException getAce() {
      return this.ace;
    }

    public getAllGateways_result setAce(org.apache.airavata.model.error.AiravataClientException ace) {
      this.ace = ace;
      return this;
    }

    public void unsetAce() {
      this.ace = null;
    }

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

    public void setAceIsSet(boolean value) {
      if (!value) {
        this.ace = null;
      }
    }

    public org.apache.airavata.model.error.AiravataSystemException getAse() {
      return this.ase;
    }

    public getAllGateways_result setAse(org.apache.airavata.model.error.AiravataSystemException ase) {
      this.ase = ase;
      return this;
    }

    public void unsetAse() {
      this.ase = null;
    }

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

    public void setAseIsSet(boolean value) {
      if (!value) {
        this.ase = 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, Object value) {
      switch (field) {
      case SUCCESS:
        if (value == null) {
          unsetSuccess();
        } else {
          setSuccess((List<org.apache.airavata.model.workspace.Gateway>)value);
        }
        break;

      case IRE:
        if (value == null) {
          unsetIre();
        } else {
          setIre((org.apache.airavata.model.error.InvalidRequestException)value);
        }
        break;

      case ACE:
        if (value == null) {
          unsetAce();
        } else {
          setAce((org.apache.airavata.model.error.AiravataClientException)value);
        }
        break;

      case ASE:
        if (value == null) {
          unsetAse();
        } else {
          setAse((org.apache.airavata.model.error.AiravataSystemException)value);
        }
        break;

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

      }
    }

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

      case IRE:
        return getIre();

      case ACE:
        return getAce();

      case ASE:
        return getAse();

      case AE:
        return getAe();

      }
      throw new IllegalStateException();
    }

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

      switch (field) {
      case SUCCESS:
        return isSetSuccess();
      case IRE:
        return isSetIre();
      case ACE:
        return isSetAce();
      case ASE:
        return isSetAse();
      case AE:
        return isSetAe();
      }
      throw new IllegalStateException();
    }

    @Override
    public boolean equals(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;

      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_ire = true && this.isSetIre();
      boolean that_present_ire = true && that.isSetIre();
      if (this_present_ire || that_present_ire) {
        if (!(this_present_ire && that_present_ire))
          return false;
        if (!this.ire.equals(that.ire))
          return false;
      }

      boolean this_present_ace = true && this.isSetAce();
      boolean that_present_ace = true && that.isSetAce();
      if (this_present_ace || that_present_ace) {
        if (!(this_present_ace && that_present_ace))
          return false;
        if (!this.ace.equals(that.ace))
          return false;
      }

      boolean this_present_ase = true && this.isSetAse();
      boolean that_present_ase = true && that.isSetAse();
      if (this_present_ase || that_present_ase) {
        if (!(this_present_ase && that_present_ase))
          return false;
        if (!this.ase.equals(that.ase))
          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() {
      List<Object> list = new ArrayList<Object>();

      boolean present_success = true && (isSetSuccess());
      list.add(present_success);
      if (present_success)
        list.add(success);

      boolean present_ire = true && (isSetIre());
      list.add(present_ire);
      if (present_ire)
        list.add(ire);

      boolean present_ace = true && (isSetAce());
      list.add(present_ace);
      if (present_ace)
        list.add(ace);

      boolean present_ase = true && (isSetAse());
      list.add(present_ase);
      if (present_ase)
        list.add(ase);

      boolean present_ae = true && (isSetAe());
      list.add(present_ae);
      if (present_ae)
        list.add(ae);

      return list.hashCode();
    }

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

      int lastComparison = 0;

      lastComparison = Boolean.valueOf(isSetSuccess()).compareTo(other.isSetSuccess());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetSuccess()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.success, other.success);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = Boolean.valueOf(isSetIre()).compareTo(other.isSetIre());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetIre()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.ire, other.ire);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = Boolean.valueOf(isSetAce()).compareTo(other.isSetAce());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetAce()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.ace, other.ace);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = Boolean.valueOf(isSetAse()).compareTo(other.isSetAse());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetAse()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.ase, other.ase);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = 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 {
      schemes.get(iprot.getScheme()).getScheme().read(iprot, this);
    }

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

    @Override
    public String toString() {
      StringBuilder sb = new StringBuilder("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("ire:");
      if (this.ire == null) {
        sb.append("null");
      } else {
        sb.append(this.ire);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("ace:");
      if (this.ace == null) {
        sb.append("null");
      } else {
        sb.append(this.ace);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("ase:");
      if (this.ase == null) {
        sb.append("null");
      } else {
        sb.append(this.ase);
      }
      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, 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 SchemeFactory {
      public getAllGateways_resultStandardScheme getScheme() {
        return new getAllGateways_resultStandardScheme();
      }
    }

    private static class getAllGateways_resultStandardScheme extends 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 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: // IRE
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.ire = new org.apache.airavata.model.error.InvalidRequestException();
                struct.ire.read(iprot);
                struct.setIreIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 2: // ACE
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.ace = new org.apache.airavata.model.error.AiravataClientException();
                struct.ace.read(iprot);
                struct.setAceIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 3: // ASE
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.ase = new org.apache.airavata.model.error.AiravataSystemException();
                struct.ase.read(iprot);
                struct.setAseIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 4: // 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.ire != null) {
          oprot.writeFieldBegin(IRE_FIELD_DESC);
          struct.ire.write(oprot);
          oprot.writeFieldEnd();
        }
        if (struct.ace != null) {
          oprot.writeFieldBegin(ACE_FIELD_DESC);
          struct.ace.write(oprot);
          oprot.writeFieldEnd();
        }
        if (struct.ase != null) {
          oprot.writeFieldBegin(ASE_FIELD_DESC);
          struct.ase.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 SchemeFactory {
      public getAllGateways_resultTupleScheme getScheme() {
        return new getAllGateways_resultTupleScheme();
      }
    }

    private static class getAllGateways_resultTupleScheme extends TupleScheme<getAllGateways_result> {

      @Override
      public void write(org.apache.thrift.protocol.TProtocol prot, getAllGateways_result struct) throws org.apache.thrift.TException {
        TTupleProtocol oprot = (TTupleProtocol) prot;
        BitSet optionals = new BitSet();
        if (struct.isSetSuccess()) {
          optionals.set(0);
        }
        if (struct.isSetIre()) {
          optionals.set(1);
        }
        if (struct.isSetAce()) {
          optionals.set(2);
        }
        if (struct.isSetAse()) {
          optionals.set(3);
        }
        if (struct.isSetAe()) {
          optionals.set(4);
        }
        oprot.writeBitSet(optionals, 5);
        if (struct.isSetSuccess()) {
          {
            oprot.writeI32(struct.success.size());
            for (org.apache.airavata.model.workspace.Gateway _iter4 : struct.success)
            {
              _iter4.write(oprot);
            }
          }
        }
        if (struct.isSetIre()) {
          struct.ire.write(oprot);
        }
        if (struct.isSetAce()) {
          struct.ace.write(oprot);
        }
        if (struct.isSetAse()) {
          struct.ase.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 {
        TTupleProtocol iprot = (TTupleProtocol) prot;
        BitSet incoming = iprot.readBitSet(5);
        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 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.ire = new org.apache.airavata.model.error.InvalidRequestException();
          struct.ire.read(iprot);
          struct.setIreIsSet(true);
        }
        if (incoming.get(2)) {
          struct.ace = new org.apache.airavata.model.error.AiravataClientException();
          struct.ace.read(iprot);
          struct.setAceIsSet(true);
        }
        if (incoming.get(3)) {
          struct.ase = new org.apache.airavata.model.error.AiravataSystemException();
          struct.ase.read(iprot);
          struct.setAseIsSet(true);
        }
        if (incoming.get(4)) {
          struct.ae = new org.apache.airavata.model.error.AuthorizationException();
          struct.ae.read(iprot);
          struct.setAeIsSet(true);
        }
      }
    }

  }

  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 Map<Class<? extends IScheme>, SchemeFactory> schemes = new HashMap<Class<? extends IScheme>, SchemeFactory>();
    static {
      schemes.put(StandardScheme.class, new isGatewayExist_argsStandardSchemeFactory());
      schemes.put(TupleScheme.class, new isGatewayExist_argsTupleSchemeFactory());
    }

    public org.apache.airavata.model.security.AuthzToken authzToken; // required
    public 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 Map<String, _Fields> byName = new HashMap<String, _Fields>();

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

      /**
       * Find the _Fields constant that matches fieldId, or null if its not found.
       */
      public static _Fields findByThriftId(int fieldId) {
        switch(fieldId) {
          case 1: // 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 IllegalArgumentException("Field " + fieldId + " doesn't exist!");
        return fields;
      }

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

      private final short _thriftId;
      private final String _fieldName;

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

      public short getThriftFieldId() {
        return _thriftId;
      }

      public String getFieldName() {
        return _fieldName;
      }
    }

    // isset id assignments
    public static final Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
    static {
      Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new EnumMap<_Fields, org.apache.thrift.meta_data.FieldMetaData>(_Fields.class);
      tmpMap.put(_Fields.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 = 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,
      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 String getGatewayId() {
      return this.gatewayId;
    }

    public isGatewayExist_args setGatewayId(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, 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((String)value);
        }
        break;

      }
    }

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

      case GATEWAY_ID:
        return getGatewayId();

      }
      throw new IllegalStateException();
    }

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

      switch (field) {
      case AUTHZ_TOKEN:
        return isSetAuthzToken();
      case GATEWAY_ID:
        return isSetGatewayId();
      }
      throw new IllegalStateException();
    }

    @Override
    public boolean equals(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;

      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() {
      List<Object> list = new ArrayList<Object>();

      boolean present_authzToken = true && (isSetAuthzToken());
      list.add(present_authzToken);
      if (present_authzToken)
        list.add(authzToken);

      boolean present_gatewayId = true && (isSetGatewayId());
      list.add(present_gatewayId);
      if (present_gatewayId)
        list.add(gatewayId);

      return list.hashCode();
    }

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

      int lastComparison = 0;

      lastComparison = 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 = 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 {
      schemes.get(iprot.getScheme()).getScheme().read(iprot, this);
    }

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

    @Override
    public String toString() {
      StringBuilder sb = new StringBuilder("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, 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 SchemeFactory {
      public isGatewayExist_argsStandardScheme getScheme() {
        return new isGatewayExist_argsStandardScheme();
      }
    }

    private static class isGatewayExist_argsStandardScheme extends 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 SchemeFactory {
      public isGatewayExist_argsTupleScheme getScheme() {
        return new isGatewayExist_argsTupleScheme();
      }
    }

    private static class isGatewayExist_argsTupleScheme extends TupleScheme<isGatewayExist_args> {

      @Override
      public void write(org.apache.thrift.protocol.TProtocol prot, isGatewayExist_args struct) throws org.apache.thrift.TException {
        TTupleProtocol oprot = (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 {
        TTupleProtocol iprot = (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);
      }
    }

  }

  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 IRE_FIELD_DESC = new org.apache.thrift.protocol.TField("ire", org.apache.thrift.protocol.TType.STRUCT, (short)1);
    private static final org.apache.thrift.protocol.TField ACE_FIELD_DESC = new org.apache.thrift.protocol.TField("ace", org.apache.thrift.protocol.TType.STRUCT, (short)2);
    private static final org.apache.thrift.protocol.TField ASE_FIELD_DESC = new org.apache.thrift.protocol.TField("ase", org.apache.thrift.protocol.TType.STRUCT, (short)3);
    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)4);

    private static final Map<Class<? extends IScheme>, SchemeFactory> schemes = new HashMap<Class<? extends IScheme>, SchemeFactory>();
    static {
      schemes.put(StandardScheme.class, new isGatewayExist_resultStandardSchemeFactory());
      schemes.put(TupleScheme.class, new isGatewayExist_resultTupleSchemeFactory());
    }

    public boolean success; // required
    public org.apache.airavata.model.error.InvalidRequestException ire; // required
    public org.apache.airavata.model.error.AiravataClientException ace; // required
    public org.apache.airavata.model.error.AiravataSystemException ase; // 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"),
      IRE((short)1, "ire"),
      ACE((short)2, "ace"),
      ASE((short)3, "ase"),
      AE((short)4, "ae");

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

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

      /**
       * Find the _Fields constant that matches fieldId, or null if its not found.
       */
      public static _Fields findByThriftId(int fieldId) {
        switch(fieldId) {
          case 0: // SUCCESS
            return SUCCESS;
          case 1: // IRE
            return IRE;
          case 2: // ACE
            return ACE;
          case 3: // ASE
            return ASE;
          case 4: // 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 IllegalArgumentException("Field " + fieldId + " doesn't exist!");
        return fields;
      }

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

      private final short _thriftId;
      private final String _fieldName;

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

      public short getThriftFieldId() {
        return _thriftId;
      }

      public String getFieldName() {
        return _fieldName;
      }
    }

    // isset id assignments
    private static final int __SUCCESS_ISSET_ID = 0;
    private byte __isset_bitfield = 0;
    public static final Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
    static {
      Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new EnumMap<_Fields, org.apache.thrift.meta_data.FieldMetaData>(_Fields.class);
      tmpMap.put(_Fields.SUCCESS, new org.apache.thrift.meta_data.FieldMetaData("success", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.BOOL)));
      tmpMap.put(_Fields.IRE, new org.apache.thrift.meta_data.FieldMetaData("ire", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRUCT)));
      tmpMap.put(_Fields.ACE, new org.apache.thrift.meta_data.FieldMetaData("ace", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRUCT)));
      tmpMap.put(_Fields.ASE, new org.apache.thrift.meta_data.FieldMetaData("ase", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRUCT)));
      tmpMap.put(_Fields.AE, new org.apache.thrift.meta_data.FieldMetaData("ae", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRUCT)));
      metaDataMap = Collections.unmodifiableMap(tmpMap);
      org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(isGatewayExist_result.class, metaDataMap);
    }

    public isGatewayExist_result() {
    }

    public isGatewayExist_result(
      boolean success,
      org.apache.airavata.model.error.InvalidRequestException ire,
      org.apache.airavata.model.error.AiravataClientException ace,
      org.apache.airavata.model.error.AiravataSystemException ase,
      org.apache.airavata.model.error.AuthorizationException ae)
    {
      this();
      this.success = success;
      setSuccessIsSet(true);
      this.ire = ire;
      this.ace = ace;
      this.ase = ase;
      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.isSetIre()) {
        this.ire = new org.apache.airavata.model.error.InvalidRequestException(other.ire);
      }
      if (other.isSetAce()) {
        this.ace = new org.apache.airavata.model.error.AiravataClientException(other.ace);
      }
      if (other.isSetAse()) {
        this.ase = new org.apache.airavata.model.error.AiravataSystemException(other.ase);
      }
      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.ire = null;
      this.ace = null;
      this.ase = 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 = EncodingUtils.clearBit(__isset_bitfield, __SUCCESS_ISSET_ID);
    }

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

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

    public org.apache.airavata.model.error.InvalidRequestException getIre() {
      return this.ire;
    }

    public isGatewayExist_result setIre(org.apache.airavata.model.error.InvalidRequestException ire) {
      this.ire = ire;
      return this;
    }

    public void unsetIre() {
      this.ire = null;
    }

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

    public void setIreIsSet(boolean value) {
      if (!value) {
        this.ire = null;
      }
    }

    public org.apache.airavata.model.error.AiravataClientException getAce() {
      return this.ace;
    }

    public isGatewayExist_result setAce(org.apache.airavata.model.error.AiravataClientException ace) {
      this.ace = ace;
      return this;
    }

    public void unsetAce() {
      this.ace = null;
    }

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

    public void setAceIsSet(boolean value) {
      if (!value) {
        this.ace = null;
      }
    }

    public org.apache.airavata.model.error.AiravataSystemException getAse() {
      return this.ase;
    }

    public isGatewayExist_result setAse(org.apache.airavata.model.error.AiravataSystemException ase) {
      this.ase = ase;
      return this;
    }

    public void unsetAse() {
      this.ase = null;
    }

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

    public void setAseIsSet(boolean value) {
      if (!value) {
        this.ase = 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, Object value) {
      switch (field) {
      case SUCCESS:
        if (value == null) {
          unsetSuccess();
        } else {
          setSuccess((Boolean)value);
        }
        break;

      case IRE:
        if (value == null) {
          unsetIre();
        } else {
          setIre((org.apache.airavata.model.error.InvalidRequestException)value);
        }
        break;

      case ACE:
        if (value == null) {
          unsetAce();
        } else {
          setAce((org.apache.airavata.model.error.AiravataClientException)value);
        }
        break;

      case ASE:
        if (value == null) {
          unsetAse();
        } else {
          setAse((org.apache.airavata.model.error.AiravataSystemException)value);
        }
        break;

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

      }
    }

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

      case IRE:
        return getIre();

      case ACE:
        return getAce();

      case ASE:
        return getAse();

      case AE:
        return getAe();

      }
      throw new IllegalStateException();
    }

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

      switch (field) {
      case SUCCESS:
        return isSetSuccess();
      case IRE:
        return isSetIre();
      case ACE:
        return isSetAce();
      case ASE:
        return isSetAse();
      case AE:
        return isSetAe();
      }
      throw new IllegalStateException();
    }

    @Override
    public boolean equals(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;

      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_ire = true && this.isSetIre();
      boolean that_present_ire = true && that.isSetIre();
      if (this_present_ire || that_present_ire) {
        if (!(this_present_ire && that_present_ire))
          return false;
        if (!this.ire.equals(that.ire))
          return false;
      }

      boolean this_present_ace = true && this.isSetAce();
      boolean that_present_ace = true && that.isSetAce();
      if (this_present_ace || that_present_ace) {
        if (!(this_present_ace && that_present_ace))
          return false;
        if (!this.ace.equals(that.ace))
          return false;
      }

      boolean this_present_ase = true && this.isSetAse();
      boolean that_present_ase = true && that.isSetAse();
      if (this_present_ase || that_present_ase) {
        if (!(this_present_ase && that_present_ase))
          return false;
        if (!this.ase.equals(that.ase))
          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() {
      List<Object> list = new ArrayList<Object>();

      boolean present_success = true;
      list.add(present_success);
      if (present_success)
        list.add(success);

      boolean present_ire = true && (isSetIre());
      list.add(present_ire);
      if (present_ire)
        list.add(ire);

      boolean present_ace = true && (isSetAce());
      list.add(present_ace);
      if (present_ace)
        list.add(ace);

      boolean present_ase = true && (isSetAse());
      list.add(present_ase);
      if (present_ase)
        list.add(ase);

      boolean present_ae = true && (isSetAe());
      list.add(present_ae);
      if (present_ae)
        list.add(ae);

      return list.hashCode();
    }

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

      int lastComparison = 0;

      lastComparison = Boolean.valueOf(isSetSuccess()).compareTo(other.isSetSuccess());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetSuccess()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.success, other.success);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = Boolean.valueOf(isSetIre()).compareTo(other.isSetIre());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetIre()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.ire, other.ire);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = Boolean.valueOf(isSetAce()).compareTo(other.isSetAce());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetAce()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.ace, other.ace);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = Boolean.valueOf(isSetAse()).compareTo(other.isSetAse());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetAse()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.ase, other.ase);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = 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 {
      schemes.get(iprot.getScheme()).getScheme().read(iprot, this);
    }

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

    @Override
    public String toString() {
      StringBuilder sb = new StringBuilder("isGatewayExist_result(");
      boolean first = true;

      sb.append("success:");
      sb.append(this.success);
      first = false;
      if (!first) sb.append(", ");
      sb.append("ire:");
      if (this.ire == null) {
        sb.append("null");
      } else {
        sb.append(this.ire);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("ace:");
      if (this.ace == null) {
        sb.append("null");
      } else {
        sb.append(this.ace);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("ase:");
      if (this.ase == null) {
        sb.append("null");
      } else {
        sb.append(this.ase);
      }
      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, 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 SchemeFactory {
      public isGatewayExist_resultStandardScheme getScheme() {
        return new isGatewayExist_resultStandardScheme();
      }
    }

    private static class isGatewayExist_resultStandardScheme extends 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: // IRE
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.ire = new org.apache.airavata.model.error.InvalidRequestException();
                struct.ire.read(iprot);
                struct.setIreIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 2: // ACE
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.ace = new org.apache.airavata.model.error.AiravataClientException();
                struct.ace.read(iprot);
                struct.setAceIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 3: // ASE
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.ase = new org.apache.airavata.model.error.AiravataSystemException();
                struct.ase.read(iprot);
                struct.setAseIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 4: // 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.ire != null) {
          oprot.writeFieldBegin(IRE_FIELD_DESC);
          struct.ire.write(oprot);
          oprot.writeFieldEnd();
        }
        if (struct.ace != null) {
          oprot.writeFieldBegin(ACE_FIELD_DESC);
          struct.ace.write(oprot);
          oprot.writeFieldEnd();
        }
        if (struct.ase != null) {
          oprot.writeFieldBegin(ASE_FIELD_DESC);
          struct.ase.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 SchemeFactory {
      public isGatewayExist_resultTupleScheme getScheme() {
        return new isGatewayExist_resultTupleScheme();
      }
    }

    private static class isGatewayExist_resultTupleScheme extends TupleScheme<isGatewayExist_result> {

      @Override
      public void write(org.apache.thrift.protocol.TProtocol prot, isGatewayExist_result struct) throws org.apache.thrift.TException {
        TTupleProtocol oprot = (TTupleProtocol) prot;
        BitSet optionals = new BitSet();
        if (struct.isSetSuccess()) {
          optionals.set(0);
        }
        if (struct.isSetIre()) {
          optionals.set(1);
        }
        if (struct.isSetAce()) {
          optionals.set(2);
        }
        if (struct.isSetAse()) {
          optionals.set(3);
        }
        if (struct.isSetAe()) {
          optionals.set(4);
        }
        oprot.writeBitSet(optionals, 5);
        if (struct.isSetSuccess()) {
          oprot.writeBool(struct.success);
        }
        if (struct.isSetIre()) {
          struct.ire.write(oprot);
        }
        if (struct.isSetAce()) {
          struct.ace.write(oprot);
        }
        if (struct.isSetAse()) {
          struct.ase.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 {
        TTupleProtocol iprot = (TTupleProtocol) prot;
        BitSet incoming = iprot.readBitSet(5);
        if (incoming.get(0)) {
          struct.success = iprot.readBool();
          struct.setSuccessIsSet(true);
        }
        if (incoming.get(1)) {
          struct.ire = new org.apache.airavata.model.error.InvalidRequestException();
          struct.ire.read(iprot);
          struct.setIreIsSet(true);
        }
        if (incoming.get(2)) {
          struct.ace = new org.apache.airavata.model.error.AiravataClientException();
          struct.ace.read(iprot);
          struct.setAceIsSet(true);
        }
        if (incoming.get(3)) {
          struct.ase = new org.apache.airavata.model.error.AiravataSystemException();
          struct.ase.read(iprot);
          struct.setAseIsSet(true);
        }
        if (incoming.get(4)) {
          struct.ae = new org.apache.airavata.model.error.AuthorizationException();
          struct.ae.read(iprot);
          struct.setAeIsSet(true);
        }
      }
    }

  }

  public static class generateAndRegisterSSHKeys_args implements org.apache.thrift.TBase<generateAndRegisterSSHKeys_args, generateAndRegisterSSHKeys_args._Fields>, java.io.Serializable, Cloneable, Comparable<generateAndRegisterSSHKeys_args>   {
    private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("generateAndRegisterSSHKeys_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.protocol.TField USER_NAME_FIELD_DESC = new org.apache.thrift.protocol.TField("userName", org.apache.thrift.protocol.TType.STRING, (short)3);

    private static final Map<Class<? extends IScheme>, SchemeFactory> schemes = new HashMap<Class<? extends IScheme>, SchemeFactory>();
    static {
      schemes.put(StandardScheme.class, new generateAndRegisterSSHKeys_argsStandardSchemeFactory());
      schemes.put(TupleScheme.class, new generateAndRegisterSSHKeys_argsTupleSchemeFactory());
    }

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

    /** 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"),
      USER_NAME((short)3, "userName");

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

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

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

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

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

      private final short _thriftId;
      private final String _fieldName;

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

      public short getThriftFieldId() {
        return _thriftId;
      }

      public String getFieldName() {
        return _fieldName;
      }
    }

    // isset id assignments
    public static final Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
    static {
      Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new EnumMap<_Fields, org.apache.thrift.meta_data.FieldMetaData>(_Fields.class);
      tmpMap.put(_Fields.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)));
      tmpMap.put(_Fields.USER_NAME, new org.apache.thrift.meta_data.FieldMetaData("userName", org.apache.thrift.TFieldRequirementType.REQUIRED, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING)));
      metaDataMap = Collections.unmodifiableMap(tmpMap);
      org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(generateAndRegisterSSHKeys_args.class, metaDataMap);
    }

    public generateAndRegisterSSHKeys_args() {
    }

    public generateAndRegisterSSHKeys_args(
      org.apache.airavata.model.security.AuthzToken authzToken,
      String gatewayId,
      String userName)
    {
      this();
      this.authzToken = authzToken;
      this.gatewayId = gatewayId;
      this.userName = userName;
    }

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

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

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

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

    public generateAndRegisterSSHKeys_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 String getGatewayId() {
      return this.gatewayId;
    }

    public generateAndRegisterSSHKeys_args setGatewayId(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 String getUserName() {
      return this.userName;
    }

    public generateAndRegisterSSHKeys_args setUserName(String userName) {
      this.userName = userName;
      return this;
    }

    public void unsetUserName() {
      this.userName = null;
    }

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

    public void setUserNameIsSet(boolean value) {
      if (!value) {
        this.userName = null;
      }
    }

    public void setFieldValue(_Fields field, 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((String)value);
        }
        break;

      case USER_NAME:
        if (value == null) {
          unsetUserName();
        } else {
          setUserName((String)value);
        }
        break;

      }
    }

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

      case GATEWAY_ID:
        return getGatewayId();

      case USER_NAME:
        return getUserName();

      }
      throw new IllegalStateException();
    }

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

      switch (field) {
      case AUTHZ_TOKEN:
        return isSetAuthzToken();
      case GATEWAY_ID:
        return isSetGatewayId();
      case USER_NAME:
        return isSetUserName();
      }
      throw new IllegalStateException();
    }

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

    public boolean equals(generateAndRegisterSSHKeys_args that) {
      if (that == null)
        return false;

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

      boolean this_present_userName = true && this.isSetUserName();
      boolean that_present_userName = true && that.isSetUserName();
      if (this_present_userName || that_present_userName) {
        if (!(this_present_userName && that_present_userName))
          return false;
        if (!this.userName.equals(that.userName))
          return false;
      }

      return true;
    }

    @Override
    public int hashCode() {
      List<Object> list = new ArrayList<Object>();

      boolean present_authzToken = true && (isSetAuthzToken());
      list.add(present_authzToken);
      if (present_authzToken)
        list.add(authzToken);

      boolean present_gatewayId = true && (isSetGatewayId());
      list.add(present_gatewayId);
      if (present_gatewayId)
        list.add(gatewayId);

      boolean present_userName = true && (isSetUserName());
      list.add(present_userName);
      if (present_userName)
        list.add(userName);

      return list.hashCode();
    }

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

      int lastComparison = 0;

      lastComparison = 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 = 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;
        }
      }
      lastComparison = Boolean.valueOf(isSetUserName()).compareTo(other.isSetUserName());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetUserName()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.userName, other.userName);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      return 0;
    }

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

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

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

    @Override
    public String toString() {
      StringBuilder sb = new StringBuilder("generateAndRegisterSSHKeys_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;
      if (!first) sb.append(", ");
      sb.append("userName:");
      if (this.userName == null) {
        sb.append("null");
      } else {
        sb.append(this.userName);
      }
      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());
      }
      if (userName == null) {
        throw new org.apache.thrift.protocol.TProtocolException("Required field 'userName' 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, 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 generateAndRegisterSSHKeys_argsStandardSchemeFactory implements SchemeFactory {
      public generateAndRegisterSSHKeys_argsStandardScheme getScheme() {
        return new generateAndRegisterSSHKeys_argsStandardScheme();
      }
    }

    private static class generateAndRegisterSSHKeys_argsStandardScheme extends StandardScheme<generateAndRegisterSSHKeys_args> {

      public void read(org.apache.thrift.protocol.TProtocol iprot, generateAndRegisterSSHKeys_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;
            case 3: // USER_NAME
              if (schemeField.type == org.apache.thrift.protocol.TType.STRING) {
                struct.userName = iprot.readString();
                struct.setUserNameIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            default:
              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
          }
          iprot.readFieldEnd();
        }
        iprot.readStructEnd();

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

      public void write(org.apache.thrift.protocol.TProtocol oprot, generateAndRegisterSSHKeys_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();
        }
        if (struct.userName != null) {
          oprot.writeFieldBegin(USER_NAME_FIELD_DESC);
          oprot.writeString(struct.userName);
          oprot.writeFieldEnd();
        }
        oprot.writeFieldStop();
        oprot.writeStructEnd();
      }

    }

    private static class generateAndRegisterSSHKeys_argsTupleSchemeFactory implements SchemeFactory {
      public generateAndRegisterSSHKeys_argsTupleScheme getScheme() {
        return new generateAndRegisterSSHKeys_argsTupleScheme();
      }
    }

    private static class generateAndRegisterSSHKeys_argsTupleScheme extends TupleScheme<generateAndRegisterSSHKeys_args> {

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

      @Override
      public void read(org.apache.thrift.protocol.TProtocol prot, generateAndRegisterSSHKeys_args struct) throws org.apache.thrift.TException {
        TTupleProtocol iprot = (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);
        struct.userName = iprot.readString();
        struct.setUserNameIsSet(true);
      }
    }

  }

  public static class generateAndRegisterSSHKeys_result implements org.apache.thrift.TBase<generateAndRegisterSSHKeys_result, generateAndRegisterSSHKeys_result._Fields>, java.io.Serializable, Cloneable, Comparable<generateAndRegisterSSHKeys_result>   {
    private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("generateAndRegisterSSHKeys_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 IRE_FIELD_DESC = new org.apache.thrift.protocol.TField("ire", org.apache.thrift.protocol.TType.STRUCT, (short)1);
    private static final org.apache.thrift.protocol.TField ACE_FIELD_DESC = new org.apache.thrift.protocol.TField("ace", org.apache.thrift.protocol.TType.STRUCT, (short)2);
    private static final org.apache.thrift.protocol.TField ASE_FIELD_DESC = new org.apache.thrift.protocol.TField("ase", org.apache.thrift.protocol.TType.STRUCT, (short)3);

    private static final Map<Class<? extends IScheme>, SchemeFactory> schemes = new HashMap<Class<? extends IScheme>, SchemeFactory>();
    static {
      schemes.put(StandardScheme.class, new generateAndRegisterSSHKeys_resultStandardSchemeFactory());
      schemes.put(TupleScheme.class, new generateAndRegisterSSHKeys_resultTupleSchemeFactory());
    }

    public String success; // required
    public org.apache.airavata.model.error.InvalidRequestException ire; // required
    public org.apache.airavata.model.error.AiravataClientException ace; // required
    public org.apache.airavata.model.error.AiravataSystemException ase; // required

    /** 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"),
      IRE((short)1, "ire"),
      ACE((short)2, "ace"),
      ASE((short)3, "ase");

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

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

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

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

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

      private final short _thriftId;
      private final String _fieldName;

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

      public short getThriftFieldId() {
        return _thriftId;
      }

      public String getFieldName() {
        return _fieldName;
      }
    }

    // isset id assignments
    public static final Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
    static {
      Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new EnumMap<_Fields, org.apache.thrift.meta_data.FieldMetaData>(_Fields.class);
      tmpMap.put(_Fields.SUCCESS, new org.apache.thrift.meta_data.FieldMetaData("success", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING)));
      tmpMap.put(_Fields.IRE, new org.apache.thrift.meta_data.FieldMetaData("ire", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRUCT)));
      tmpMap.put(_Fields.ACE, new org.apache.thrift.meta_data.FieldMetaData("ace", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRUCT)));
      tmpMap.put(_Fields.ASE, new org.apache.thrift.meta_data.FieldMetaData("ase", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRUCT)));
      metaDataMap = Collections.unmodifiableMap(tmpMap);
      org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(generateAndRegisterSSHKeys_result.class, metaDataMap);
    }

    public generateAndRegisterSSHKeys_result() {
    }

    public generateAndRegisterSSHKeys_result(
      String success,
      org.apache.airavata.model.error.InvalidRequestException ire,
      org.apache.airavata.model.error.AiravataClientException ace,
      org.apache.airavata.model.error.AiravataSystemException ase)
    {
      this();
      this.success = success;
      this.ire = ire;
      this.ace = ace;
      this.ase = ase;
    }

    /**
     * Performs a deep copy on <i>other</i>.
     */
    public generateAndRegisterSSHKeys_result(generateAndRegisterSSHKeys_result other) {
      if (other.isSetSuccess()) {
        this.success = other.success;
      }
      if (other.isSetIre()) {
        this.ire = new org.apache.airavata.model.error.InvalidRequestException(other.ire);
      }
      if (other.isSetAce()) {
        this.ace = new org.apache.airavata.model.error.AiravataClientException(other.ace);
      }
      if (other.isSetAse()) {
        this.ase = new org.apache.airavata.model.error.AiravataSystemException(other.ase);
      }
    }

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

    @Override
    public void clear() {
      this.success = null;
      this.ire = null;
      this.ace = null;
      this.ase = null;
    }

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

    public generateAndRegisterSSHKeys_result setSuccess(String success) {
      this.success = success;
      return this;
    }

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

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

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

    public org.apache.airavata.model.error.InvalidRequestException getIre() {
      return this.ire;
    }

    public generateAndRegisterSSHKeys_result setIre(org.apache.airavata.model.error.InvalidRequestException ire) {
      this.ire = ire;
      return this;
    }

    public void unsetIre() {
      this.ire = null;
    }

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

    public void setIreIsSet(boolean value) {
      if (!value) {
        this.ire = null;
      }
    }

    public org.apache.airavata.model.error.AiravataClientException getAce() {
      return this.ace;
    }

    public generateAndRegisterSSHKeys_result setAce(org.apache.airavata.model.error.AiravataClientException ace) {
      this.ace = ace;
      return this;
    }

    public void unsetAce() {
      this.ace = null;
    }

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

    public void setAceIsSet(boolean value) {
      if (!value) {
        this.ace = null;
      }
    }

    public org.apache.airavata.model.error.AiravataSystemException getAse() {
      return this.ase;
    }

    public generateAndRegisterSSHKeys_result setAse(org.apache.airavata.model.error.AiravataSystemException ase) {
      this.ase = ase;
      return this;
    }

    public void unsetAse() {
      this.ase = null;
    }

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

    public void setAseIsSet(boolean value) {
      if (!value) {
        this.ase = null;
      }
    }

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

      case IRE:
        if (value == null) {
          unsetIre();
        } else {
          setIre((org.apache.airavata.model.error.InvalidRequestException)value);
        }
        break;

      case ACE:
        if (value == null) {
          unsetAce();
        } else {
          setAce((org.apache.airavata.model.error.AiravataClientException)value);
        }
        break;

      case ASE:
        if (value == null) {
          unsetAse();
        } else {
          setAse((org.apache.airavata.model.error.AiravataSystemException)value);
        }
        break;

      }
    }

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

      case IRE:
        return getIre();

      case ACE:
        return getAce();

      case ASE:
        return getAse();

      }
      throw new IllegalStateException();
    }

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

      switch (field) {
      case SUCCESS:
        return isSetSuccess();
      case IRE:
        return isSetIre();
      case ACE:
        return isSetAce();
      case ASE:
        return isSetAse();
      }
      throw new IllegalStateException();
    }

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

    public boolean equals(generateAndRegisterSSHKeys_result that) {
      if (that == null)
        return false;

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

      boolean this_present_ire = true && this.isSetIre();
      boolean that_present_ire = true && that.isSetIre();
      if (this_present_ire || that_present_ire) {
        if (!(this_present_ire && that_present_ire))
          return false;
        if (!this.ire.equals(that.ire))
          return false;
      }

      boolean this_present_ace = true && this.isSetAce();
      boolean that_present_ace = true && that.isSetAce();
      if (this_present_ace || that_present_ace) {
        if (!(this_present_ace && that_present_ace))
          return false;
        if (!this.ace.equals(that.ace))
          return false;
      }

      boolean this_present_ase = true && this.isSetAse();
      boolean that_present_ase = true && that.isSetAse();
      if (this_present_ase || that_present_ase) {
        if (!(this_present_ase && that_present_ase))
          return false;
        if (!this.ase.equals(that.ase))
          return false;
      }

      return true;
    }

    @Override
    public int hashCode() {
      List<Object> list = new ArrayList<Object>();

      boolean present_success = true && (isSetSuccess());
      list.add(present_success);
      if (present_success)
        list.add(success);

      boolean present_ire = true && (isSetIre());
      list.add(present_ire);
      if (present_ire)
        list.add(ire);

      boolean present_ace = true && (isSetAce());
      list.add(present_ace);
      if (present_ace)
        list.add(ace);

      boolean present_ase = true && (isSetAse());
      list.add(present_ase);
      if (present_ase)
        list.add(ase);

      return list.hashCode();
    }

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

      int lastComparison = 0;

      lastComparison = Boolean.valueOf(isSetSuccess()).compareTo(other.isSetSuccess());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetSuccess()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.success, other.success);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = Boolean.valueOf(isSetIre()).compareTo(other.isSetIre());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetIre()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.ire, other.ire);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = Boolean.valueOf(isSetAce()).compareTo(other.isSetAce());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetAce()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.ace, other.ace);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = Boolean.valueOf(isSetAse()).compareTo(other.isSetAse());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetAse()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.ase, other.ase);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      return 0;
    }

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

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

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

    @Override
    public String toString() {
      StringBuilder sb = new StringBuilder("generateAndRegisterSSHKeys_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("ire:");
      if (this.ire == null) {
        sb.append("null");
      } else {
        sb.append(this.ire);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("ace:");
      if (this.ace == null) {
        sb.append("null");
      } else {
        sb.append(this.ace);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("ase:");
      if (this.ase == null) {
        sb.append("null");
      } else {
        sb.append(this.ase);
      }
      first = false;
      sb.append(")");
      return sb.toString();
    }

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

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

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

    private static class generateAndRegisterSSHKeys_resultStandardSchemeFactory implements SchemeFactory {
      public generateAndRegisterSSHKeys_resultStandardScheme getScheme() {
        return new generateAndRegisterSSHKeys_resultStandardScheme();
      }
    }

    private static class generateAndRegisterSSHKeys_resultStandardScheme extends StandardScheme<generateAndRegisterSSHKeys_result> {

      public void read(org.apache.thrift.protocol.TProtocol iprot, generateAndRegisterSSHKeys_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: // IRE
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.ire = new org.apache.airavata.model.error.InvalidRequestException();
                struct.ire.read(iprot);
                struct.setIreIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 2: // ACE
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.ace = new org.apache.airavata.model.error.AiravataClientException();
                struct.ace.read(iprot);
                struct.setAceIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 3: // ASE
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.ase = new org.apache.airavata.model.error.AiravataSystemException();
                struct.ase.read(iprot);
                struct.setAseIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            default:
              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
          }
          iprot.readFieldEnd();
        }
        iprot.readStructEnd();

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

      public void write(org.apache.thrift.protocol.TProtocol oprot, generateAndRegisterSSHKeys_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.ire != null) {
          oprot.writeFieldBegin(IRE_FIELD_DESC);
          struct.ire.write(oprot);
          oprot.writeFieldEnd();
        }
        if (struct.ace != null) {
          oprot.writeFieldBegin(ACE_FIELD_DESC);
          struct.ace.write(oprot);
          oprot.writeFieldEnd();
        }
        if (struct.ase != null) {
          oprot.writeFieldBegin(ASE_FIELD_DESC);
          struct.ase.write(oprot);
          oprot.writeFieldEnd();
        }
        oprot.writeFieldStop();
        oprot.writeStructEnd();
      }

    }

    private static class generateAndRegisterSSHKeys_resultTupleSchemeFactory implements SchemeFactory {
      public generateAndRegisterSSHKeys_resultTupleScheme getScheme() {
        return new generateAndRegisterSSHKeys_resultTupleScheme();
      }
    }

    private static class generateAndRegisterSSHKeys_resultTupleScheme extends TupleScheme<generateAndRegisterSSHKeys_result> {

      @Override
      public void write(org.apache.thrift.protocol.TProtocol prot, generateAndRegisterSSHKeys_result struct) throws org.apache.thrift.TException {
        TTupleProtocol oprot = (TTupleProtocol) prot;
        BitSet optionals = new BitSet();
        if (struct.isSetSuccess()) {
          optionals.set(0);
        }
        if (struct.isSetIre()) {
          optionals.set(1);
        }
        if (struct.isSetAce()) {
          optionals.set(2);
        }
        if (struct.isSetAse()) {
          optionals.set(3);
        }
        oprot.writeBitSet(optionals, 4);
        if (struct.isSetSuccess()) {
          oprot.writeString(struct.success);
        }
        if (struct.isSetIre()) {
          struct.ire.write(oprot);
        }
        if (struct.isSetAce()) {
          struct.ace.write(oprot);
        }
        if (struct.isSetAse()) {
          struct.ase.write(oprot);
        }
      }

      @Override
      public void read(org.apache.thrift.protocol.TProtocol prot, generateAndRegisterSSHKeys_result struct) throws org.apache.thrift.TException {
        TTupleProtocol iprot = (TTupleProtocol) prot;
        BitSet incoming = iprot.readBitSet(4);
        if (incoming.get(0)) {
          struct.success = iprot.readString();
          struct.setSuccessIsSet(true);
        }
        if (incoming.get(1)) {
          struct.ire = new org.apache.airavata.model.error.InvalidRequestException();
          struct.ire.read(iprot);
          struct.setIreIsSet(true);
        }
        if (incoming.get(2)) {
          struct.ace = new org.apache.airavata.model.error.AiravataClientException();
          struct.ace.read(iprot);
          struct.setAceIsSet(true);
        }
        if (incoming.get(3)) {
          struct.ase = new org.apache.airavata.model.error.AiravataSystemException();
          struct.ase.read(iprot);
          struct.setAseIsSet(true);
        }
      }
    }

  }

  public static class getSSHPubKey_args implements org.apache.thrift.TBase<getSSHPubKey_args, getSSHPubKey_args._Fields>, java.io.Serializable, Cloneable, Comparable<getSSHPubKey_args>   {
    private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("getSSHPubKey_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_CRED_STORE_TOKEN_FIELD_DESC = new org.apache.thrift.protocol.TField("airavataCredStoreToken", 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 Map<Class<? extends IScheme>, SchemeFactory> schemes = new HashMap<Class<? extends IScheme>, SchemeFactory>();
    static {
      schemes.put(StandardScheme.class, new getSSHPubKey_argsStandardSchemeFactory());
      schemes.put(TupleScheme.class, new getSSHPubKey_argsTupleSchemeFactory());
    }

    public org.apache.airavata.model.security.AuthzToken authzToken; // required
    public String airavataCredStoreToken; // required
    public 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_CRED_STORE_TOKEN((short)2, "airavataCredStoreToken"),
      GATEWAY_ID((short)3, "gatewayId");

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

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

      /**
       * Find the _Fields constant that matches fieldId, or null if its not found.
       */
      public static _Fields findByThriftId(int fieldId) {
        switch(fieldId) {
          case 1: // AUTHZ_TOKEN
            return AUTHZ_TOKEN;
          case 2: // AIRAVATA_CRED_STORE_TOKEN
            return AIRAVATA_CRED_STORE_TOKEN;
          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 IllegalArgumentException("Field " + fieldId + " doesn't exist!");
        return fields;
      }

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

      private final short _thriftId;
      private final String _fieldName;

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

      public short getThriftFieldId() {
        return _thriftId;
      }

      public String getFieldName() {
        return _fieldName;
      }
    }

    // isset id assignments
    public static final Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
    static {
      Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new EnumMap<_Fields, org.apache.thrift.meta_data.FieldMetaData>(_Fields.class);
      tmpMap.put(_Fields.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_CRED_STORE_TOKEN, new org.apache.thrift.meta_data.FieldMetaData("airavataCredStoreToken", 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 = Collections.unmodifiableMap(tmpMap);
      org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(getSSHPubKey_args.class, metaDataMap);
    }

    public getSSHPubKey_args() {
    }

    public getSSHPubKey_args(
      org.apache.airavata.model.security.AuthzToken authzToken,
      String airavataCredStoreToken,
      String gatewayId)
    {
      this();
      this.authzToken = authzToken;
      this.airavataCredStoreToken = airavataCredStoreToken;
      this.gatewayId = gatewayId;
    }

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

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

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

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

    public getSSHPubKey_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 String getAiravataCredStoreToken() {
      return this.airavataCredStoreToken;
    }

    public getSSHPubKey_args setAiravataCredStoreToken(String airavataCredStoreToken) {
      this.airavataCredStoreToken = airavataCredStoreToken;
      return this;
    }

    public void unsetAiravataCredStoreToken() {
      this.airavataCredStoreToken = null;
    }

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

    public void setAiravataCredStoreTokenIsSet(boolean value) {
      if (!value) {
        this.airavataCredStoreToken = null;
      }
    }

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

    public getSSHPubKey_args setGatewayId(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, Object value) {
      switch (field) {
      case AUTHZ_TOKEN:
        if (value == null) {
          unsetAuthzToken();
        } else {
          setAuthzToken((org.apache.airavata.model.security.AuthzToken)value);
        }
        break;

      case AIRAVATA_CRED_STORE_TOKEN:
        if (value == null) {
          unsetAiravataCredStoreToken();
        } else {
          setAiravataCredStoreToken((String)value);
        }
        break;

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

      }
    }

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

      case AIRAVATA_CRED_STORE_TOKEN:
        return getAiravataCredStoreToken();

      case GATEWAY_ID:
        return getGatewayId();

      }
      throw new IllegalStateException();
    }

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

      switch (field) {
      case AUTHZ_TOKEN:
        return isSetAuthzToken();
      case AIRAVATA_CRED_STORE_TOKEN:
        return isSetAiravataCredStoreToken();
      case GATEWAY_ID:
        return isSetGatewayId();
      }
      throw new IllegalStateException();
    }

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

    public boolean equals(getSSHPubKey_args that) {
      if (that == null)
        return false;

      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_airavataCredStoreToken = true && this.isSetAiravataCredStoreToken();
      boolean that_present_airavataCredStoreToken = true && that.isSetAiravataCredStoreToken();
      if (this_present_airavataCredStoreToken || that_present_airavataCredStoreToken) {
        if (!(this_present_airavataCredStoreToken && that_present_airavataCredStoreToken))
          return false;
        if (!this.airavataCredStoreToken.equals(that.airavataCredStoreToken))
          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() {
      List<Object> list = new ArrayList<Object>();

      boolean present_authzToken = true && (isSetAuthzToken());
      list.add(present_authzToken);
      if (present_authzToken)
        list.add(authzToken);

      boolean present_airavataCredStoreToken = true && (isSetAiravataCredStoreToken());
      list.add(present_airavataCredStoreToken);
      if (present_airavataCredStoreToken)
        list.add(airavataCredStoreToken);

      boolean present_gatewayId = true && (isSetGatewayId());
      list.add(present_gatewayId);
      if (present_gatewayId)
        list.add(gatewayId);

      return list.hashCode();
    }

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

      int lastComparison = 0;

      lastComparison = 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 = Boolean.valueOf(isSetAiravataCredStoreToken()).compareTo(other.isSetAiravataCredStoreToken());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetAiravataCredStoreToken()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.airavataCredStoreToken, other.airavataCredStoreToken);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = 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 {
      schemes.get(iprot.getScheme()).getScheme().read(iprot, this);
    }

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

    @Override
    public String toString() {
      StringBuilder sb = new StringBuilder("getSSHPubKey_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("airavataCredStoreToken:");
      if (this.airavataCredStoreToken == null) {
        sb.append("null");
      } else {
        sb.append(this.airavataCredStoreToken);
      }
      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 (airavataCredStoreToken == null) {
        throw new org.apache.thrift.protocol.TProtocolException("Required field 'airavataCredStoreToken' 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, 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 getSSHPubKey_argsStandardSchemeFactory implements SchemeFactory {
      public getSSHPubKey_argsStandardScheme getScheme() {
        return new getSSHPubKey_argsStandardScheme();
      }
    }

    private static class getSSHPubKey_argsStandardScheme extends StandardScheme<getSSHPubKey_args> {

      public void read(org.apache.thrift.protocol.TProtocol iprot, getSSHPubKey_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_CRED_STORE_TOKEN
              if (schemeField.type == org.apache.thrift.protocol.TType.STRING) {
                struct.airavataCredStoreToken = iprot.readString();
                struct.setAiravataCredStoreTokenIsSet(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, getSSHPubKey_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.airavataCredStoreToken != null) {
          oprot.writeFieldBegin(AIRAVATA_CRED_STORE_TOKEN_FIELD_DESC);
          oprot.writeString(struct.airavataCredStoreToken);
          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 getSSHPubKey_argsTupleSchemeFactory implements SchemeFactory {
      public getSSHPubKey_argsTupleScheme getScheme() {
        return new getSSHPubKey_argsTupleScheme();
      }
    }

    private static class getSSHPubKey_argsTupleScheme extends TupleScheme<getSSHPubKey_args> {

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

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

  }

  public static class getSSHPubKey_result implements org.apache.thrift.TBase<getSSHPubKey_result, getSSHPubKey_result._Fields>, java.io.Serializable, Cloneable, Comparable<getSSHPubKey_result>   {
    private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("getSSHPubKey_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 IRE_FIELD_DESC = new org.apache.thrift.protocol.TField("ire", org.apache.thrift.protocol.TType.STRUCT, (short)1);
    private static final org.apache.thrift.protocol.TField ACE_FIELD_DESC = new org.apache.thrift.protocol.TField("ace", org.apache.thrift.protocol.TType.STRUCT, (short)2);
    private static final org.apache.thrift.protocol.TField ASE_FIELD_DESC = new org.apache.thrift.protocol.TField("ase", org.apache.thrift.protocol.TType.STRUCT, (short)3);

    private static final Map<Class<? extends IScheme>, SchemeFactory> schemes = new HashMap<Class<? extends IScheme>, SchemeFactory>();
    static {
      schemes.put(StandardScheme.class, new getSSHPubKey_resultStandardSchemeFactory());
      schemes.put(TupleScheme.class, new getSSHPubKey_resultTupleSchemeFactory());
    }

    public String success; // required
    public org.apache.airavata.model.error.InvalidRequestException ire; // required
    public org.apache.airavata.model.error.AiravataClientException ace; // required
    public org.apache.airavata.model.error.AiravataSystemException ase; // required

    /** 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"),
      IRE((short)1, "ire"),
      ACE((short)2, "ace"),
      ASE((short)3, "ase");

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

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

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

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

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

      private final short _thriftId;
      private final String _fieldName;

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

      public short getThriftFieldId() {
        return _thriftId;
      }

      public String getFieldName() {
        return _fieldName;
      }
    }

    // isset id assignments
    public static final Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
    static {
      Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new EnumMap<_Fields, org.apache.thrift.meta_data.FieldMetaData>(_Fields.class);
      tmpMap.put(_Fields.SUCCESS, new org.apache.thrift.meta_data.FieldMetaData("success", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING)));
      tmpMap.put(_Fields.IRE, new org.apache.thrift.meta_data.FieldMetaData("ire", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRUCT)));
      tmpMap.put(_Fields.ACE, new org.apache.thrift.meta_data.FieldMetaData("ace", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRUCT)));
      tmpMap.put(_Fields.ASE, new org.apache.thrift.meta_data.FieldMetaData("ase", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRUCT)));
      metaDataMap = Collections.unmodifiableMap(tmpMap);
      org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(getSSHPubKey_result.class, metaDataMap);
    }

    public getSSHPubKey_result() {
    }

    public getSSHPubKey_result(
      String success,
      org.apache.airavata.model.error.InvalidRequestException ire,
      org.apache.airavata.model.error.AiravataClientException ace,
      org.apache.airavata.model.error.AiravataSystemException ase)
    {
      this();
      this.success = success;
      this.ire = ire;
      this.ace = ace;
      this.ase = ase;
    }

    /**
     * Performs a deep copy on <i>other</i>.
     */
    public getSSHPubKey_result(getSSHPubKey_result other) {
      if (other.isSetSuccess()) {
        this.success = other.success;
      }
      if (other.isSetIre()) {
        this.ire = new org.apache.airavata.model.error.InvalidRequestException(other.ire);
      }
      if (other.isSetAce()) {
        this.ace = new org.apache.airavata.model.error.AiravataClientException(other.ace);
      }
      if (other.isSetAse()) {
        this.ase = new org.apache.airavata.model.error.AiravataSystemException(other.ase);
      }
    }

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

    @Override
    public void clear() {
      this.success = null;
      this.ire = null;
      this.ace = null;
      this.ase = null;
    }

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

    public getSSHPubKey_result setSuccess(String success) {
      this.success = success;
      return this;
    }

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

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

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

    public org.apache.airavata.model.error.InvalidRequestException getIre() {
      return this.ire;
    }

    public getSSHPubKey_result setIre(org.apache.airavata.model.error.InvalidRequestException ire) {
      this.ire = ire;
      return this;
    }

    public void unsetIre() {
      this.ire = null;
    }

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

    public void setIreIsSet(boolean value) {
      if (!value) {
        this.ire = null;
      }
    }

    public org.apache.airavata.model.error.AiravataClientException getAce() {
      return this.ace;
    }

    public getSSHPubKey_result setAce(org.apache.airavata.model.error.AiravataClientException ace) {
      this.ace = ace;
      return this;
    }

    public void unsetAce() {
      this.ace = null;
    }

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

    public void setAceIsSet(boolean value) {
      if (!value) {
        this.ace = null;
      }
    }

    public org.apache.airavata.model.error.AiravataSystemException getAse() {
      return this.ase;
    }

    public getSSHPubKey_result setAse(org.apache.airavata.model.error.AiravataSystemException ase) {
      this.ase = ase;
      return this;
    }

    public void unsetAse() {
      this.ase = null;
    }

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

    public void setAseIsSet(boolean value) {
      if (!value) {
        this.ase = null;
      }
    }

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

      case IRE:
        if (value == null) {
          unsetIre();
        } else {
          setIre((org.apache.airavata.model.error.InvalidRequestException)value);
        }
        break;

      case ACE:
        if (value == null) {
          unsetAce();
        } else {
          setAce((org.apache.airavata.model.error.AiravataClientException)value);
        }
        break;

      case ASE:
        if (value == null) {
          unsetAse();
        } else {
          setAse((org.apache.airavata.model.error.AiravataSystemException)value);
        }
        break;

      }
    }

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

      case IRE:
        return getIre();

      case ACE:
        return getAce();

      case ASE:
        return getAse();

      }
      throw new IllegalStateException();
    }

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

      switch (field) {
      case SUCCESS:
        return isSetSuccess();
      case IRE:
        return isSetIre();
      case ACE:
        return isSetAce();
      case ASE:
        return isSetAse();
      }
      throw new IllegalStateException();
    }

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

    public boolean equals(getSSHPubKey_result that) {
      if (that == null)
        return false;

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

      boolean this_present_ire = true && this.isSetIre();
      boolean that_present_ire = true && that.isSetIre();
      if (this_present_ire || that_present_ire) {
        if (!(this_present_ire && that_present_ire))
          return false;
        if (!this.ire.equals(that.ire))
          return false;
      }

      boolean this_present_ace = true && this.isSetAce();
      boolean that_present_ace = true && that.isSetAce();
      if (this_present_ace || that_present_ace) {
        if (!(this_present_ace && that_present_ace))
          return false;
        if (!this.ace.equals(that.ace))
          return false;
      }

      boolean this_present_ase = true && this.isSetAse();
      boolean that_present_ase = true && that.isSetAse();
      if (this_present_ase || that_present_ase) {
        if (!(this_present_ase && that_present_ase))
          return false;
        if (!this.ase.equals(that.ase))
          return false;
      }

      return true;
    }

    @Override
    public int hashCode() {
      List<Object> list = new ArrayList<Object>();

      boolean present_success = true && (isSetSuccess());
      list.add(present_success);
      if (present_success)
        list.add(success);

      boolean present_ire = true && (isSetIre());
      list.add(present_ire);
      if (present_ire)
        list.add(ire);

      boolean present_ace = true && (isSetAce());
      list.add(present_ace);
      if (present_ace)
        list.add(ace);

      boolean present_ase = true && (isSetAse());
      list.add(present_ase);
      if (present_ase)
        list.add(ase);

      return list.hashCode();
    }

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

      int lastComparison = 0;

      lastComparison = Boolean.valueOf(isSetSuccess()).compareTo(other.isSetSuccess());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetSuccess()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.success, other.success);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = Boolean.valueOf(isSetIre()).compareTo(other.isSetIre());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetIre()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.ire, other.ire);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = Boolean.valueOf(isSetAce()).compareTo(other.isSetAce());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetAce()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.ace, other.ace);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = Boolean.valueOf(isSetAse()).compareTo(other.isSetAse());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetAse()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.ase, other.ase);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      return 0;
    }

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

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

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

    @Override
    public String toString() {
      StringBuilder sb = new StringBuilder("getSSHPubKey_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("ire:");
      if (this.ire == null) {
        sb.append("null");
      } else {
        sb.append(this.ire);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("ace:");
      if (this.ace == null) {
        sb.append("null");
      } else {
        sb.append(this.ace);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("ase:");
      if (this.ase == null) {
        sb.append("null");
      } else {
        sb.append(this.ase);
      }
      first = false;
      sb.append(")");
      return sb.toString();
    }

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

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

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

    private static class getSSHPubKey_resultStandardSchemeFactory implements SchemeFactory {
      public getSSHPubKey_resultStandardScheme getScheme() {
        return new getSSHPubKey_resultStandardScheme();
      }
    }

    private static class getSSHPubKey_resultStandardScheme extends StandardScheme<getSSHPubKey_result> {

      public void read(org.apache.thrift.protocol.TProtocol iprot, getSSHPubKey_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: // IRE
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.ire = new org.apache.airavata.model.error.InvalidRequestException();
                struct.ire.read(iprot);
                struct.setIreIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 2: // ACE
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.ace = new org.apache.airavata.model.error.AiravataClientException();
                struct.ace.read(iprot);
                struct.setAceIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 3: // ASE
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.ase = new org.apache.airavata.model.error.AiravataSystemException();
                struct.ase.read(iprot);
                struct.setAseIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            default:
              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
          }
          iprot.readFieldEnd();
        }
        iprot.readStructEnd();

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

      public void write(org.apache.thrift.protocol.TProtocol oprot, getSSHPubKey_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.ire != null) {
          oprot.writeFieldBegin(IRE_FIELD_DESC);
          struct.ire.write(oprot);
          oprot.writeFieldEnd();
        }
        if (struct.ace != null) {
          oprot.writeFieldBegin(ACE_FIELD_DESC);
          struct.ace.write(oprot);
          oprot.writeFieldEnd();
        }
        if (struct.ase != null) {
          oprot.writeFieldBegin(ASE_FIELD_DESC);
          struct.ase.write(oprot);
          oprot.writeFieldEnd();
        }
        oprot.writeFieldStop();
        oprot.writeStructEnd();
      }

    }

    private static class getSSHPubKey_resultTupleSchemeFactory implements SchemeFactory {
      public getSSHPubKey_resultTupleScheme getScheme() {
        return new getSSHPubKey_resultTupleScheme();
      }
    }

    private static class getSSHPubKey_resultTupleScheme extends TupleScheme<getSSHPubKey_result> {

      @Override
      public void write(org.apache.thrift.protocol.TProtocol prot, getSSHPubKey_result struct) throws org.apache.thrift.TException {
        TTupleProtocol oprot = (TTupleProtocol) prot;
        BitSet optionals = new BitSet();
        if (struct.isSetSuccess()) {
          optionals.set(0);
        }
        if (struct.isSetIre()) {
          optionals.set(1);
        }
        if (struct.isSetAce()) {
          optionals.set(2);
        }
        if (struct.isSetAse()) {
          optionals.set(3);
        }
        oprot.writeBitSet(optionals, 4);
        if (struct.isSetSuccess()) {
          oprot.writeString(struct.success);
        }
        if (struct.isSetIre()) {
          struct.ire.write(oprot);
        }
        if (struct.isSetAce()) {
          struct.ace.write(oprot);
        }
        if (struct.isSetAse()) {
          struct.ase.write(oprot);
        }
      }

      @Override
      public void read(org.apache.thrift.protocol.TProtocol prot, getSSHPubKey_result struct) throws org.apache.thrift.TException {
        TTupleProtocol iprot = (TTupleProtocol) prot;
        BitSet incoming = iprot.readBitSet(4);
        if (incoming.get(0)) {
          struct.success = iprot.readString();
          struct.setSuccessIsSet(true);
        }
        if (incoming.get(1)) {
          struct.ire = new org.apache.airavata.model.error.InvalidRequestException();
          struct.ire.read(iprot);
          struct.setIreIsSet(true);
        }
        if (incoming.get(2)) {
          struct.ace = new org.apache.airavata.model.error.AiravataClientException();
          struct.ace.read(iprot);
          struct.setAceIsSet(true);
        }
        if (incoming.get(3)) {
          struct.ase = new org.apache.airavata.model.error.AiravataSystemException();
          struct.ase.read(iprot);
          struct.setAseIsSet(true);
        }
      }
    }

  }

  public static class getAllUserSSHPubKeys_args implements org.apache.thrift.TBase<getAllUserSSHPubKeys_args, getAllUserSSHPubKeys_args._Fields>, java.io.Serializable, Cloneable, Comparable<getAllUserSSHPubKeys_args>   {
    private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("getAllUserSSHPubKeys_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 USER_NAME_FIELD_DESC = new org.apache.thrift.protocol.TField("userName", org.apache.thrift.protocol.TType.STRING, (short)2);

    private static final Map<Class<? extends IScheme>, SchemeFactory> schemes = new HashMap<Class<? extends IScheme>, SchemeFactory>();
    static {
      schemes.put(StandardScheme.class, new getAllUserSSHPubKeys_argsStandardSchemeFactory());
      schemes.put(TupleScheme.class, new getAllUserSSHPubKeys_argsTupleSchemeFactory());
    }

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

    /** 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"),
      USER_NAME((short)2, "userName");

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

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

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

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

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

      private final short _thriftId;
      private final String _fieldName;

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

      public short getThriftFieldId() {
        return _thriftId;
      }

      public String getFieldName() {
        return _fieldName;
      }
    }

    // isset id assignments
    public static final Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
    static {
      Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new EnumMap<_Fields, org.apache.thrift.meta_data.FieldMetaData>(_Fields.class);
      tmpMap.put(_Fields.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.USER_NAME, new org.apache.thrift.meta_data.FieldMetaData("userName", org.apache.thrift.TFieldRequirementType.REQUIRED, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING)));
      metaDataMap = Collections.unmodifiableMap(tmpMap);
      org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(getAllUserSSHPubKeys_args.class, metaDataMap);
    }

    public getAllUserSSHPubKeys_args() {
    }

    public getAllUserSSHPubKeys_args(
      org.apache.airavata.model.security.AuthzToken authzToken,
      String userName)
    {
      this();
      this.authzToken = authzToken;
      this.userName = userName;
    }

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

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

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

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

    public getAllUserSSHPubKeys_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 String getUserName() {
      return this.userName;
    }

    public getAllUserSSHPubKeys_args setUserName(String userName) {
      this.userName = userName;
      return this;
    }

    public void unsetUserName() {
      this.userName = null;
    }

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

    public void setUserNameIsSet(boolean value) {
      if (!value) {
        this.userName = null;
      }
    }

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

      case USER_NAME:
        if (value == null) {
          unsetUserName();
        } else {
          setUserName((String)value);
        }
        break;

      }
    }

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

      case USER_NAME:
        return getUserName();

      }
      throw new IllegalStateException();
    }

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

      switch (field) {
      case AUTHZ_TOKEN:
        return isSetAuthzToken();
      case USER_NAME:
        return isSetUserName();
      }
      throw new IllegalStateException();
    }

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

    public boolean equals(getAllUserSSHPubKeys_args that) {
      if (that == null)
        return false;

      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_userName = true && this.isSetUserName();
      boolean that_present_userName = true && that.isSetUserName();
      if (this_present_userName || that_present_userName) {
        if (!(this_present_userName && that_present_userName))
          return false;
        if (!this.userName.equals(that.userName))
          return false;
      }

      return true;
    }

    @Override
    public int hashCode() {
      List<Object> list = new ArrayList<Object>();

      boolean present_authzToken = true && (isSetAuthzToken());
      list.add(present_authzToken);
      if (present_authzToken)
        list.add(authzToken);

      boolean present_userName = true && (isSetUserName());
      list.add(present_userName);
      if (present_userName)
        list.add(userName);

      return list.hashCode();
    }

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

      int lastComparison = 0;

      lastComparison = 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 = Boolean.valueOf(isSetUserName()).compareTo(other.isSetUserName());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetUserName()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.userName, other.userName);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      return 0;
    }

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

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

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

    @Override
    public String toString() {
      StringBuilder sb = new StringBuilder("getAllUserSSHPubKeys_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("userName:");
      if (this.userName == null) {
        sb.append("null");
      } else {
        sb.append(this.userName);
      }
      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 (userName == null) {
        throw new org.apache.thrift.protocol.TProtocolException("Required field 'userName' 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, 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 getAllUserSSHPubKeys_argsStandardSchemeFactory implements SchemeFactory {
      public getAllUserSSHPubKeys_argsStandardScheme getScheme() {
        return new getAllUserSSHPubKeys_argsStandardScheme();
      }
    }

    private static class getAllUserSSHPubKeys_argsStandardScheme extends StandardScheme<getAllUserSSHPubKeys_args> {

      public void read(org.apache.thrift.protocol.TProtocol iprot, getAllUserSSHPubKeys_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: // USER_NAME
              if (schemeField.type == org.apache.thrift.protocol.TType.STRING) {
                struct.userName = iprot.readString();
                struct.setUserNameIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            default:
              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
          }
          iprot.readFieldEnd();
        }
        iprot.readStructEnd();

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

      public void write(org.apache.thrift.protocol.TProtocol oprot, getAllUserSSHPubKeys_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.userName != null) {
          oprot.writeFieldBegin(USER_NAME_FIELD_DESC);
          oprot.writeString(struct.userName);
          oprot.writeFieldEnd();
        }
        oprot.writeFieldStop();
        oprot.writeStructEnd();
      }

    }

    private static class getAllUserSSHPubKeys_argsTupleSchemeFactory implements SchemeFactory {
      public getAllUserSSHPubKeys_argsTupleScheme getScheme() {
        return new getAllUserSSHPubKeys_argsTupleScheme();
      }
    }

    private static class getAllUserSSHPubKeys_argsTupleScheme extends TupleScheme<getAllUserSSHPubKeys_args> {

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

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

  }

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

    private static final org.apache.thrift.protocol.TField SUCCESS_FIELD_DESC = new org.apache.thrift.protocol.TField("success", org.apache.thrift.protocol.TType.MAP, (short)0);
    private static final org.apache.thrift.protocol.TField IRE_FIELD_DESC = new org.apache.thrift.protocol.TField("ire", org.apache.thrift.protocol.TType.STRUCT, (short)1);
    private static final org.apache.thrift.protocol.TField ACE_FIELD_DESC = new org.apache.thrift.protocol.TField("ace", org.apache.thrift.protocol.TType.STRUCT, (short)2);
    private static final org.apache.thrift.protocol.TField ASE_FIELD_DESC = new org.apache.thrift.protocol.TField("ase", org.apache.thrift.protocol.TType.STRUCT, (short)3);

    private static final Map<Class<? extends IScheme>, SchemeFactory> schemes = new HashMap<Class<? extends IScheme>, SchemeFactory>();
    static {
      schemes.put(StandardScheme.class, new getAllUserSSHPubKeys_resultStandardSchemeFactory());
      schemes.put(TupleScheme.class, new getAllUserSSHPubKeys_resultTupleSchemeFactory());
    }

    public Map<String,String> success; // required
    public org.apache.airavata.model.error.InvalidRequestException ire; // required
    public org.apache.airavata.model.error.AiravataClientException ace; // required
    public org.apache.airavata.model.error.AiravataSystemException ase; // required

    /** 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"),
      IRE((short)1, "ire"),
      ACE((short)2, "ace"),
      ASE((short)3, "ase");

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

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

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

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

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

      private final short _thriftId;
      private final String _fieldName;

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

      public short getThriftFieldId() {
        return _thriftId;
      }

      public String getFieldName() {
        return _fieldName;
      }
    }

    // isset id assignments
    public static final Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
    static {
      Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new EnumMap<_Fields, org.apache.thrift.meta_data.FieldMetaData>(_Fields.class);
      tmpMap.put(_Fields.SUCCESS, new org.apache.thrift.meta_data.FieldMetaData("success", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.MapMetaData(org.apache.thrift.protocol.TType.MAP, 
              new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING), 
              new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING))));
      tmpMap.put(_Fields.IRE, new org.apache.thrift.meta_data.FieldMetaData("ire", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRUCT)));
      tmpMap.put(_Fields.ACE, new org.apache.thrift.meta_data.FieldMetaData("ace", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRUCT)));
      tmpMap.put(_Fields.ASE, new org.apache.thrift.meta_data.FieldMetaData("ase", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRUCT)));
      metaDataMap = Collections.unmodifiableMap(tmpMap);
      org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(getAllUserSSHPubKeys_result.class, metaDataMap);
    }

    public getAllUserSSHPubKeys_result() {
    }

    public getAllUserSSHPubKeys_result(
      Map<String,String> success,
      org.apache.airavata.model.error.InvalidRequestException ire,
      org.apache.airavata.model.error.AiravataClientException ace,
      org.apache.airavata.model.error.AiravataSystemException ase)
    {
      this();
      this.success = success;
      this.ire = ire;
      this.ace = ace;
      this.ase = ase;
    }

    /**
     * Performs a deep copy on <i>other</i>.
     */
    public getAllUserSSHPubKeys_result(getAllUserSSHPubKeys_result other) {
      if (other.isSetSuccess()) {
        Map<String,String> __this__success = new HashMap<String,String>(other.success);
        this.success = __this__success;
      }
      if (other.isSetIre()) {
        this.ire = new org.apache.airavata.model.error.InvalidRequestException(other.ire);
      }
      if (other.isSetAce()) {
        this.ace = new org.apache.airavata.model.error.AiravataClientException(other.ace);
      }
      if (other.isSetAse()) {
        this.ase = new org.apache.airavata.model.error.AiravataSystemException(other.ase);
      }
    }

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

    @Override
    public void clear() {
      this.success = null;
      this.ire = null;
      this.ace = null;
      this.ase = null;
    }

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

    public void putToSuccess(String key, String val) {
      if (this.success == null) {
        this.success = new HashMap<String,String>();
      }
      this.success.put(key, val);
    }

    public Map<String,String> getSuccess() {
      return this.success;
    }

    public getAllUserSSHPubKeys_result setSuccess(Map<String,String> success) {
      this.success = success;
      return this;
    }

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

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

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

    public org.apache.airavata.model.error.InvalidRequestException getIre() {
      return this.ire;
    }

    public getAllUserSSHPubKeys_result setIre(org.apache.airavata.model.error.InvalidRequestException ire) {
      this.ire = ire;
      return this;
    }

    public void unsetIre() {
      this.ire = null;
    }

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

    public void setIreIsSet(boolean value) {
      if (!value) {
        this.ire = null;
      }
    }

    public org.apache.airavata.model.error.AiravataClientException getAce() {
      return this.ace;
    }

    public getAllUserSSHPubKeys_result setAce(org.apache.airavata.model.error.AiravataClientException ace) {
      this.ace = ace;
      return this;
    }

    public void unsetAce() {
      this.ace = null;
    }

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

    public void setAceIsSet(boolean value) {
      if (!value) {
        this.ace = null;
      }
    }

    public org.apache.airavata.model.error.AiravataSystemException getAse() {
      return this.ase;
    }

    public getAllUserSSHPubKeys_result setAse(org.apache.airavata.model.error.AiravataSystemException ase) {
      this.ase = ase;
      return this;
    }

    public void unsetAse() {
      this.ase = null;
    }

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

    public void setAseIsSet(boolean value) {
      if (!value) {
        this.ase = null;
      }
    }

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

      case IRE:
        if (value == null) {
          unsetIre();
        } else {
          setIre((org.apache.airavata.model.error.InvalidRequestException)value);
        }
        break;

      case ACE:
        if (value == null) {
          unsetAce();
        } else {
          setAce((org.apache.airavata.model.error.AiravataClientException)value);
        }
        break;

      case ASE:
        if (value == null) {
          unsetAse();
        } else {
          setAse((org.apache.airavata.model.error.AiravataSystemException)value);
        }
        break;

      }
    }

    public Object getFieldValue(_Fields field) {
      switch (field) {
      case SUCCESS:
        return getSuccess();

      case IRE:
        return getIre();

      case ACE:
        return getAce();

      case ASE:
        return getAse();

      }
      throw new IllegalStateException();
    }

    /** Returns true if field corresponding to fieldID is set (has been assigned a value) and false otherwise */
    public boolean isSet(_Fields field) {
      if (field == null) {
        throw new IllegalArgumentException();
      }

      switch (field) {
      case SUCCESS:
        return isSetSuccess();
      case IRE:
        return isSetIre();
      case ACE:
        return isSetAce();
      case ASE:
        return isSetAse();
      }
      throw new IllegalStateException();
    }

    @Override
    public boolean equals(Object that) {
      if (that == null)
        return false;
      if (that instanceof getAllUserSSHPubKeys_result)
        return this.equals((getAllUserSSHPubKeys_result)that);
      return false;
    }

    public boolean equals(getAllUserSSHPubKeys_result that) {
      if (that == null)
        return false;

      boolean this_present_success = true && this.isSetSuccess();
      boolean that_present_success = true && that.isSetSuccess();
      if (this_present_success || that_present_success) {
        if (!(this_present_success && that_present_success))
          return false;
        if (!this.success.equals(that.success))
          return false;
      }

      boolean this_present_ire = true && this.isSetIre();
      boolean that_present_ire = true && that.isSetIre();
      if (this_present_ire || that_present_ire) {
        if (!(this_present_ire && that_present_ire))
          return false;
        if (!this.ire.equals(that.ire))
          return false;
      }

      boolean this_present_ace = true && this.isSetAce();
      boolean that_present_ace = true && that.isSetAce();
      if (this_present_ace || that_present_ace) {
        if (!(this_present_ace && that_present_ace))
          return false;
        if (!this.ace.equals(that.ace))
          return false;
      }

      boolean this_present_ase = true && this.isSetAse();
      boolean that_present_ase = true && that.isSetAse();
      if (this_present_ase || that_present_ase) {
        if (!(this_present_ase && that_present_ase))
          return false;
        if (!this.ase.equals(that.ase))
          return false;
      }

      return true;
    }

    @Override
    public int hashCode() {
      List<Object> list = new ArrayList<Object>();

      boolean present_success = true && (isSetSuccess());
      list.add(present_success);
      if (present_success)
        list.add(success);

      boolean present_ire = true && (isSetIre());
      list.add(present_ire);
      if (present_ire)
        list.add(ire);

      boolean present_ace = true && (isSetAce());
      list.add(present_ace);
      if (present_ace)
        list.add(ace);

      boolean present_ase = true && (isSetAse());
      list.add(present_ase);
      if (present_ase)
        list.add(ase);

      return list.hashCode();
    }

    @Override
    public int compareTo(getAllUserSSHPubKeys_result other) {
      if (!getClass().equals(other.getClass())) {
        return getClass().getName().compareTo(other.getClass().getName());
      }

      int lastComparison = 0;

      lastComparison = Boolean.valueOf(isSetSuccess()).compareTo(other.isSetSuccess());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetSuccess()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.success, other.success);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = Boolean.valueOf(isSetIre()).compareTo(other.isSetIre());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetIre()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.ire, other.ire);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = Boolean.valueOf(isSetAce()).compareTo(other.isSetAce());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetAce()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.ace, other.ace);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = Boolean.valueOf(isSetAse()).compareTo(other.isSetAse());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetAse()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.ase, other.ase);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      return 0;
    }

    public _Fields fieldForId(int fieldId) {
      return _Fields.findByThriftId(fieldId);
    }

    public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
      schemes.get(iprot.getScheme()).getScheme().read(iprot, this);
    }

    public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException {
      schemes.get(oprot.getScheme()).getScheme().write(oprot, this);
      }

    @Override
    public String toString() {
      StringBuilder sb = new StringBuilder("getAllUserSSHPubKeys_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("ire:");
      if (this.ire == null) {
        sb.append("null");
      } else {
        sb.append(this.ire);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("ace:");
      if (this.ace == null) {
        sb.append("null");
      } else {
        sb.append(this.ace);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("ase:");
      if (this.ase == null) {
        sb.append("null");
      } else {
        sb.append(this.ase);
      }
      first = false;
      sb.append(")");
      return sb.toString();
    }

    public void validate() throws org.apache.thrift.TException {
      // check for required fields
      // check for sub-struct validity
    }

    private void writeObject(java.io.ObjectOutputStream out) throws java.io.IOException {
      try {
        write(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(out)));
      } catch (org.apache.thrift.TException te) {
        throw new java.io.IOException(te);
      }
    }

    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, ClassNotFoundException {
      try {
        read(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(in)));
      } catch (org.apache.thrift.TException te) {
        throw new java.io.IOException(te);
      }
    }

    private static class getAllUserSSHPubKeys_resultStandardSchemeFactory implements SchemeFactory {
      public getAllUserSSHPubKeys_resultStandardScheme getScheme() {
        return new getAllUserSSHPubKeys_resultStandardScheme();
      }
    }

    private static class getAllUserSSHPubKeys_resultStandardScheme extends StandardScheme<getAllUserSSHPubKeys_result> {

      public void read(org.apache.thrift.protocol.TProtocol iprot, getAllUserSSHPubKeys_result struct) throws org.apache.thrift.TException {
        org.apache.thrift.protocol.TField schemeField;
        iprot.readStructBegin();
        while (true)
        {
          schemeField = iprot.readFieldBegin();
          if (schemeField.type == org.apache.thrift.protocol.TType.STOP) { 
            break;
          }
          switch (schemeField.id) {
            case 0: // SUCCESS
              if (schemeField.type == org.apache.thrift.protocol.TType.MAP) {
                {
                  org.apache.thrift.protocol.TMap _map8 = iprot.readMapBegin();
                  struct.success = new HashMap<String,String>(2*_map8.size);
                  String _key9;
                  String _val10;
                  for (int _i11 = 0; _i11 < _map8.size; ++_i11)
                  {
                    _key9 = iprot.readString();
                    _val10 = iprot.readString();
                    struct.success.put(_key9, _val10);
                  }
                  iprot.readMapEnd();
                }
                struct.setSuccessIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 1: // IRE
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.ire = new org.apache.airavata.model.error.InvalidRequestException();
                struct.ire.read(iprot);
                struct.setIreIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 2: // ACE
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.ace = new org.apache.airavata.model.error.AiravataClientException();
                struct.ace.read(iprot);
                struct.setAceIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 3: // ASE
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.ase = new org.apache.airavata.model.error.AiravataSystemException();
                struct.ase.read(iprot);
                struct.setAseIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            default:
              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
          }
          iprot.readFieldEnd();
        }
        iprot.readStructEnd();

        // check for required fields of primitive type, which can't be checked in the validate method
        struct.validate();
      }

      public void write(org.apache.thrift.protocol.TProtocol oprot, getAllUserSSHPubKeys_result struct) throws org.apache.thrift.TException {
        struct.validate();

        oprot.writeStructBegin(STRUCT_DESC);
        if (struct.success != null) {
          oprot.writeFieldBegin(SUCCESS_FIELD_DESC);
          {
            oprot.writeMapBegin(new org.apache.thrift.protocol.TMap(org.apache.thrift.protocol.TType.STRING, org.apache.thrift.protocol.TType.STRING, struct.success.size()));
            for (Map.Entry<String, String> _iter12 : struct.success.entrySet())
            {
              oprot.writeString(_iter12.getKey());
              oprot.writeString(_iter12.getValue());
            }
            oprot.writeMapEnd();
          }
          oprot.writeFieldEnd();
        }
        if (struct.ire != null) {
          oprot.writeFieldBegin(IRE_FIELD_DESC);
          struct.ire.write(oprot);
          oprot.writeFieldEnd();
        }
        if (struct.ace != null) {
          oprot.writeFieldBegin(ACE_FIELD_DESC);
          struct.ace.write(oprot);
          oprot.writeFieldEnd();
        }
        if (struct.ase != null) {
          oprot.writeFieldBegin(ASE_FIELD_DESC);
          struct.ase.write(oprot);
          oprot.writeFieldEnd();
        }
        oprot.writeFieldStop();
        oprot.writeStructEnd();
      }

    }

    private static class getAllUserSSHPubKeys_resultTupleSchemeFactory implements SchemeFactory {
      public getAllUserSSHPubKeys_resultTupleScheme getScheme() {
        return new getAllUserSSHPubKeys_resultTupleScheme();
      }
    }

    private static class getAllUserSSHPubKeys_resultTupleScheme extends TupleScheme<getAllUserSSHPubKeys_result> {

      @Override
      public void write(org.apache.thrift.protocol.TProtocol prot, getAllUserSSHPubKeys_result struct) throws org.apache.thrift.TException {
        TTupleProtocol oprot = (TTupleProtocol) prot;
        BitSet optionals = new BitSet();
        if (struct.isSetSuccess()) {
          optionals.set(0);
        }
        if (struct.isSetIre()) {
          optionals.set(1);
        }
        if (struct.isSetAce()) {
          optionals.set(2);
        }
        if (struct.isSetAse()) {
          optionals.set(3);
        }
        oprot.writeBitSet(optionals, 4);
        if (struct.isSetSuccess()) {
          {
            oprot.writeI32(struct.success.size());
            for (Map.Entry<String, String> _iter13 : struct.success.entrySet())
            {
              oprot.writeString(_iter13.getKey());
              oprot.writeString(_iter13.getValue());
            }
          }
        }
        if (struct.isSetIre()) {
          struct.ire.write(oprot);
        }
        if (struct.isSetAce()) {
          struct.ace.write(oprot);
        }
        if (struct.isSetAse()) {
          struct.ase.write(oprot);
        }
      }

      @Override
      public void read(org.apache.thrift.protocol.TProtocol prot, getAllUserSSHPubKeys_result struct) throws org.apache.thrift.TException {
        TTupleProtocol iprot = (TTupleProtocol) prot;
        BitSet incoming = iprot.readBitSet(4);
        if (incoming.get(0)) {
          {
            org.apache.thrift.protocol.TMap _map14 = new org.apache.thrift.protocol.TMap(org.apache.thrift.protocol.TType.STRING, org.apache.thrift.protocol.TType.STRING, iprot.readI32());
            struct.success = new HashMap<String,String>(2*_map14.size);
            String _key15;
            String _val16;
            for (int _i17 = 0; _i17 < _map14.size; ++_i17)
            {
              _key15 = iprot.readString();
              _val16 = iprot.readString();
              struct.success.put(_key15, _val16);
            }
          }
          struct.setSuccessIsSet(true);
        }
        if (incoming.get(1)) {
          struct.ire = new org.apache.airavata.model.error.InvalidRequestException();
          struct.ire.read(iprot);
          struct.setIreIsSet(true);
        }
        if (incoming.get(2)) {
          struct.ace = new org.apache.airavata.model.error.AiravataClientException();
          struct.ace.read(iprot);
          struct.setAceIsSet(true);
        }
        if (incoming.get(3)) {
          struct.ase = new org.apache.airavata.model.error.AiravataSystemException();
          struct.ase.read(iprot);
          struct.setAseIsSet(true);
        }
      }
    }

  }

  public static class createProject_args implements org.apache.thrift.TBase<createProject_args, createProject_args._Fields>, java.io.Serializable, Cloneable, Comparable<createProject_args>   {
    private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("createProject_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.protocol.TField PROJECT_FIELD_DESC = new org.apache.thrift.protocol.TField("project", org.apache.thrift.protocol.TType.STRUCT, (short)3);

    private static final Map<Class<? extends IScheme>, SchemeFactory> schemes = new HashMap<Class<? extends IScheme>, SchemeFactory>();
    static {
      schemes.put(StandardScheme.class, new createProject_argsStandardSchemeFactory());
      schemes.put(TupleScheme.class, new createProject_argsTupleSchemeFactory());
    }

    public org.apache.airavata.model.security.AuthzToken authzToken; // required
    public String gatewayId; // required
    public org.apache.airavata.model.workspace.Project project; // required

    /** 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"),
      PROJECT((short)3, "project");

      private static final Map<String, _Fields> byName = new HashMap<String, _Fields>();

      static {
        for (_Fields field : EnumSet.allOf(_Fields.class)) {
          byName.put(field.getFieldName(), field);
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, or null if its not found.
       */
      public static _Fields findByThriftId(int fieldId) {
        switch(fieldId) {
          case 1: // AUTHZ_TOKEN
            return AUTHZ_TOKEN;
          case 2: // GATEWAY_ID
            return GATEWAY_ID;
          case 3: // PROJECT
            return PROJECT;
          default:
            return null;
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, throwing an exception
       * if it is not found.
       */
      public static _Fields findByThriftIdOrThrow(int fieldId) {
        _Fields fields = findByThriftId(fieldId);
        if (fields == null) throw new IllegalArgumentException("Field " + fieldId + " doesn't exist!");
        return fields;
      }

      /**
       * Find the _Fields constant that matches name, or null if its not found.
       */
      public static _Fields findByName(String name) {
        return byName.get(name);
      }

      private final short _thriftId;
      private final String _fieldName;

      _Fields(short thriftId, String fieldName) {
        _thriftId = thriftId;
        _fieldName = fieldName;
      }

      public short getThriftFieldId() {
        return _thriftId;
      }

      public String getFieldName() {
        return _fieldName;
      }
    }

    // isset id assignments
    public static final Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
    static {
      Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new EnumMap<_Fields, org.apache.thrift.meta_data.FieldMetaData>(_Fields.class);
      tmpMap.put(_Fields.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)));
      tmpMap.put(_Fields.PROJECT, new org.apache.thrift.meta_data.FieldMetaData("project", org.apache.thrift.TFieldRequirementType.REQUIRED, 
          new org.apache.thrift.meta_data.StructMetaData(org.apache.thrift.protocol.TType.STRUCT, org.apache.airavata.model.workspace.Project.class)));
      metaDataMap = Collections.unmodifiableMap(tmpMap);
      org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(createProject_args.class, metaDataMap);
    }

    public createProject_args() {
    }

    public createProject_args(
      org.apache.airavata.model.security.AuthzToken authzToken,
      String gatewayId,
      org.apache.airavata.model.workspace.Project project)
    {
      this();
      this.authzToken = authzToken;
      this.gatewayId = gatewayId;
      this.project = project;
    }

    /**
     * Performs a deep copy on <i>other</i>.
     */
    public createProject_args(createProject_args other) {
      if (other.isSetAuthzToken()) {
        this.authzToken = new org.apache.airavata.model.security.AuthzToken(other.authzToken);
      }
      if (other.isSetGatewayId()) {
        this.gatewayId = other.gatewayId;
      }
      if (other.isSetProject()) {
        this.project = new org.apache.airavata.model.workspace.Project(other.project);
      }
    }

    public createProject_args deepCopy() {
      return new createProject_args(this);
    }

    @Override
    public void clear() {
      this.authzToken = null;
      this.gatewayId = null;
      this.project = null;
    }

    public org.apache.airavata.model.security.AuthzToken getAuthzToken() {
      return this.authzToken;
    }

    public createProject_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 String getGatewayId() {
      return this.gatewayId;
    }

    public createProject_args setGatewayId(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 org.apache.airavata.model.workspace.Project getProject() {
      return this.project;
    }

    public createProject_args setProject(org.apache.airavata.model.workspace.Project project) {
      this.project = project;
      return this;
    }

    public void unsetProject() {
      this.project = null;
    }

    /** Returns true if field project is set (has been assigned a value) and false otherwise */
    public boolean isSetProject() {
      return this.project != null;
    }

    public void setProjectIsSet(boolean value) {
      if (!value) {
        this.project = null;
      }
    }

    public void setFieldValue(_Fields field, 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((String)value);
        }
        break;

      case PROJECT:
        if (value == null) {
          unsetProject();
        } else {
          setProject((org.apache.airavata.model.workspace.Project)value);
        }
        break;

      }
    }

    public Object getFieldValue(_Fields field) {
      switch (field) {
      case AUTHZ_TOKEN:
        return getAuthzToken();

      case GATEWAY_ID:
        return getGatewayId();

      case PROJECT:
        return getProject();

      }
      throw new IllegalStateException();
    }

    /** Returns true if field corresponding to fieldID is set (has been assigned a value) and false otherwise */
    public boolean isSet(_Fields field) {
      if (field == null) {
        throw new IllegalArgumentException();
      }

      switch (field) {
      case AUTHZ_TOKEN:
        return isSetAuthzToken();
      case GATEWAY_ID:
        return isSetGatewayId();
      case PROJECT:
        return isSetProject();
      }
      throw new IllegalStateException();
    }

    @Override
    public boolean equals(Object that) {
      if (that == null)
        return false;
      if (that instanceof createProject_args)
        return this.equals((createProject_args)that);
      return false;
    }

    public boolean equals(createProject_args that) {
      if (that == null)
        return false;

      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;
      }

      boolean this_present_project = true && this.isSetProject();
      boolean that_present_project = true && that.isSetProject();
      if (this_present_project || that_present_project) {
        if (!(this_present_project && that_present_project))
          return false;
        if (!this.project.equals(that.project))
          return false;
      }

      return true;
    }

    @Override
    public int hashCode() {
      List<Object> list = new ArrayList<Object>();

      boolean present_authzToken = true && (isSetAuthzToken());
      list.add(present_authzToken);
      if (present_authzToken)
        list.add(authzToken);

      boolean present_gatewayId = true && (isSetGatewayId());
      list.add(present_gatewayId);
      if (present_gatewayId)
        list.add(gatewayId);

      boolean present_project = true && (isSetProject());
      list.add(present_project);
      if (present_project)
        list.add(project);

      return list.hashCode();
    }

    @Override
    public int compareTo(createProject_args other) {
      if (!getClass().equals(other.getClass())) {
        return getClass().getName().compareTo(other.getClass().getName());
      }

      int lastComparison = 0;

      lastComparison = 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 = 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;
        }
      }
      lastComparison = Boolean.valueOf(isSetProject()).compareTo(other.isSetProject());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetProject()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.project, other.project);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      return 0;
    }

    public _Fields fieldForId(int fieldId) {
      return _Fields.findByThriftId(fieldId);
    }

    public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
      schemes.get(iprot.getScheme()).getScheme().read(iprot, this);
    }

    public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException {
      schemes.get(oprot.getScheme()).getScheme().write(oprot, this);
    }

    @Override
    public String toString() {
      StringBuilder sb = new StringBuilder("createProject_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;
      if (!first) sb.append(", ");
      sb.append("project:");
      if (this.project == null) {
        sb.append("null");
      } else {
        sb.append(this.project);
      }
      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());
      }
      if (project == null) {
        throw new org.apache.thrift.protocol.TProtocolException("Required field 'project' was not present! Struct: " + toString());
      }
      // check for sub-struct validity
      if (authzToken != null) {
        authzToken.validate();
      }
      if (project != null) {
        project.validate();
      }
    }

    private void writeObject(java.io.ObjectOutputStream out) throws java.io.IOException {
      try {
        write(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(out)));
      } catch (org.apache.thrift.TException te) {
        throw new java.io.IOException(te);
      }
    }

    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, ClassNotFoundException {
      try {
        read(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(in)));
      } catch (org.apache.thrift.TException te) {
        throw new java.io.IOException(te);
      }
    }

    private static class createProject_argsStandardSchemeFactory implements SchemeFactory {
      public createProject_argsStandardScheme getScheme() {
        return new createProject_argsStandardScheme();
      }
    }

    private static class createProject_argsStandardScheme extends StandardScheme<createProject_args> {

      public void read(org.apache.thrift.protocol.TProtocol iprot, createProject_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;
            case 3: // PROJECT
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.project = new org.apache.airavata.model.workspace.Project();
                struct.project.read(iprot);
                struct.setProjectIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            default:
              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
          }
          iprot.readFieldEnd();
        }
        iprot.readStructEnd();

        // check for required fields of primitive type, which can't be checked in the validate method
        struct.validate();
      }

      public void write(org.apache.thrift.protocol.TProtocol oprot, createProject_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();
        }
        if (struct.project != null) {
          oprot.writeFieldBegin(PROJECT_FIELD_DESC);
          struct.project.write(oprot);
          oprot.writeFieldEnd();
        }
        oprot.writeFieldStop();
        oprot.writeStructEnd();
      }

    }

    private static class createProject_argsTupleSchemeFactory implements SchemeFactory {
      public createProject_argsTupleScheme getScheme() {
        return new createProject_argsTupleScheme();
      }
    }

    private static class createProject_argsTupleScheme extends TupleScheme<createProject_args> {

      @Override
      public void write(org.apache.thrift.protocol.TProtocol prot, createProject_args struct) throws org.apache.thrift.TException {
        TTupleProtocol oprot = (TTupleProtocol) prot;
        struct.authzToken.write(oprot);
        oprot.writeString(struct.gatewayId);
        struct.project.write(oprot);
      }

      @Override
      public void read(org.apache.thrift.protocol.TProtocol prot, createProject_args struct) throws org.apache.thrift.TException {
        TTupleProtocol iprot = (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);
        struct.project = new org.apache.airavata.model.workspace.Project();
        struct.project.read(iprot);
        struct.setProjectIsSet(true);
      }
    }

  }

  public static class createProject_result implements org.apache.thrift.TBase<createProject_result, createProject_result._Fields>, java.io.Serializable, Cloneable, Comparable<createProject_result>   {
    private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("createProject_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 IRE_FIELD_DESC = new org.apache.thrift.protocol.TField("ire", org.apache.thrift.protocol.TType.STRUCT, (short)1);
    private static final org.apache.thrift.protocol.TField ACE_FIELD_DESC = new org.apache.thrift.protocol.TField("ace", org.apache.thrift.protocol.TType.STRUCT, (short)2);
    private static final org.apache.thrift.protocol.TField ASE_FIELD_DESC = new org.apache.thrift.protocol.TField("ase", org.apache.thrift.protocol.TType.STRUCT, (short)3);
    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)4);

    private static final Map<Class<? extends IScheme>, SchemeFactory> schemes = new HashMap<Class<? extends IScheme>, SchemeFactory>();
    static {
      schemes.put(StandardScheme.class, new createProject_resultStandardSchemeFactory());
      schemes.put(TupleScheme.class, new createProject_resultTupleSchemeFactory());
    }

    public String success; // required
    public org.apache.airavata.model.error.InvalidRequestException ire; // required
    public org.apache.airavata.model.error.AiravataClientException ace; // required
    public org.apache.airavata.model.error.AiravataSystemException ase; // 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"),
      IRE((short)1, "ire"),
      ACE((short)2, "ace"),
      ASE((short)3, "ase"),
      AE((short)4, "ae");

      private static final Map<String, _Fields> byName = new HashMap<String, _Fields>();

      static {
        for (_Fields field : EnumSet.allOf(_Fields.class)) {
          byName.put(field.getFieldName(), field);
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, or null if its not found.
       */
      public static _Fields findByThriftId(int fieldId) {
        switch(fieldId) {
          case 0: // SUCCESS
            return SUCCESS;
          case 1: // IRE
            return IRE;
          case 2: // ACE
            return ACE;
          case 3: // ASE
            return ASE;
          case 4: // 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 IllegalArgumentException("Field " + fieldId + " doesn't exist!");
        return fields;
      }

      /**
       * Find the _Fields constant that matches name, or null if its not found.
       */
      public static _Fields findByName(String name) {
        return byName.get(name);
      }

      private final short _thriftId;
      private final String _fieldName;

      _Fields(short thriftId, String fieldName) {
        _thriftId = thriftId;
        _fieldName = fieldName;
      }

      public short getThriftFieldId() {
        return _thriftId;
      }

      public String getFieldName() {
        return _fieldName;
      }
    }

    // isset id assignments
    public static final Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
    static {
      Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new EnumMap<_Fields, org.apache.thrift.meta_data.FieldMetaData>(_Fields.class);
      tmpMap.put(_Fields.SUCCESS, new org.apache.thrift.meta_data.FieldMetaData("success", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING)));
      tmpMap.put(_Fields.IRE, new org.apache.thrift.meta_data.FieldMetaData("ire", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRUCT)));
      tmpMap.put(_Fields.ACE, new org.apache.thrift.meta_data.FieldMetaData("ace", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRUCT)));
      tmpMap.put(_Fields.ASE, new org.apache.thrift.meta_data.FieldMetaData("ase", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRUCT)));
      tmpMap.put(_Fields.AE, new org.apache.thrift.meta_data.FieldMetaData("ae", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRUCT)));
      metaDataMap = Collections.unmodifiableMap(tmpMap);
      org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(createProject_result.class, metaDataMap);
    }

    public createProject_result() {
    }

    public createProject_result(
      String success,
      org.apache.airavata.model.error.InvalidRequestException ire,
      org.apache.airavata.model.error.AiravataClientException ace,
      org.apache.airavata.model.error.AiravataSystemException ase,
      org.apache.airavata.model.error.AuthorizationException ae)
    {
      this();
      this.success = success;
      this.ire = ire;
      this.ace = ace;
      this.ase = ase;
      this.ae = ae;
    }

    /**
     * Performs a deep copy on <i>other</i>.
     */
    public createProject_result(createProject_result other) {
      if (other.isSetSuccess()) {
        this.success = other.success;
      }
      if (other.isSetIre()) {
        this.ire = new org.apache.airavata.model.error.InvalidRequestException(other.ire);
      }
      if (other.isSetAce()) {
        this.ace = new org.apache.airavata.model.error.AiravataClientException(other.ace);
      }
      if (other.isSetAse()) {
        this.ase = new org.apache.airavata.model.error.AiravataSystemException(other.ase);
      }
      if (other.isSetAe()) {
        this.ae = new org.apache.airavata.model.error.AuthorizationException(other.ae);
      }
    }

    public createProject_result deepCopy() {
      return new createProject_result(this);
    }

    @Override
    public void clear() {
      this.success = null;
      this.ire = null;
      this.ace = null;
      this.ase = null;
      this.ae = null;
    }

    public String getSuccess() {
      return this.success;
    }

    public createProject_result setSuccess(String success) {
      this.success = success;
      return this;
    }

    public void unsetSuccess() {
      this.success = null;
    }

    /** Returns true if field success is set (has been assigned a value) and false otherwise */
    public boolean isSetSuccess() {
      return this.success != null;
    }

    public void setSuccessIsSet(boolean value) {
      if (!value) {
        this.success = null;
      }
    }

    public org.apache.airavata.model.error.InvalidRequestException getIre() {
      return this.ire;
    }

    public createProject_result setIre(org.apache.airavata.model.error.InvalidRequestException ire) {
      this.ire = ire;
      return this;
    }

    public void unsetIre() {
      this.ire = null;
    }

    /** Returns true if field ire is set (has been assigned a value) and false otherwise */
    public boolean isSetIre() {
      return this.ire != null;
    }

    public void setIreIsSet(boolean value) {
      if (!value) {
        this.ire = null;
      }
    }

    public org.apache.airavata.model.error.AiravataClientException getAce() {
      return this.ace;
    }

    public createProject_result setAce(org.apache.airavata.model.error.AiravataClientException ace) {
      this.ace = ace;
      return this;
    }

    public void unsetAce() {
      this.ace = null;
    }

    /** Returns true if field ace is set (has been assigned a value) and false otherwise */
    public boolean isSetAce() {
      return this.ace != null;
    }

    public void setAceIsSet(boolean value) {
      if (!value) {
        this.ace = null;
      }
    }

    public org.apache.airavata.model.error.AiravataSystemException getAse() {
      return this.ase;
    }

    public createProject_result setAse(org.apache.airavata.model.error.AiravataSystemException ase) {
      this.ase = ase;
      return this;
    }

    public void unsetAse() {
      this.ase = null;
    }

    /** Returns true if field ase is set (has been assigned a value) and false otherwise */
    public boolean isSetAse() {
      return this.ase != null;
    }

    public void setAseIsSet(boolean value) {
      if (!value) {
        this.ase = null;
      }
    }

    public org.apache.airavata.model.error.AuthorizationException getAe() {
      return this.ae;
    }

    public createProject_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, Object value) {
      switch (field) {
      case SUCCESS:
        if (value == null) {
          unsetSuccess();
        } else {
          setSuccess((String)value);
        }
        break;

      case IRE:
        if (value == null) {
          unsetIre();
        } else {
          setIre((org.apache.airavata.model.error.InvalidRequestException)value);
        }
        break;

      case ACE:
        if (value == null) {
          unsetAce();
        } else {
          setAce((org.apache.airavata.model.error.AiravataClientException)value);
        }
        break;

      case ASE:
        if (value == null) {
          unsetAse();
        } else {
          setAse((org.apache.airavata.model.error.AiravataSystemException)value);
        }
        break;

      case AE:
        if (value == null) {
          unsetAe();
        } else {
          setAe((org.apache.airavata.model.error.AuthorizationException)value);
        }
        break;

      }
    }

    public Object getFieldValue(_Fields field) {
      switch (field) {
      case SUCCESS:
        return getSuccess();

      case IRE:
        return getIre();

      case ACE:
        return getAce();

      case ASE:
        return getAse();

      case AE:
        return getAe();

      }
      throw new IllegalStateException();
    }

    /** Returns true if field corresponding to fieldID is set (has been assigned a value) and false otherwise */
    public boolean isSet(_Fields field) {
      if (field == null) {
        throw new IllegalArgumentException();
      }

      switch (field) {
      case SUCCESS:
        return isSetSuccess();
      case IRE:
        return isSetIre();
      case ACE:
        return isSetAce();
      case ASE:
        return isSetAse();
      case AE:
        return isSetAe();
      }
      throw new IllegalStateException();
    }

    @Override
    public boolean equals(Object that) {
      if (that == null)
        return false;
      if (that instanceof createProject_result)
        return this.equals((createProject_result)that);
      return false;
    }

    public boolean equals(createProject_result that) {
      if (that == null)
        return false;

      boolean this_present_success = true && this.isSetSuccess();
      boolean that_present_success = true && that.isSetSuccess();
      if (this_present_success || that_present_success) {
        if (!(this_present_success && that_present_success))
          return false;
        if (!this.success.equals(that.success))
          return false;
      }

      boolean this_present_ire = true && this.isSetIre();
      boolean that_present_ire = true && that.isSetIre();
      if (this_present_ire || that_present_ire) {
        if (!(this_present_ire && that_present_ire))
          return false;
        if (!this.ire.equals(that.ire))
          return false;
      }

      boolean this_present_ace = true && this.isSetAce();
      boolean that_present_ace = true && that.isSetAce();
      if (this_present_ace || that_present_ace) {
        if (!(this_present_ace && that_present_ace))
          return false;
        if (!this.ace.equals(that.ace))
          return false;
      }

      boolean this_present_ase = true && this.isSetAse();
      boolean that_present_ase = true && that.isSetAse();
      if (this_present_ase || that_present_ase) {
        if (!(this_present_ase && that_present_ase))
          return false;
        if (!this.ase.equals(that.ase))
          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() {
      List<Object> list = new ArrayList<Object>();

      boolean present_success = true && (isSetSuccess());
      list.add(present_success);
      if (present_success)
        list.add(success);

      boolean present_ire = true && (isSetIre());
      list.add(present_ire);
      if (present_ire)
        list.add(ire);

      boolean present_ace = true && (isSetAce());
      list.add(present_ace);
      if (present_ace)
        list.add(ace);

      boolean present_ase = true && (isSetAse());
      list.add(present_ase);
      if (present_ase)
        list.add(ase);

      boolean present_ae = true && (isSetAe());
      list.add(present_ae);
      if (present_ae)
        list.add(ae);

      return list.hashCode();
    }

    @Override
    public int compareTo(createProject_result other) {
      if (!getClass().equals(other.getClass())) {
        return getClass().getName().compareTo(other.getClass().getName());
      }

      int lastComparison = 0;

      lastComparison = Boolean.valueOf(isSetSuccess()).compareTo(other.isSetSuccess());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetSuccess()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.success, other.success);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = Boolean.valueOf(isSetIre()).compareTo(other.isSetIre());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetIre()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.ire, other.ire);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = Boolean.valueOf(isSetAce()).compareTo(other.isSetAce());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetAce()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.ace, other.ace);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = Boolean.valueOf(isSetAse()).compareTo(other.isSetAse());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetAse()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.ase, other.ase);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = 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 {
      schemes.get(iprot.getScheme()).getScheme().read(iprot, this);
    }

    public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException {
      schemes.get(oprot.getScheme()).getScheme().write(oprot, this);
      }

    @Override
    public String toString() {
      StringBuilder sb = new StringBuilder("createProject_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("ire:");
      if (this.ire == null) {
        sb.append("null");
      } else {
        sb.append(this.ire);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("ace:");
      if (this.ace == null) {
        sb.append("null");
      } else {
        sb.append(this.ace);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("ase:");
      if (this.ase == null) {
        sb.append("null");
      } else {
        sb.append(this.ase);
      }
      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, 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 createProject_resultStandardSchemeFactory implements SchemeFactory {
      public createProject_resultStandardScheme getScheme() {
        return new createProject_resultStandardScheme();
      }
    }

    private static class createProject_resultStandardScheme extends StandardScheme<createProject_result> {

      public void read(org.apache.thrift.protocol.TProtocol iprot, createProject_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: // IRE
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.ire = new org.apache.airavata.model.error.InvalidRequestException();
                struct.ire.read(iprot);
                struct.setIreIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 2: // ACE
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.ace = new org.apache.airavata.model.error.AiravataClientException();
                struct.ace.read(iprot);
                struct.setAceIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 3: // ASE
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.ase = new org.apache.airavata.model.error.AiravataSystemException();
                struct.ase.read(iprot);
                struct.setAseIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 4: // 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, createProject_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.ire != null) {
          oprot.writeFieldBegin(IRE_FIELD_DESC);
          struct.ire.write(oprot);
          oprot.writeFieldEnd();
        }
        if (struct.ace != null) {
          oprot.writeFieldBegin(ACE_FIELD_DESC);
          struct.ace.write(oprot);
          oprot.writeFieldEnd();
        }
        if (struct.ase != null) {
          oprot.writeFieldBegin(ASE_FIELD_DESC);
          struct.ase.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 createProject_resultTupleSchemeFactory implements SchemeFactory {
      public createProject_resultTupleScheme getScheme() {
        return new createProject_resultTupleScheme();
      }
    }

    private static class createProject_resultTupleScheme extends TupleScheme<createProject_result> {

      @Override
      public void write(org.apache.thrift.protocol.TProtocol prot, createProject_result struct) throws org.apache.thrift.TException {
        TTupleProtocol oprot = (TTupleProtocol) prot;
        BitSet optionals = new BitSet();
        if (struct.isSetSuccess()) {
          optionals.set(0);
        }
        if (struct.isSetIre()) {
          optionals.set(1);
        }
        if (struct.isSetAce()) {
          optionals.set(2);
        }
        if (struct.isSetAse()) {
          optionals.set(3);
        }
        if (struct.isSetAe()) {
          optionals.set(4);
        }
        oprot.writeBitSet(optionals, 5);
        if (struct.isSetSuccess()) {
          oprot.writeString(struct.success);
        }
        if (struct.isSetIre()) {
          struct.ire.write(oprot);
        }
        if (struct.isSetAce()) {
          struct.ace.write(oprot);
        }
        if (struct.isSetAse()) {
          struct.ase.write(oprot);
        }
        if (struct.isSetAe()) {
          struct.ae.write(oprot);
        }
      }

      @Override
      public void read(org.apache.thrift.protocol.TProtocol prot, createProject_result struct) throws org.apache.thrift.TException {
        TTupleProtocol iprot = (TTupleProtocol) prot;
        BitSet incoming = iprot.readBitSet(5);
        if (incoming.get(0)) {
          struct.success = iprot.readString();
          struct.setSuccessIsSet(true);
        }
        if (incoming.get(1)) {
          struct.ire = new org.apache.airavata.model.error.InvalidRequestException();
          struct.ire.read(iprot);
          struct.setIreIsSet(true);
        }
        if (incoming.get(2)) {
          struct.ace = new org.apache.airavata.model.error.AiravataClientException();
          struct.ace.read(iprot);
          struct.setAceIsSet(true);
        }
        if (incoming.get(3)) {
          struct.ase = new org.apache.airavata.model.error.AiravataSystemException();
          struct.ase.read(iprot);
          struct.setAseIsSet(true);
        }
        if (incoming.get(4)) {
          struct.ae = new org.apache.airavata.model.error.AuthorizationException();
          struct.ae.read(iprot);
          struct.setAeIsSet(true);
        }
      }
    }

  }

  public static class updateProject_args implements org.apache.thrift.TBase<updateProject_args, updateProject_args._Fields>, java.io.Serializable, Cloneable, Comparable<updateProject_args>   {
    private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("updateProject_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 PROJECT_ID_FIELD_DESC = new org.apache.thrift.protocol.TField("projectId", org.apache.thrift.protocol.TType.STRING, (short)2);
    private static final org.apache.thrift.protocol.TField UPDATED_PROJECT_FIELD_DESC = new org.apache.thrift.protocol.TField("updatedProject", org.apache.thrift.protocol.TType.STRUCT, (short)3);

    private static final Map<Class<? extends IScheme>, SchemeFactory> schemes = new HashMap<Class<? extends IScheme>, SchemeFactory>();
    static {
      schemes.put(StandardScheme.class, new updateProject_argsStandardSchemeFactory());
      schemes.put(TupleScheme.class, new updateProject_argsTupleSchemeFactory());
    }

    public org.apache.airavata.model.security.AuthzToken authzToken; // required
    public String projectId; // required
    public org.apache.airavata.model.workspace.Project updatedProject; // required

    /** 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"),
      PROJECT_ID((short)2, "projectId"),
      UPDATED_PROJECT((short)3, "updatedProject");

      private static final Map<String, _Fields> byName = new HashMap<String, _Fields>();

      static {
        for (_Fields field : EnumSet.allOf(_Fields.class)) {
          byName.put(field.getFieldName(), field);
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, or null if its not found.
       */
      public static _Fields findByThriftId(int fieldId) {
        switch(fieldId) {
          case 1: // AUTHZ_TOKEN
            return AUTHZ_TOKEN;
          case 2: // PROJECT_ID
            return PROJECT_ID;
          case 3: // UPDATED_PROJECT
            return UPDATED_PROJECT;
          default:
            return null;
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, throwing an exception
       * if it is not found.
       */
      public static _Fields findByThriftIdOrThrow(int fieldId) {
        _Fields fields = findByThriftId(fieldId);
        if (fields == null) throw new IllegalArgumentException("Field " + fieldId + " doesn't exist!");
        return fields;
      }

      /**
       * Find the _Fields constant that matches name, or null if its not found.
       */
      public static _Fields findByName(String name) {
        return byName.get(name);
      }

      private final short _thriftId;
      private final String _fieldName;

      _Fields(short thriftId, String fieldName) {
        _thriftId = thriftId;
        _fieldName = fieldName;
      }

      public short getThriftFieldId() {
        return _thriftId;
      }

      public String getFieldName() {
        return _fieldName;
      }
    }

    // isset id assignments
    public static final Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
    static {
      Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new EnumMap<_Fields, org.apache.thrift.meta_data.FieldMetaData>(_Fields.class);
      tmpMap.put(_Fields.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.PROJECT_ID, new org.apache.thrift.meta_data.FieldMetaData("projectId", org.apache.thrift.TFieldRequirementType.REQUIRED, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING)));
      tmpMap.put(_Fields.UPDATED_PROJECT, new org.apache.thrift.meta_data.FieldMetaData("updatedProject", org.apache.thrift.TFieldRequirementType.REQUIRED, 
          new org.apache.thrift.meta_data.StructMetaData(org.apache.thrift.protocol.TType.STRUCT, org.apache.airavata.model.workspace.Project.class)));
      metaDataMap = Collections.unmodifiableMap(tmpMap);
      org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(updateProject_args.class, metaDataMap);
    }

    public updateProject_args() {
    }

    public updateProject_args(
      org.apache.airavata.model.security.AuthzToken authzToken,
      String projectId,
      org.apache.airavata.model.workspace.Project updatedProject)
    {
      this();
      this.authzToken = authzToken;
      this.projectId = projectId;
      this.updatedProject = updatedProject;
    }

    /**
     * Performs a deep copy on <i>other</i>.
     */
    public updateProject_args(updateProject_args other) {
      if (other.isSetAuthzToken()) {
        this.authzToken = new org.apache.airavata.model.security.AuthzToken(other.authzToken);
      }
      if (other.isSetProjectId()) {
        this.projectId = other.projectId;
      }
      if (other.isSetUpdatedProject()) {
        this.updatedProject = new org.apache.airavata.model.workspace.Project(other.updatedProject);
      }
    }

    public updateProject_args deepCopy() {
      return new updateProject_args(this);
    }

    @Override
    public void clear() {
      this.authzToken = null;
      this.projectId = null;
      this.updatedProject = null;
    }

    public org.apache.airavata.model.security.AuthzToken getAuthzToken() {
      return this.authzToken;
    }

    public updateProject_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 String getProjectId() {
      return this.projectId;
    }

    public updateProject_args setProjectId(String projectId) {
      this.projectId = projectId;
      return this;
    }

    public void unsetProjectId() {
      this.projectId = null;
    }

    /** Returns true if field projectId is set (has been assigned a value) and false otherwise */
    public boolean isSetProjectId() {
      return this.projectId != null;
    }

    public void setProjectIdIsSet(boolean value) {
      if (!value) {
        this.projectId = null;
      }
    }

    public org.apache.airavata.model.workspace.Project getUpdatedProject() {
      return this.updatedProject;
    }

    public updateProject_args setUpdatedProject(org.apache.airavata.model.workspace.Project updatedProject) {
      this.updatedProject = updatedProject;
      return this;
    }

    public void unsetUpdatedProject() {
      this.updatedProject = null;
    }

    /** Returns true if field updatedProject is set (has been assigned a value) and false otherwise */
    public boolean isSetUpdatedProject() {
      return this.updatedProject != null;
    }

    public void setUpdatedProjectIsSet(boolean value) {
      if (!value) {
        this.updatedProject = null;
      }
    }

    public void setFieldValue(_Fields field, Object value) {
      switch (field) {
      case AUTHZ_TOKEN:
        if (value == null) {
          unsetAuthzToken();
        } else {
          setAuthzToken((org.apache.airavata.model.security.AuthzToken)value);
        }
        break;

      case PROJECT_ID:
        if (value == null) {
          unsetProjectId();
        } else {
          setProjectId((String)value);
        }
        break;

      case UPDATED_PROJECT:
        if (value == null) {
          unsetUpdatedProject();
        } else {
          setUpdatedProject((org.apache.airavata.model.workspace.Project)value);
        }
        break;

      }
    }

    public Object getFieldValue(_Fields field) {
      switch (field) {
      case AUTHZ_TOKEN:
        return getAuthzToken();

      case PROJECT_ID:
        return getProjectId();

      case UPDATED_PROJECT:
        return getUpdatedProject();

      }
      throw new IllegalStateException();
    }

    /** Returns true if field corresponding to fieldID is set (has been assigned a value) and false otherwise */
    public boolean isSet(_Fields field) {
      if (field == null) {
        throw new IllegalArgumentException();
      }

      switch (field) {
      case AUTHZ_TOKEN:
        return isSetAuthzToken();
      case PROJECT_ID:
        return isSetProjectId();
      case UPDATED_PROJECT:
        return isSetUpdatedProject();
      }
      throw new IllegalStateException();
    }

    @Override
    public boolean equals(Object that) {
      if (that == null)
        return false;
      if (that instanceof updateProject_args)
        return this.equals((updateProject_args)that);
      return false;
    }

    public boolean equals(updateProject_args that) {
      if (that == null)
        return false;

      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_projectId = true && this.isSetProjectId();
      boolean that_present_projectId = true && that.isSetProjectId();
      if (this_present_projectId || that_present_projectId) {
        if (!(this_present_projectId && that_present_projectId))
          return false;
        if (!this.projectId.equals(that.projectId))
          return false;
      }

      boolean this_present_updatedProject = true && this.isSetUpdatedProject();
      boolean that_present_updatedProject = true && that.isSetUpdatedProject();
      if (this_present_updatedProject || that_present_updatedProject) {
        if (!(this_present_updatedProject && that_present_updatedProject))
          return false;
        if (!this.updatedProject.equals(that.updatedProject))
          return false;
      }

      return true;
    }

    @Override
    public int hashCode() {
      List<Object> list = new ArrayList<Object>();

      boolean present_authzToken = true && (isSetAuthzToken());
      list.add(present_authzToken);
      if (present_authzToken)
        list.add(authzToken);

      boolean present_projectId = true && (isSetProjectId());
      list.add(present_projectId);
      if (present_projectId)
        list.add(projectId);

      boolean present_updatedProject = true && (isSetUpdatedProject());
      list.add(present_updatedProject);
      if (present_updatedProject)
        list.add(updatedProject);

      return list.hashCode();
    }

    @Override
    public int compareTo(updateProject_args other) {
      if (!getClass().equals(other.getClass())) {
        return getClass().getName().compareTo(other.getClass().getName());
      }

      int lastComparison = 0;

      lastComparison = 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 = Boolean.valueOf(isSetProjectId()).compareTo(other.isSetProjectId());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetProjectId()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.projectId, other.projectId);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = Boolean.valueOf(isSetUpdatedProject()).compareTo(other.isSetUpdatedProject());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetUpdatedProject()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.updatedProject, other.updatedProject);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      return 0;
    }

    public _Fields fieldForId(int fieldId) {
      return _Fields.findByThriftId(fieldId);
    }

    public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
      schemes.get(iprot.getScheme()).getScheme().read(iprot, this);
    }

    public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException {
      schemes.get(oprot.getScheme()).getScheme().write(oprot, this);
    }

    @Override
    public String toString() {
      StringBuilder sb = new StringBuilder("updateProject_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("projectId:");
      if (this.projectId == null) {
        sb.append("null");
      } else {
        sb.append(this.projectId);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("updatedProject:");
      if (this.updatedProject == null) {
        sb.append("null");
      } else {
        sb.append(this.updatedProject);
      }
      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 (projectId == null) {
        throw new org.apache.thrift.protocol.TProtocolException("Required field 'projectId' was not present! Struct: " + toString());
      }
      if (updatedProject == null) {
        throw new org.apache.thrift.protocol.TProtocolException("Required field 'updatedProject' was not present! Struct: " + toString());
      }
      // check for sub-struct validity
      if (authzToken != null) {
        authzToken.validate();
      }
      if (updatedProject != null) {
        updatedProject.validate();
      }
    }

    private void writeObject(java.io.ObjectOutputStream out) throws java.io.IOException {
      try {
        write(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(out)));
      } catch (org.apache.thrift.TException te) {
        throw new java.io.IOException(te);
      }
    }

    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, ClassNotFoundException {
      try {
        read(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(in)));
      } catch (org.apache.thrift.TException te) {
        throw new java.io.IOException(te);
      }
    }

    private static class updateProject_argsStandardSchemeFactory implements SchemeFactory {
      public updateProject_argsStandardScheme getScheme() {
        return new updateProject_argsStandardScheme();
      }
    }

    private static class updateProject_argsStandardScheme extends StandardScheme<updateProject_args> {

      public void read(org.apache.thrift.protocol.TProtocol iprot, updateProject_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: // PROJECT_ID
              if (schemeField.type == org.apache.thrift.protocol.TType.STRING) {
                struct.projectId = iprot.readString();
                struct.setProjectIdIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 3: // UPDATED_PROJECT
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.updatedProject = new org.apache.airavata.model.workspace.Project();
                struct.updatedProject.read(iprot);
                struct.setUpdatedProjectIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            default:
              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
          }
          iprot.readFieldEnd();
        }
        iprot.readStructEnd();

        // check for required fields of primitive type, which can't be checked in the validate method
        struct.validate();
      }

      public void write(org.apache.thrift.protocol.TProtocol oprot, updateProject_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.projectId != null) {
          oprot.writeFieldBegin(PROJECT_ID_FIELD_DESC);
          oprot.writeString(struct.projectId);
          oprot.writeFieldEnd();
        }
        if (struct.updatedProject != null) {
          oprot.writeFieldBegin(UPDATED_PROJECT_FIELD_DESC);
          struct.updatedProject.write(oprot);
          oprot.writeFieldEnd();
        }
        oprot.writeFieldStop();
        oprot.writeStructEnd();
      }

    }

    private static class updateProject_argsTupleSchemeFactory implements SchemeFactory {
      public updateProject_argsTupleScheme getScheme() {
        return new updateProject_argsTupleScheme();
      }
    }

    private static class updateProject_argsTupleScheme extends TupleScheme<updateProject_args> {

      @Override
      public void write(org.apache.thrift.protocol.TProtocol prot, updateProject_args struct) throws org.apache.thrift.TException {
        TTupleProtocol oprot = (TTupleProtocol) prot;
        struct.authzToken.write(oprot);
        oprot.writeString(struct.projectId);
        struct.updatedProject.write(oprot);
      }

      @Override
      public void read(org.apache.thrift.protocol.TProtocol prot, updateProject_args struct) throws org.apache.thrift.TException {
        TTupleProtocol iprot = (TTupleProtocol) prot;
        struct.authzToken = new org.apache.airavata.model.security.AuthzToken();
        struct.authzToken.read(iprot);
        struct.setAuthzTokenIsSet(true);
        struct.projectId = iprot.readString();
        struct.setProjectIdIsSet(true);
        struct.updatedProject = new org.apache.airavata.model.workspace.Project();
        struct.updatedProject.read(iprot);
        struct.setUpdatedProjectIsSet(true);
      }
    }

  }

  public static class updateProject_result implements org.apache.thrift.TBase<updateProject_result, updateProject_result._Fields>, java.io.Serializable, Cloneable, Comparable<updateProject_result>   {
    private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("updateProject_result");

    private static final org.apache.thrift.protocol.TField IRE_FIELD_DESC = new org.apache.thrift.protocol.TField("ire", org.apache.thrift.protocol.TType.STRUCT, (short)1);
    private static final org.apache.thrift.protocol.TField ACE_FIELD_DESC = new org.apache.thrift.protocol.TField("ace", org.apache.thrift.protocol.TType.STRUCT, (short)2);
    private static final org.apache.thrift.protocol.TField ASE_FIELD_DESC = new org.apache.thrift.protocol.TField("ase", org.apache.thrift.protocol.TType.STRUCT, (short)3);
    private static final org.apache.thrift.protocol.TField PNFE_FIELD_DESC = new org.apache.thrift.protocol.TField("pnfe", org.apache.thrift.protocol.TType.STRUCT, (short)4);
    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)5);

    private static final Map<Class<? extends IScheme>, SchemeFactory> schemes = new HashMap<Class<? extends IScheme>, SchemeFactory>();
    static {
      schemes.put(StandardScheme.class, new updateProject_resultStandardSchemeFactory());
      schemes.put(TupleScheme.class, new updateProject_resultTupleSchemeFactory());
    }

    public org.apache.airavata.model.error.InvalidRequestException ire; // required
    public org.apache.airavata.model.error.AiravataClientException ace; // required
    public org.apache.airavata.model.error.AiravataSystemException ase; // required
    public org.apache.airavata.model.error.ProjectNotFoundException pnfe; // 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 {
      IRE((short)1, "ire"),
      ACE((short)2, "ace"),
      ASE((short)3, "ase"),
      PNFE((short)4, "pnfe"),
      AE((short)5, "ae");

      private static final Map<String, _Fields> byName = new HashMap<String, _Fields>();

      static {
        for (_Fields field : EnumSet.allOf(_Fields.class)) {
          byName.put(field.getFieldName(), field);
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, or null if its not found.
       */
      public static _Fields findByThriftId(int fieldId) {
        switch(fieldId) {
          case 1: // IRE
            return IRE;
          case 2: // ACE
            return ACE;
          case 3: // ASE
            return ASE;
          case 4: // PNFE
            return PNFE;
          case 5: // 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 IllegalArgumentException("Field " + fieldId + " doesn't exist!");
        return fields;
      }

      /**
       * Find the _Fields constant that matches name, or null if its not found.
       */
      public static _Fields findByName(String name) {
        return byName.get(name);
      }

      private final short _thriftId;
      private final String _fieldName;

      _Fields(short thriftId, String fieldName) {
        _thriftId = thriftId;
        _fieldName = fieldName;
      }

      public short getThriftFieldId() {
        return _thriftId;
      }

      public String getFieldName() {
        return _fieldName;
      }
    }

    // isset id assignments
    public static final Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
    static {
      Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new EnumMap<_Fields, org.apache.thrift.meta_data.FieldMetaData>(_Fields.class);
      tmpMap.put(_Fields.IRE, new org.apache.thrift.meta_data.FieldMetaData("ire", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRUCT)));
      tmpMap.put(_Fields.ACE, new org.apache.thrift.meta_data.FieldMetaData("ace", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRUCT)));
      tmpMap.put(_Fields.ASE, new org.apache.thrift.meta_data.FieldMetaData("ase", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRUCT)));
      tmpMap.put(_Fields.PNFE, new org.apache.thrift.meta_data.FieldMetaData("pnfe", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRUCT)));
      tmpMap.put(_Fields.AE, new org.apache.thrift.meta_data.FieldMetaData("ae", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRUCT)));
      metaDataMap = Collections.unmodifiableMap(tmpMap);
      org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(updateProject_result.class, metaDataMap);
    }

    public updateProject_result() {
    }

    public updateProject_result(
      org.apache.airavata.model.error.InvalidRequestException ire,
      org.apache.airavata.model.error.AiravataClientException ace,
      org.apache.airavata.model.error.AiravataSystemException ase,
      org.apache.airavata.model.error.ProjectNotFoundException pnfe,
      org.apache.airavata.model.error.AuthorizationException ae)
    {
      this();
      this.ire = ire;
      this.ace = ace;
      this.ase = ase;
      this.pnfe = pnfe;
      this.ae = ae;
    }

    /**
     * Performs a deep copy on <i>other</i>.
     */
    public updateProject_result(updateProject_result other) {
      if (other.isSetIre()) {
        this.ire = new org.apache.airavata.model.error.InvalidRequestException(other.ire);
      }
      if (other.isSetAce()) {
        this.ace = new org.apache.airavata.model.error.AiravataClientException(other.ace);
      }
      if (other.isSetAse()) {
        this.ase = new org.apache.airavata.model.error.AiravataSystemException(other.ase);
      }
      if (other.isSetPnfe()) {
        this.pnfe = new org.apache.airavata.model.error.ProjectNotFoundException(other.pnfe);
      }
      if (other.isSetAe()) {
        this.ae = new org.apache.airavata.model.error.AuthorizationException(other.ae);
      }
    }

    public updateProject_result deepCopy() {
      return new updateProject_result(this);
    }

    @Override
    public void clear() {
      this.ire = null;
      this.ace = null;
      this.ase = null;
      this.pnfe = null;
      this.ae = null;
    }

    public org.apache.airavata.model.error.InvalidRequestException getIre() {
      return this.ire;
    }

    public updateProject_result setIre(org.apache.airavata.model.error.InvalidRequestException ire) {
      this.ire = ire;
      return this;
    }

    public void unsetIre() {
      this.ire = null;
    }

    /** Returns true if field ire is set (has been assigned a value) and false otherwise */
    public boolean isSetIre() {
      return this.ire != null;
    }

    public void setIreIsSet(boolean value) {
      if (!value) {
        this.ire = null;
      }
    }

    public org.apache.airavata.model.error.AiravataClientException getAce() {
      return this.ace;
    }

    public updateProject_result setAce(org.apache.airavata.model.error.AiravataClientException ace) {
      this.ace = ace;
      return this;
    }

    public void unsetAce() {
      this.ace = null;
    }

    /** Returns true if field ace is set (has been assigned a value) and false otherwise */
    public boolean isSetAce() {
      return this.ace != null;
    }

    public void setAceIsSet(boolean value) {
      if (!value) {
        this.ace = null;
      }
    }

    public org.apache.airavata.model.error.AiravataSystemException getAse() {
      return this.ase;
    }

    public updateProject_result setAse(org.apache.airavata.model.error.AiravataSystemException ase) {
      this.ase = ase;
      return this;
    }

    public void unsetAse() {
      this.ase = null;
    }

    /** Returns true if field ase is set (has been assigned a value) and false otherwise */
    public boolean isSetAse() {
      return this.ase != null;
    }

    public void setAseIsSet(boolean value) {
      if (!value) {
        this.ase = null;
      }
    }

    public org.apache.airavata.model.error.ProjectNotFoundException getPnfe() {
      return this.pnfe;
    }

    public updateProject_result setPnfe(org.apache.airavata.model.error.ProjectNotFoundException pnfe) {
      this.pnfe = pnfe;
      return this;
    }

    public void unsetPnfe() {
      this.pnfe = null;
    }

    /** Returns true if field pnfe is set (has been assigned a value) and false otherwise */
    public boolean isSetPnfe() {
      return this.pnfe != null;
    }

    public void setPnfeIsSet(boolean value) {
      if (!value) {
        this.pnfe = null;
      }
    }

    public org.apache.airavata.model.error.AuthorizationException getAe() {
      return this.ae;
    }

    public updateProject_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, Object value) {
      switch (field) {
      case IRE:
        if (value == null) {
          unsetIre();
        } else {
          setIre((org.apache.airavata.model.error.InvalidRequestException)value);
        }
        break;

      case ACE:
        if (value == null) {
          unsetAce();
        } else {
          setAce((org.apache.airavata.model.error.AiravataClientException)value);
        }
        break;

      case ASE:
        if (value == null) {
          unsetAse();
        } else {
          setAse((org.apache.airavata.model.error.AiravataSystemException)value);
        }
        break;

      case PNFE:
        if (value == null) {
          unsetPnfe();
        } else {
          setPnfe((org.apache.airavata.model.error.ProjectNotFoundException)value);
        }
        break;

      case AE:
        if (value == null) {
          unsetAe();
        } else {
          setAe((org.apache.airavata.model.error.AuthorizationException)value);
        }
        break;

      }
    }

    public Object getFieldValue(_Fields field) {
      switch (field) {
      case IRE:
        return getIre();

      case ACE:
        return getAce();

      case ASE:
        return getAse();

      case PNFE:
        return getPnfe();

      case AE:
        return getAe();

      }
      throw new IllegalStateException();
    }

    /** Returns true if field corresponding to fieldID is set (has been assigned a value) and false otherwise */
    public boolean isSet(_Fields field) {
      if (field == null) {
        throw new IllegalArgumentException();
      }

      switch (field) {
      case IRE:
        return isSetIre();
      case ACE:
        return isSetAce();
      case ASE:
        return isSetAse();
      case PNFE:
        return isSetPnfe();
      case AE:
        return isSetAe();
      }
      throw new IllegalStateException();
    }

    @Override
    public boolean equals(Object that) {
      if (that == null)
        return false;
      if (that instanceof updateProject_result)
        return this.equals((updateProject_result)that);
      return false;
    }

    public boolean equals(updateProject_result that) {
      if (that == null)
        return false;

      boolean this_present_ire = true && this.isSetIre();
      boolean that_present_ire = true && that.isSetIre();
      if (this_present_ire || that_present_ire) {
        if (!(this_present_ire && that_present_ire))
          return false;
        if (!this.ire.equals(that.ire))
          return false;
      }

      boolean this_present_ace = true && this.isSetAce();
      boolean that_present_ace = true && that.isSetAce();
      if (this_present_ace || that_present_ace) {
        if (!(this_present_ace && that_present_ace))
          return false;
        if (!this.ace.equals(that.ace))
          return false;
      }

      boolean this_present_ase = true && this.isSetAse();
      boolean that_present_ase = true && that.isSetAse();
      if (this_present_ase || that_present_ase) {
        if (!(this_present_ase && that_present_ase))
          return false;
        if (!this.ase.equals(that.ase))
          return false;
      }

      boolean this_present_pnfe = true && this.isSetPnfe();
      boolean that_present_pnfe = true && that.isSetPnfe();
      if (this_present_pnfe || that_present_pnfe) {
        if (!(this_present_pnfe && that_present_pnfe))
          return false;
        if (!this.pnfe.equals(that.pnfe))
          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() {
      List<Object> list = new ArrayList<Object>();

      boolean present_ire = true && (isSetIre());
      list.add(present_ire);
      if (present_ire)
        list.add(ire);

      boolean present_ace = true && (isSetAce());
      list.add(present_ace);
      if (present_ace)
        list.add(ace);

      boolean present_ase = true && (isSetAse());
      list.add(present_ase);
      if (present_ase)
        list.add(ase);

      boolean present_pnfe = true && (isSetPnfe());
      list.add(present_pnfe);
      if (present_pnfe)
        list.add(pnfe);

      boolean present_ae = true && (isSetAe());
      list.add(present_ae);
      if (present_ae)
        list.add(ae);

      return list.hashCode();
    }

    @Override
    public int compareTo(updateProject_result other) {
      if (!getClass().equals(other.getClass())) {
        return getClass().getName().compareTo(other.getClass().getName());
      }

      int lastComparison = 0;

      lastComparison = Boolean.valueOf(isSetIre()).compareTo(other.isSetIre());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetIre()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.ire, other.ire);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = Boolean.valueOf(isSetAce()).compareTo(other.isSetAce());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetAce()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.ace, other.ace);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = Boolean.valueOf(isSetAse()).compareTo(other.isSetAse());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetAse()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.ase, other.ase);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = Boolean.valueOf(isSetPnfe()).compareTo(other.isSetPnfe());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetPnfe()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.pnfe, other.pnfe);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = 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 {
      schemes.get(iprot.getScheme()).getScheme().read(iprot, this);
    }

    public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException {
      schemes.get(oprot.getScheme()).getScheme().write(oprot, this);
      }

    @Override
    public String toString() {
      StringBuilder sb = new StringBuilder("updateProject_result(");
      boolean first = true;

      sb.append("ire:");
      if (this.ire == null) {
        sb.append("null");
      } else {
        sb.append(this.ire);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("ace:");
      if (this.ace == null) {
        sb.append("null");
      } else {
        sb.append(this.ace);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("ase:");
      if (this.ase == null) {
        sb.append("null");
      } else {
        sb.append(this.ase);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("pnfe:");
      if (this.pnfe == null) {
        sb.append("null");
      } else {
        sb.append(this.pnfe);
      }
      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, 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 updateProject_resultStandardSchemeFactory implements SchemeFactory {
      public updateProject_resultStandardScheme getScheme() {
        return new updateProject_resultStandardScheme();
      }
    }

    private static class updateProject_resultStandardScheme extends StandardScheme<updateProject_result> {

      public void read(org.apache.thrift.protocol.TProtocol iprot, updateProject_result struct) throws org.apache.thrift.TException {
        org.apache.thrift.protocol.TField schemeField;
        iprot.readStructBegin();
        while (true)
        {
          schemeField = iprot.readFieldBegin();
          if (schemeField.type == org.apache.thrift.protocol.TType.STOP) { 
            break;
          }
          switch (schemeField.id) {
            case 1: // IRE
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.ire = new org.apache.airavata.model.error.InvalidRequestException();
                struct.ire.read(iprot);
                struct.setIreIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 2: // ACE
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.ace = new org.apache.airavata.model.error.AiravataClientException();
                struct.ace.read(iprot);
                struct.setAceIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 3: // ASE
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.ase = new org.apache.airavata.model.error.AiravataSystemException();
                struct.ase.read(iprot);
                struct.setAseIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 4: // PNFE
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.pnfe = new org.apache.airavata.model.error.ProjectNotFoundException();
                struct.pnfe.read(iprot);
                struct.setPnfeIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 5: // 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, updateProject_result struct) throws org.apache.thrift.TException {
        struct.validate();

        oprot.writeStructBegin(STRUCT_DESC);
        if (struct.ire != null) {
          oprot.writeFieldBegin(IRE_FIELD_DESC);
          struct.ire.write(oprot);
          oprot.writeFieldEnd();
        }
        if (struct.ace != null) {
          oprot.writeFieldBegin(ACE_FIELD_DESC);
          struct.ace.write(oprot);
          oprot.writeFieldEnd();
        }
        if (struct.ase != null) {
          oprot.writeFieldBegin(ASE_FIELD_DESC);
          struct.ase.write(oprot);
          oprot.writeFieldEnd();
        }
        if (struct.pnfe != null) {
          oprot.writeFieldBegin(PNFE_FIELD_DESC);
          struct.pnfe.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 updateProject_resultTupleSchemeFactory implements SchemeFactory {
      public updateProject_resultTupleScheme getScheme() {
        return new updateProject_resultTupleScheme();
      }
    }

    private static class updateProject_resultTupleScheme extends TupleScheme<updateProject_result> {

      @Override
      public void write(org.apache.thrift.protocol.TProtocol prot, updateProject_result struct) throws org.apache.thrift.TException {
        TTupleProtocol oprot = (TTupleProtocol) prot;
        BitSet optionals = new BitSet();
        if (struct.isSetIre()) {
          optionals.set(0);
        }
        if (struct.isSetAce()) {
          optionals.set(1);
        }
        if (struct.isSetAse()) {
          optionals.set(2);
        }
        if (struct.isSetPnfe()) {
          optionals.set(3);
        }
        if (struct.isSetAe()) {
          optionals.set(4);
        }
        oprot.writeBitSet(optionals, 5);
        if (struct.isSetIre()) {
          struct.ire.write(oprot);
        }
        if (struct.isSetAce()) {
          struct.ace.write(oprot);
        }
        if (struct.isSetAse()) {
          struct.ase.write(oprot);
        }
        if (struct.isSetPnfe()) {
          struct.pnfe.write(oprot);
        }
        if (struct.isSetAe()) {
          struct.ae.write(oprot);
        }
      }

      @Override
      public void read(org.apache.thrift.protocol.TProtocol prot, updateProject_result struct) throws org.apache.thrift.TException {
        TTupleProtocol iprot = (TTupleProtocol) prot;
        BitSet incoming = iprot.readBitSet(5);
        if (incoming.get(0)) {
          struct.ire = new org.apache.airavata.model.error.InvalidRequestException();
          struct.ire.read(iprot);
          struct.setIreIsSet(true);
        }
        if (incoming.get(1)) {
          struct.ace = new org.apache.airavata.model.error.AiravataClientException();
          struct.ace.read(iprot);
          struct.setAceIsSet(true);
        }
        if (incoming.get(2)) {
          struct.ase = new org.apache.airavata.model.error.AiravataSystemException();
          struct.ase.read(iprot);
          struct.setAseIsSet(true);
        }
        if (incoming.get(3)) {
          struct.pnfe = new org.apache.airavata.model.error.ProjectNotFoundException();
          struct.pnfe.read(iprot);
          struct.setPnfeIsSet(true);
        }
        if (incoming.get(4)) {
          struct.ae = new org.apache.airavata.model.error.AuthorizationException();
          struct.ae.read(iprot);
          struct.setAeIsSet(true);
        }
      }
    }

  }

  public static class getProject_args implements org.apache.thrift.TBase<getProject_args, getProject_args._Fields>, java.io.Serializable, Cloneable, Comparable<getProject_args>   {
    private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("getProject_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 PROJECT_ID_FIELD_DESC = new org.apache.thrift.protocol.TField("projectId", org.apache.thrift.protocol.TType.STRING, (short)2);

    private static final Map<Class<? extends IScheme>, SchemeFactory> schemes = new HashMap<Class<? extends IScheme>, SchemeFactory>();
    static {
      schemes.put(StandardScheme.class, new getProject_argsStandardSchemeFactory());
      schemes.put(TupleScheme.class, new getProject_argsTupleSchemeFactory());
    }

    public org.apache.airavata.model.security.AuthzToken authzToken; // required
    public String projectId; // required

    /** 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"),
      PROJECT_ID((short)2, "projectId");

      private static final Map<String, _Fields> byName = new HashMap<String, _Fields>();

      static {
        for (_Fields field : EnumSet.allOf(_Fields.class)) {
          byName.put(field.getFieldName(), field);
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, or null if its not found.
       */
      public static _Fields findByThriftId(int fieldId) {
        switch(fieldId) {
          case 1: // AUTHZ_TOKEN
            return AUTHZ_TOKEN;
          case 2: // PROJECT_ID
            return PROJECT_ID;
          default:
            return null;
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, throwing an exception
       * if it is not found.
       */
      public static _Fields findByThriftIdOrThrow(int fieldId) {
        _Fields fields = findByThriftId(fieldId);
        if (fields == null) throw new IllegalArgumentException("Field " + fieldId + " doesn't exist!");
        return fields;
      }

      /**
       * Find the _Fields constant that matches name, or null if its not found.
       */
      public static _Fields findByName(String name) {
        return byName.get(name);
      }

      private final short _thriftId;
      private final String _fieldName;

      _Fields(short thriftId, String fieldName) {
        _thriftId = thriftId;
        _fieldName = fieldName;
      }

      public short getThriftFieldId() {
        return _thriftId;
      }

      public String getFieldName() {
        return _fieldName;
      }
    }

    // isset id assignments
    public static final Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
    static {
      Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new EnumMap<_Fields, org.apache.thrift.meta_data.FieldMetaData>(_Fields.class);
      tmpMap.put(_Fields.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.PROJECT_ID, new org.apache.thrift.meta_data.FieldMetaData("projectId", org.apache.thrift.TFieldRequirementType.REQUIRED, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING)));
      metaDataMap = Collections.unmodifiableMap(tmpMap);
      org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(getProject_args.class, metaDataMap);
    }

    public getProject_args() {
    }

    public getProject_args(
      org.apache.airavata.model.security.AuthzToken authzToken,
      String projectId)
    {
      this();
      this.authzToken = authzToken;
      this.projectId = projectId;
    }

    /**
     * Performs a deep copy on <i>other</i>.
     */
    public getProject_args(getProject_args other) {
      if (other.isSetAuthzToken()) {
        this.authzToken = new org.apache.airavata.model.security.AuthzToken(other.authzToken);
      }
      if (other.isSetProjectId()) {
        this.projectId = other.projectId;
      }
    }

    public getProject_args deepCopy() {
      return new getProject_args(this);
    }

    @Override
    public void clear() {
      this.authzToken = null;
      this.projectId = null;
    }

    public org.apache.airavata.model.security.AuthzToken getAuthzToken() {
      return this.authzToken;
    }

    public getProject_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 String getProjectId() {
      return this.projectId;
    }

    public getProject_args setProjectId(String projectId) {
      this.projectId = projectId;
      return this;
    }

    public void unsetProjectId() {
      this.projectId = null;
    }

    /** Returns true if field projectId is set (has been assigned a value) and false otherwise */
    public boolean isSetProjectId() {
      return this.projectId != null;
    }

    public void setProjectIdIsSet(boolean value) {
      if (!value) {
        this.projectId = null;
      }
    }

    public void setFieldValue(_Fields field, Object value) {
      switch (field) {
      case AUTHZ_TOKEN:
        if (value == null) {
          unsetAuthzToken();
        } else {
          setAuthzToken((org.apache.airavata.model.security.AuthzToken)value);
        }
        break;

      case PROJECT_ID:
        if (value == null) {
          unsetProjectId();
        } else {
          setProjectId((String)value);
        }
        break;

      }
    }

    public Object getFieldValue(_Fields field) {
      switch (field) {
      case AUTHZ_TOKEN:
        return getAuthzToken();

      case PROJECT_ID:
        return getProjectId();

      }
      throw new IllegalStateException();
    }

    /** Returns true if field corresponding to fieldID is set (has been assigned a value) and false otherwise */
    public boolean isSet(_Fields field) {
      if (field == null) {
        throw new IllegalArgumentException();
      }

      switch (field) {
      case AUTHZ_TOKEN:
        return isSetAuthzToken();
      case PROJECT_ID:
        return isSetProjectId();
      }
      throw new IllegalStateException();
    }

    @Override
    public boolean equals(Object that) {
      if (that == null)
        return false;
      if (that instanceof getProject_args)
        return this.equals((getProject_args)that);
      return false;
    }

    public boolean equals(getProject_args that) {
      if (that == null)
        return false;

      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_projectId = true && this.isSetProjectId();
      boolean that_present_projectId = true && that.isSetProjectId();
      if (this_present_projectId || that_present_projectId) {
        if (!(this_present_projectId && that_present_projectId))
          return false;
        if (!this.projectId.equals(that.projectId))
          return false;
      }

      return true;
    }

    @Override
    public int hashCode() {
      List<Object> list = new ArrayList<Object>();

      boolean present_authzToken = true && (isSetAuthzToken());
      list.add(present_authzToken);
      if (present_authzToken)
        list.add(authzToken);

      boolean present_projectId = true && (isSetProjectId());
      list.add(present_projectId);
      if (present_projectId)
        list.add(projectId);

      return list.hashCode();
    }

    @Override
    public int compareTo(getProject_args other) {
      if (!getClass().equals(other.getClass())) {
        return getClass().getName().compareTo(other.getClass().getName());
      }

      int lastComparison = 0;

      lastComparison = 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 = Boolean.valueOf(isSetProjectId()).compareTo(other.isSetProjectId());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetProjectId()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.projectId, other.projectId);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      return 0;
    }

    public _Fields fieldForId(int fieldId) {
      return _Fields.findByThriftId(fieldId);
    }

    public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
      schemes.get(iprot.getScheme()).getScheme().read(iprot, this);
    }

    public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException {
      schemes.get(oprot.getScheme()).getScheme().write(oprot, this);
    }

    @Override
    public String toString() {
      StringBuilder sb = new StringBuilder("getProject_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("projectId:");
      if (this.projectId == null) {
        sb.append("null");
      } else {
        sb.append(this.projectId);
      }
      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 (projectId == null) {
        throw new org.apache.thrift.protocol.TProtocolException("Required field 'projectId' 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, 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 getProject_argsStandardSchemeFactory implements SchemeFactory {
      public getProject_argsStandardScheme getScheme() {
        return new getProject_argsStandardScheme();
      }
    }

    private static class getProject_argsStandardScheme extends StandardScheme<getProject_args> {

      public void read(org.apache.thrift.protocol.TProtocol iprot, getProject_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: // PROJECT_ID
              if (schemeField.type == org.apache.thrift.protocol.TType.STRING) {
                struct.projectId = iprot.readString();
                struct.setProjectIdIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            default:
              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
          }
          iprot.readFieldEnd();
        }
        iprot.readStructEnd();

        // check for required fields of primitive type, which can't be checked in the validate method
        struct.validate();
      }

      public void write(org.apache.thrift.protocol.TProtocol oprot, getProject_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.projectId != null) {
          oprot.writeFieldBegin(PROJECT_ID_FIELD_DESC);
          oprot.writeString(struct.projectId);
          oprot.writeFieldEnd();
        }
        oprot.writeFieldStop();
        oprot.writeStructEnd();
      }

    }

    private static class getProject_argsTupleSchemeFactory implements SchemeFactory {
      public getProject_argsTupleScheme getScheme() {
        return new getProject_argsTupleScheme();
      }
    }

    private static class getProject_argsTupleScheme extends TupleScheme<getProject_args> {

      @Override
      public void write(org.apache.thrift.protocol.TProtocol prot, getProject_args struct) throws org.apache.thrift.TException {
        TTupleProtocol oprot = (TTupleProtocol) prot;
        struct.authzToken.write(oprot);
        oprot.writeString(struct.projectId);
      }

      @Override
      public void read(org.apache.thrift.protocol.TProtocol prot, getProject_args struct) throws org.apache.thrift.TException {
        TTupleProtocol iprot = (TTupleProtocol) prot;
        struct.authzToken = new org.apache.airavata.model.security.AuthzToken();
        struct.authzToken.read(iprot);
        struct.setAuthzTokenIsSet(true);
        struct.projectId = iprot.readString();
        struct.setProjectIdIsSet(true);
      }
    }

  }

  public static class getProject_result implements org.apache.thrift.TBase<getProject_result, getProject_result._Fields>, java.io.Serializable, Cloneable, Comparable<getProject_result>   {
    private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("getProject_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 IRE_FIELD_DESC = new org.apache.thrift.protocol.TField("ire", org.apache.thrift.protocol.TType.STRUCT, (short)1);
    private static final org.apache.thrift.protocol.TField ACE_FIELD_DESC = new org.apache.thrift.protocol.TField("ace", org.apache.thrift.protocol.TType.STRUCT, (short)2);
    private static final org.apache.thrift.protocol.TField ASE_FIELD_DESC = new org.apache.thrift.protocol.TField("ase", org.apache.thrift.protocol.TType.STRUCT, (short)3);
    private static final org.apache.thrift.protocol.TField PNFE_FIELD_DESC = new org.apache.thrift.protocol.TField("pnfe", org.apache.thrift.protocol.TType.STRUCT, (short)4);
    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)5);

    private static final Map<Class<? extends IScheme>, SchemeFactory> schemes = new HashMap<Class<? extends IScheme>, SchemeFactory>();
    static {
      schemes.put(StandardScheme.class, new getProject_resultStandardSchemeFactory());
      schemes.put(TupleScheme.class, new getProject_resultTupleSchemeFactory());
    }

    public org.apache.airavata.model.workspace.Project success; // required
    public org.apache.airavata.model.error.InvalidRequestException ire; // required
    public org.apache.airavata.model.error.AiravataClientException ace; // required
    public org.apache.airavata.model.error.AiravataSystemException ase; // required
    public org.apache.airavata.model.error.ProjectNotFoundException pnfe; // 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"),
      IRE((short)1, "ire"),
      ACE((short)2, "ace"),
      ASE((short)3, "ase"),
      PNFE((short)4, "pnfe"),
      AE((short)5, "ae");

      private static final Map<String, _Fields> byName = new HashMap<String, _Fields>();

      static {
        for (_Fields field : EnumSet.allOf(_Fields.class)) {
          byName.put(field.getFieldName(), field);
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, or null if its not found.
       */
      public static _Fields findByThriftId(int fieldId) {
        switch(fieldId) {
          case 0: // SUCCESS
            return SUCCESS;
          case 1: // IRE
            return IRE;
          case 2: // ACE
            return ACE;
          case 3: // ASE
            return ASE;
          case 4: // PNFE
            return PNFE;
          case 5: // 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 IllegalArgumentException("Field " + fieldId + " doesn't exist!");
        return fields;
      }

      /**
       * Find the _Fields constant that matches name, or null if its not found.
       */
      public static _Fields findByName(String name) {
        return byName.get(name);
      }

      private final short _thriftId;
      private final String _fieldName;

      _Fields(short thriftId, String fieldName) {
        _thriftId = thriftId;
        _fieldName = fieldName;
      }

      public short getThriftFieldId() {
        return _thriftId;
      }

      public String getFieldName() {
        return _fieldName;
      }
    }

    // isset id assignments
    public static final Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
    static {
      Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new EnumMap<_Fields, org.apache.thrift.meta_data.FieldMetaData>(_Fields.class);
      tmpMap.put(_Fields.SUCCESS, new org.apache.thrift.meta_data.FieldMetaData("success", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.StructMetaData(org.apache.thrift.protocol.TType.STRUCT, org.apache.airavata.model.workspace.Project.class)));
      tmpMap.put(_Fields.IRE, new org.apache.thrift.meta_data.FieldMetaData("ire", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRUCT)));
      tmpMap.put(_Fields.ACE, new org.apache.thrift.meta_data.FieldMetaData("ace", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRUCT)));
      tmpMap.put(_Fields.ASE, new org.apache.thrift.meta_data.FieldMetaData("ase", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRUCT)));
      tmpMap.put(_Fields.PNFE, new org.apache.thrift.meta_data.FieldMetaData("pnfe", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRUCT)));
      tmpMap.put(_Fields.AE, new org.apache.thrift.meta_data.FieldMetaData("ae", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRUCT)));
      metaDataMap = Collections.unmodifiableMap(tmpMap);
      org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(getProject_result.class, metaDataMap);
    }

    public getProject_result() {
    }

    public getProject_result(
      org.apache.airavata.model.workspace.Project success,
      org.apache.airavata.model.error.InvalidRequestException ire,
      org.apache.airavata.model.error.AiravataClientException ace,
      org.apache.airavata.model.error.AiravataSystemException ase,
      org.apache.airavata.model.error.ProjectNotFoundException pnfe,
      org.apache.airavata.model.error.AuthorizationException ae)
    {
      this();
      this.success = success;
      this.ire = ire;
      this.ace = ace;
      this.ase = ase;
      this.pnfe = pnfe;
      this.ae = ae;
    }

    /**
     * Performs a deep copy on <i>other</i>.
     */
    public getProject_result(getProject_result other) {
      if (other.isSetSuccess()) {
        this.success = new org.apache.airavata.model.workspace.Project(other.success);
      }
      if (other.isSetIre()) {
        this.ire = new org.apache.airavata.model.error.InvalidRequestException(other.ire);
      }
      if (other.isSetAce()) {
        this.ace = new org.apache.airavata.model.error.AiravataClientException(other.ace);
      }
      if (other.isSetAse()) {
        this.ase = new org.apache.airavata.model.error.AiravataSystemException(other.ase);
      }
      if (other.isSetPnfe()) {
        this.pnfe = new org.apache.airavata.model.error.ProjectNotFoundException(other.pnfe);
      }
      if (other.isSetAe()) {
        this.ae = new org.apache.airavata.model.error.AuthorizationException(other.ae);
      }
    }

    public getProject_result deepCopy() {
      return new getProject_result(this);
    }

    @Override
    public void clear() {
      this.success = null;
      this.ire = null;
      this.ace = null;
      this.ase = null;
      this.pnfe = null;
      this.ae = null;
    }

    public org.apache.airavata.model.workspace.Project getSuccess() {
      return this.success;
    }

    public getProject_result setSuccess(org.apache.airavata.model.workspace.Project 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.model.error.InvalidRequestException getIre() {
      return this.ire;
    }

    public getProject_result setIre(org.apache.airavata.model.error.InvalidRequestException ire) {
      this.ire = ire;
      return this;
    }

    public void unsetIre() {
      this.ire = null;
    }

    /** Returns true if field ire is set (has been assigned a value) and false otherwise */
    public boolean isSetIre() {
      return this.ire != null;
    }

    public void setIreIsSet(boolean value) {
      if (!value) {
        this.ire = null;
      }
    }

    public org.apache.airavata.model.error.AiravataClientException getAce() {
      return this.ace;
    }

    public getProject_result setAce(org.apache.airavata.model.error.AiravataClientException ace) {
      this.ace = ace;
      return this;
    }

    public void unsetAce() {
      this.ace = null;
    }

    /** Returns true if field ace is set (has been assigned a value) and false otherwise */
    public boolean isSetAce() {
      return this.ace != null;
    }

    public void setAceIsSet(boolean value) {
      if (!value) {
        this.ace = null;
      }
    }

    public org.apache.airavata.model.error.AiravataSystemException getAse() {
      return this.ase;
    }

    public getProject_result setAse(org.apache.airavata.model.error.AiravataSystemException ase) {
      this.ase = ase;
      return this;
    }

    public void unsetAse() {
      this.ase = null;
    }

    /** Returns true if field ase is set (has been assigned a value) and false otherwise */
    public boolean isSetAse() {
      return this.ase != null;
    }

    public void setAseIsSet(boolean value) {
      if (!value) {
        this.ase = null;
      }
    }

    public org.apache.airavata.model.error.ProjectNotFoundException getPnfe() {
      return this.pnfe;
    }

    public getProject_result setPnfe(org.apache.airavata.model.error.ProjectNotFoundException pnfe) {
      this.pnfe = pnfe;
      return this;
    }

    public void unsetPnfe() {
      this.pnfe = null;
    }

    /** Returns true if field pnfe is set (has been assigned a value) and false otherwise */
    public boolean isSetPnfe() {
      return this.pnfe != null;
    }

    public void setPnfeIsSet(boolean value) {
      if (!value) {
        this.pnfe = null;
      }
    }

    public org.apache.airavata.model.error.AuthorizationException getAe() {
      return this.ae;
    }

    public getProject_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, Object value) {
      switch (field) {
      case SUCCESS:
        if (value == null) {
          unsetSuccess();
        } else {
          setSuccess((org.apache.airavata.model.workspace.Project)value);
        }
        break;

      case IRE:
        if (value == null) {
          unsetIre();
        } else {
          setIre((org.apache.airavata.model.error.InvalidRequestException)value);
        }
        break;

      case ACE:
        if (value == null) {
          unsetAce();
        } else {
          setAce((org.apache.airavata.model.error.AiravataClientException)value);
        }
        break;

      case ASE:
        if (value == null) {
          unsetAse();
        } else {
          setAse((org.apache.airavata.model.error.AiravataSystemException)value);
        }
        break;

      case PNFE:
        if (value == null) {
          unsetPnfe();
        } else {
          setPnfe((org.apache.airavata.model.error.ProjectNotFoundException)value);
        }
        break;

      case AE:
        if (value == null) {
          unsetAe();
        } else {
          setAe((org.apache.airavata.model.error.AuthorizationException)value);
        }
        break;

      }
    }

    public Object getFieldValue(_Fields field) {
      switch (field) {
      case SUCCESS:
        return getSuccess();

      case IRE:
        return getIre();

      case ACE:
        return getAce();

      case ASE:
        return getAse();

      case PNFE:
        return getPnfe();

      case AE:
        return getAe();

      }
      throw new IllegalStateException();
    }

    /** Returns true if field corresponding to fieldID is set (has been assigned a value) and false otherwise */
    public boolean isSet(_Fields field) {
      if (field == null) {
        throw new IllegalArgumentException();
      }

      switch (field) {
      case SUCCESS:
        return isSetSuccess();
      case IRE:
        return isSetIre();
      case ACE:
        return isSetAce();
      case ASE:
        return isSetAse();
      case PNFE:
        return isSetPnfe();
      case AE:
        return isSetAe();
      }
      throw new IllegalStateException();
    }

    @Override
    public boolean equals(Object that) {
      if (that == null)
        return false;
      if (that instanceof getProject_result)
        return this.equals((getProject_result)that);
      return false;
    }

    public boolean equals(getProject_result that) {
      if (that == null)
        return false;

      boolean this_present_success = true && this.isSetSuccess();
      boolean that_present_success = true && that.isSetSuccess();
      if (this_present_success || that_present_success) {
        if (!(this_present_success && that_present_success))
          return false;
        if (!this.success.equals(that.success))
          return false;
      }

      boolean this_present_ire = true && this.isSetIre();
      boolean that_present_ire = true && that.isSetIre();
      if (this_present_ire || that_present_ire) {
        if (!(this_present_ire && that_present_ire))
          return false;
        if (!this.ire.equals(that.ire))
          return false;
      }

      boolean this_present_ace = true && this.isSetAce();
      boolean that_present_ace = true && that.isSetAce();
      if (this_present_ace || that_present_ace) {
        if (!(this_present_ace && that_present_ace))
          return false;
        if (!this.ace.equals(that.ace))
          return false;
      }

      boolean this_present_ase = true && this.isSetAse();
      boolean that_present_ase = true && that.isSetAse();
      if (this_present_ase || that_present_ase) {
        if (!(this_present_ase && that_present_ase))
          return false;
        if (!this.ase.equals(that.ase))
          return false;
      }

      boolean this_present_pnfe = true && this.isSetPnfe();
      boolean that_present_pnfe = true && that.isSetPnfe();
      if (this_present_pnfe || that_present_pnfe) {
        if (!(this_present_pnfe && that_present_pnfe))
          return false;
        if (!this.pnfe.equals(that.pnfe))
          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() {
      List<Object> list = new ArrayList<Object>();

      boolean present_success = true && (isSetSuccess());
      list.add(present_success);
      if (present_success)
        list.add(success);

      boolean present_ire = true && (isSetIre());
      list.add(present_ire);
      if (present_ire)
        list.add(ire);

      boolean present_ace = true && (isSetAce());
      list.add(present_ace);
      if (present_ace)
        list.add(ace);

      boolean present_ase = true && (isSetAse());
      list.add(present_ase);
      if (present_ase)
        list.add(ase);

      boolean present_pnfe = true && (isSetPnfe());
      list.add(present_pnfe);
      if (present_pnfe)
        list.add(pnfe);

      boolean present_ae = true && (isSetAe());
      list.add(present_ae);
      if (present_ae)
        list.add(ae);

      return list.hashCode();
    }

    @Override
    public int compareTo(getProject_result other) {
      if (!getClass().equals(other.getClass())) {
        return getClass().getName().compareTo(other.getClass().getName());
      }

      int lastComparison = 0;

      lastComparison = Boolean.valueOf(isSetSuccess()).compareTo(other.isSetSuccess());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetSuccess()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.success, other.success);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = Boolean.valueOf(isSetIre()).compareTo(other.isSetIre());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetIre()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.ire, other.ire);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = Boolean.valueOf(isSetAce()).compareTo(other.isSetAce());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetAce()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.ace, other.ace);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = Boolean.valueOf(isSetAse()).compareTo(other.isSetAse());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetAse()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.ase, other.ase);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = Boolean.valueOf(isSetPnfe()).compareTo(other.isSetPnfe());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetPnfe()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.pnfe, other.pnfe);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = 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 {
      schemes.get(iprot.getScheme()).getScheme().read(iprot, this);
    }

    public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException {
      schemes.get(oprot.getScheme()).getScheme().write(oprot, this);
      }

    @Override
    public String toString() {
      StringBuilder sb = new StringBuilder("getProject_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("ire:");
      if (this.ire == null) {
        sb.append("null");
      } else {
        sb.append(this.ire);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("ace:");
      if (this.ace == null) {
        sb.append("null");
      } else {
        sb.append(this.ace);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("ase:");
      if (this.ase == null) {
        sb.append("null");
      } else {
        sb.append(this.ase);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("pnfe:");
      if (this.pnfe == null) {
        sb.append("null");
      } else {
        sb.append(this.pnfe);
      }
      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, 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 getProject_resultStandardSchemeFactory implements SchemeFactory {
      public getProject_resultStandardScheme getScheme() {
        return new getProject_resultStandardScheme();
      }
    }

    private static class getProject_resultStandardScheme extends StandardScheme<getProject_result> {

      public void read(org.apache.thrift.protocol.TProtocol iprot, getProject_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.Project();
                struct.success.read(iprot);
                struct.setSuccessIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 1: // IRE
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.ire = new org.apache.airavata.model.error.InvalidRequestException();
                struct.ire.read(iprot);
                struct.setIreIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 2: // ACE
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.ace = new org.apache.airavata.model.error.AiravataClientException();
                struct.ace.read(iprot);
                struct.setAceIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 3: // ASE
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.ase = new org.apache.airavata.model.error.AiravataSystemException();
                struct.ase.read(iprot);
                struct.setAseIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 4: // PNFE
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.pnfe = new org.apache.airavata.model.error.ProjectNotFoundException();
                struct.pnfe.read(iprot);
                struct.setPnfeIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 5: // 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, getProject_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.ire != null) {
          oprot.writeFieldBegin(IRE_FIELD_DESC);
          struct.ire.write(oprot);
          oprot.writeFieldEnd();
        }
        if (struct.ace != null) {
          oprot.writeFieldBegin(ACE_FIELD_DESC);
          struct.ace.write(oprot);
          oprot.writeFieldEnd();
        }
        if (struct.ase != null) {
          oprot.writeFieldBegin(ASE_FIELD_DESC);
          struct.ase.write(oprot);
          oprot.writeFieldEnd();
        }
        if (struct.pnfe != null) {
          oprot.writeFieldBegin(PNFE_FIELD_DESC);
          struct.pnfe.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 getProject_resultTupleSchemeFactory implements SchemeFactory {
      public getProject_resultTupleScheme getScheme() {
        return new getProject_resultTupleScheme();
      }
    }

    private static class getProject_resultTupleScheme extends TupleScheme<getProject_result> {

      @Override
      public void write(org.apache.thrift.protocol.TProtocol prot, getProject_result struct) throws org.apache.thrift.TException {
        TTupleProtocol oprot = (TTupleProtocol) prot;
        BitSet optionals = new BitSet();
        if (struct.isSetSuccess()) {
          optionals.set(0);
        }
        if (struct.isSetIre()) {
          optionals.set(1);
        }
        if (struct.isSetAce()) {
          optionals.set(2);
        }
        if (struct.isSetAse()) {
          optionals.set(3);
        }
        if (struct.isSetPnfe()) {
          optionals.set(4);
        }
        if (struct.isSetAe()) {
          optionals.set(5);
        }
        oprot.writeBitSet(optionals, 6);
        if (struct.isSetSuccess()) {
          struct.success.write(oprot);
        }
        if (struct.isSetIre()) {
          struct.ire.write(oprot);
        }
        if (struct.isSetAce()) {
          struct.ace.write(oprot);
        }
        if (struct.isSetAse()) {
          struct.ase.write(oprot);
        }
        if (struct.isSetPnfe()) {
          struct.pnfe.write(oprot);
        }
        if (struct.isSetAe()) {
          struct.ae.write(oprot);
        }
      }

      @Override
      public void read(org.apache.thrift.protocol.TProtocol prot, getProject_result struct) throws org.apache.thrift.TException {
        TTupleProtocol iprot = (TTupleProtocol) prot;
        BitSet incoming = iprot.readBitSet(6);
        if (incoming.get(0)) {
          struct.success = new org.apache.airavata.model.workspace.Project();
          struct.success.read(iprot);
          struct.setSuccessIsSet(true);
        }
        if (incoming.get(1)) {
          struct.ire = new org.apache.airavata.model.error.InvalidRequestException();
          struct.ire.read(iprot);
          struct.setIreIsSet(true);
        }
        if (incoming.get(2)) {
          struct.ace = new org.apache.airavata.model.error.AiravataClientException();
          struct.ace.read(iprot);
          struct.setAceIsSet(true);
        }
        if (incoming.get(3)) {
          struct.ase = new org.apache.airavata.model.error.AiravataSystemException();
          struct.ase.read(iprot);
          struct.setAseIsSet(true);
        }
        if (incoming.get(4)) {
          struct.pnfe = new org.apache.airavata.model.error.ProjectNotFoundException();
          struct.pnfe.read(iprot);
          struct.setPnfeIsSet(true);
        }
        if (incoming.get(5)) {
          struct.ae = new org.apache.airavata.model.error.AuthorizationException();
          struct.ae.read(iprot);
          struct.setAeIsSet(true);
        }
      }
    }

  }

  public static class deleteProject_args implements org.apache.thrift.TBase<deleteProject_args, deleteProject_args._Fields>, java.io.Serializable, Cloneable, Comparable<deleteProject_args>   {
    private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("deleteProject_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 PROJECT_ID_FIELD_DESC = new org.apache.thrift.protocol.TField("projectId", org.apache.thrift.protocol.TType.STRING, (short)2);

    private static final Map<Class<? extends IScheme>, SchemeFactory> schemes = new HashMap<Class<? extends IScheme>, SchemeFactory>();
    static {
      schemes.put(StandardScheme.class, new deleteProject_argsStandardSchemeFactory());
      schemes.put(TupleScheme.class, new deleteProject_argsTupleSchemeFactory());
    }

    public org.apache.airavata.model.security.AuthzToken authzToken; // required
    public String projectId; // required

    /** 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"),
      PROJECT_ID((short)2, "projectId");

      private static final Map<String, _Fields> byName = new HashMap<String, _Fields>();

      static {
        for (_Fields field : EnumSet.allOf(_Fields.class)) {
          byName.put(field.getFieldName(), field);
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, or null if its not found.
       */
      public static _Fields findByThriftId(int fieldId) {
        switch(fieldId) {
          case 1: // AUTHZ_TOKEN
            return AUTHZ_TOKEN;
          case 2: // PROJECT_ID
            return PROJECT_ID;
          default:
            return null;
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, throwing an exception
       * if it is not found.
       */
      public static _Fields findByThriftIdOrThrow(int fieldId) {
        _Fields fields = findByThriftId(fieldId);
        if (fields == null) throw new IllegalArgumentException("Field " + fieldId + " doesn't exist!");
        return fields;
      }

      /**
       * Find the _Fields constant that matches name, or null if its not found.
       */
      public static _Fields findByName(String name) {
        return byName.get(name);
      }

      private final short _thriftId;
      private final String _fieldName;

      _Fields(short thriftId, String fieldName) {
        _thriftId = thriftId;
        _fieldName = fieldName;
      }

      public short getThriftFieldId() {
        return _thriftId;
      }

      public String getFieldName() {
        return _fieldName;
      }
    }

    // isset id assignments
    public static final Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
    static {
      Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new EnumMap<_Fields, org.apache.thrift.meta_data.FieldMetaData>(_Fields.class);
      tmpMap.put(_Fields.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.PROJECT_ID, new org.apache.thrift.meta_data.FieldMetaData("projectId", org.apache.thrift.TFieldRequirementType.REQUIRED, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING)));
      metaDataMap = Collections.unmodifiableMap(tmpMap);
      org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(deleteProject_args.class, metaDataMap);
    }

    public deleteProject_args() {
    }

    public deleteProject_args(
      org.apache.airavata.model.security.AuthzToken authzToken,
      String projectId)
    {
      this();
      this.authzToken = authzToken;
      this.projectId = projectId;
    }

    /**
     * Performs a deep copy on <i>other</i>.
     */
    public deleteProject_args(deleteProject_args other) {
      if (other.isSetAuthzToken()) {
        this.authzToken = new org.apache.airavata.model.security.AuthzToken(other.authzToken);
      }
      if (other.isSetProjectId()) {
        this.projectId = other.projectId;
      }
    }

    public deleteProject_args deepCopy() {
      return new deleteProject_args(this);
    }

    @Override
    public void clear() {
      this.authzToken = null;
      this.projectId = null;
    }

    public org.apache.airavata.model.security.AuthzToken getAuthzToken() {
      return this.authzToken;
    }

    public deleteProject_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 String getProjectId() {
      return this.projectId;
    }

    public deleteProject_args setProjectId(String projectId) {
      this.projectId = projectId;
      return this;
    }

    public void unsetProjectId() {
      this.projectId = null;
    }

    /** Returns true if field projectId is set (has been assigned a value) and false otherwise */
    public boolean isSetProjectId() {
      return this.projectId != null;
    }

    public void setProjectIdIsSet(boolean value) {
      if (!value) {
        this.projectId = null;
      }
    }

    public void setFieldValue(_Fields field, Object value) {
      switch (field) {
      case AUTHZ_TOKEN:
        if (value == null) {
          unsetAuthzToken();
        } else {
          setAuthzToken((org.apache.airavata.model.security.AuthzToken)value);
        }
        break;

      case PROJECT_ID:
        if (value == null) {
          unsetProjectId();
        } else {
          setProjectId((String)value);
        }
        break;

      }
    }

    public Object getFieldValue(_Fields field) {
      switch (field) {
      case AUTHZ_TOKEN:
        return getAuthzToken();

      case PROJECT_ID:
        return getProjectId();

      }
      throw new IllegalStateException();
    }

    /** Returns true if field corresponding to fieldID is set (has been assigned a value) and false otherwise */
    public boolean isSet(_Fields field) {
      if (field == null) {
        throw new IllegalArgumentException();
      }

      switch (field) {
      case AUTHZ_TOKEN:
        return isSetAuthzToken();
      case PROJECT_ID:
        return isSetProjectId();
      }
      throw new IllegalStateException();
    }

    @Override
    public boolean equals(Object that) {
      if (that == null)
        return false;
      if (that instanceof deleteProject_args)
        return this.equals((deleteProject_args)that);
      return false;
    }

    public boolean equals(deleteProject_args that) {
      if (that == null)
        return false;

      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_projectId = true && this.isSetProjectId();
      boolean that_present_projectId = true && that.isSetProjectId();
      if (this_present_projectId || that_present_projectId) {
        if (!(this_present_projectId && that_present_projectId))
          return false;
        if (!this.projectId.equals(that.projectId))
          return false;
      }

      return true;
    }

    @Override
    public int hashCode() {
      List<Object> list = new ArrayList<Object>();

      boolean present_authzToken = true && (isSetAuthzToken());
      list.add(present_authzToken);
      if (present_authzToken)
        list.add(authzToken);

      boolean present_projectId = true && (isSetProjectId());
      list.add(present_projectId);
      if (present_projectId)
        list.add(projectId);

      return list.hashCode();
    }

    @Override
    public int compareTo(deleteProject_args other) {
      if (!getClass().equals(other.getClass())) {
        return getClass().getName().compareTo(other.getClass().getName());
      }

      int lastComparison = 0;

      lastComparison = 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 = Boolean.valueOf(isSetProjectId()).compareTo(other.isSetProjectId());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetProjectId()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.projectId, other.projectId);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      return 0;
    }

    public _Fields fieldForId(int fieldId) {
      return _Fields.findByThriftId(fieldId);
    }

    public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
      schemes.get(iprot.getScheme()).getScheme().read(iprot, this);
    }

    public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException {
      schemes.get(oprot.getScheme()).getScheme().write(oprot, this);
    }

    @Override
    public String toString() {
      StringBuilder sb = new StringBuilder("deleteProject_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("projectId:");
      if (this.projectId == null) {
        sb.append("null");
      } else {
        sb.append(this.projectId);
      }
      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 (projectId == null) {
        throw new org.apache.thrift.protocol.TProtocolException("Required field 'projectId' 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, 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 deleteProject_argsStandardSchemeFactory implements SchemeFactory {
      public deleteProject_argsStandardScheme getScheme() {
        return new deleteProject_argsStandardScheme();
      }
    }

    private static class deleteProject_argsStandardScheme extends StandardScheme<deleteProject_args> {

      public void read(org.apache.thrift.protocol.TProtocol iprot, deleteProject_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: // PROJECT_ID
              if (schemeField.type == org.apache.thrift.protocol.TType.STRING) {
                struct.projectId = iprot.readString();
                struct.setProjectIdIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            default:
              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
          }
          iprot.readFieldEnd();
        }
        iprot.readStructEnd();

        // check for required fields of primitive type, which can't be checked in the validate method
        struct.validate();
      }

      public void write(org.apache.thrift.protocol.TProtocol oprot, deleteProject_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.projectId != null) {
          oprot.writeFieldBegin(PROJECT_ID_FIELD_DESC);
          oprot.writeString(struct.projectId);
          oprot.writeFieldEnd();
        }
        oprot.writeFieldStop();
        oprot.writeStructEnd();
      }

    }

    private static class deleteProject_argsTupleSchemeFactory implements SchemeFactory {
      public deleteProject_argsTupleScheme getScheme() {
        return new deleteProject_argsTupleScheme();
      }
    }

    private static class deleteProject_argsTupleScheme extends TupleScheme<deleteProject_args> {

      @Override
      public void write(org.apache.thrift.protocol.TProtocol prot, deleteProject_args struct) throws org.apache.thrift.TException {
        TTupleProtocol oprot = (TTupleProtocol) prot;
        struct.authzToken.write(oprot);
        oprot.writeString(struct.projectId);
      }

      @Override
      public void read(org.apache.thrift.protocol.TProtocol prot, deleteProject_args struct) throws org.apache.thrift.TException {
        TTupleProtocol iprot = (TTupleProtocol) prot;
        struct.authzToken = new org.apache.airavata.model.security.AuthzToken();
        struct.authzToken.read(iprot);
        struct.setAuthzTokenIsSet(true);
        struct.projectId = iprot.readString();
        struct.setProjectIdIsSet(true);
      }
    }

  }

  public static class deleteProject_result implements org.apache.thrift.TBase<deleteProject_result, deleteProject_result._Fields>, java.io.Serializable, Cloneable, Comparable<deleteProject_result>   {
    private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("deleteProject_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 IRE_FIELD_DESC = new org.apache.thrift.protocol.TField("ire", org.apache.thrift.protocol.TType.STRUCT, (short)1);
    private static final org.apache.thrift.protocol.TField ACE_FIELD_DESC = new org.apache.thrift.protocol.TField("ace", org.apache.thrift.protocol.TType.STRUCT, (short)2);
    private static final org.apache.thrift.protocol.TField ASE_FIELD_DESC = new org.apache.thrift.protocol.TField("ase", org.apache.thrift.protocol.TType.STRUCT, (short)3);
    private static final org.apache.thrift.protocol.TField PNFE_FIELD_DESC = new org.apache.thrift.protocol.TField("pnfe", org.apache.thrift.protocol.TType.STRUCT, (short)4);
    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)5);

    private static final Map<Class<? extends IScheme>, SchemeFactory> schemes = new HashMap<Class<? extends IScheme>, SchemeFactory>();
    static {
      schemes.put(StandardScheme.class, new deleteProject_resultStandardSchemeFactory());
      schemes.put(TupleScheme.class, new deleteProject_resultTupleSchemeFactory());
    }

    public boolean success; // required
    public org.apache.airavata.model.error.InvalidRequestException ire; // required
    public org.apache.airavata.model.error.AiravataClientException ace; // required
    public org.apache.airavata.model.error.AiravataSystemException ase; // required
    public org.apache.airavata.model.error.ProjectNotFoundException pnfe; // 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"),
      IRE((short)1, "ire"),
      ACE((short)2, "ace"),
      ASE((short)3, "ase"),
      PNFE((short)4, "pnfe"),
      AE((short)5, "ae");

      private static final Map<String, _Fields> byName = new HashMap<String, _Fields>();

      static {
        for (_Fields field : EnumSet.allOf(_Fields.class)) {
          byName.put(field.getFieldName(), field);
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, or null if its not found.
       */
      public static _Fields findByThriftId(int fieldId) {
        switch(fieldId) {
          case 0: // SUCCESS
            return SUCCESS;
          case 1: // IRE
            return IRE;
          case 2: // ACE
            return ACE;
          case 3: // ASE
            return ASE;
          case 4: // PNFE
            return PNFE;
          case 5: // 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 IllegalArgumentException("Field " + fieldId + " doesn't exist!");
        return fields;
      }

      /**
       * Find the _Fields constant that matches name, or null if its not found.
       */
      public static _Fields findByName(String name) {
        return byName.get(name);
      }

      private final short _thriftId;
      private final String _fieldName;

      _Fields(short thriftId, String fieldName) {
        _thriftId = thriftId;
        _fieldName = fieldName;
      }

      public short getThriftFieldId() {
        return _thriftId;
      }

      public String getFieldName() {
        return _fieldName;
      }
    }

    // isset id assignments
    private static final int __SUCCESS_ISSET_ID = 0;
    private byte __isset_bitfield = 0;
    public static final Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
    static {
      Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new EnumMap<_Fields, org.apache.thrift.meta_data.FieldMetaData>(_Fields.class);
      tmpMap.put(_Fields.SUCCESS, new org.apache.thrift.meta_data.FieldMetaData("success", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.BOOL)));
      tmpMap.put(_Fields.IRE, new org.apache.thrift.meta_data.FieldMetaData("ire", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRUCT)));
      tmpMap.put(_Fields.ACE, new org.apache.thrift.meta_data.FieldMetaData("ace", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRUCT)));
      tmpMap.put(_Fields.ASE, new org.apache.thrift.meta_data.FieldMetaData("ase", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRUCT)));
      tmpMap.put(_Fields.PNFE, new org.apache.thrift.meta_data.FieldMetaData("pnfe", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRUCT)));
      tmpMap.put(_Fields.AE, new org.apache.thrift.meta_data.FieldMetaData("ae", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRUCT)));
      metaDataMap = Collections.unmodifiableMap(tmpMap);
      org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(deleteProject_result.class, metaDataMap);
    }

    public deleteProject_result() {
    }

    public deleteProject_result(
      boolean success,
      org.apache.airavata.model.error.InvalidRequestException ire,
      org.apache.airavata.model.error.AiravataClientException ace,
      org.apache.airavata.model.error.AiravataSystemException ase,
      org.apache.airavata.model.error.ProjectNotFoundException pnfe,
      org.apache.airavata.model.error.AuthorizationException ae)
    {
      this();
      this.success = success;
      setSuccessIsSet(true);
      this.ire = ire;
      this.ace = ace;
      this.ase = ase;
      this.pnfe = pnfe;
      this.ae = ae;
    }

    /**
     * Performs a deep copy on <i>other</i>.
     */
    public deleteProject_result(deleteProject_result other) {
      __isset_bitfield = other.__isset_bitfield;
      this.success = other.success;
      if (other.isSetIre()) {
        this.ire = new org.apache.airavata.model.error.InvalidRequestException(other.ire);
      }
      if (other.isSetAce()) {
        this.ace = new org.apache.airavata.model.error.AiravataClientException(other.ace);
      }
      if (other.isSetAse()) {
        this.ase = new org.apache.airavata.model.error.AiravataSystemException(other.ase);
      }
      if (other.isSetPnfe()) {
        this.pnfe = new org.apache.airavata.model.error.ProjectNotFoundException(other.pnfe);
      }
      if (other.isSetAe()) {
        this.ae = new org.apache.airavata.model.error.AuthorizationException(other.ae);
      }
    }

    public deleteProject_result deepCopy() {
      return new deleteProject_result(this);
    }

    @Override
    public void clear() {
      setSuccessIsSet(false);
      this.success = false;
      this.ire = null;
      this.ace = null;
      this.ase = null;
      this.pnfe = null;
      this.ae = null;
    }

    public boolean isSuccess() {
      return this.success;
    }

    public deleteProject_result setSuccess(boolean success) {
      this.success = success;
      setSuccessIsSet(true);
      return this;
    }

    public void unsetSuccess() {
      __isset_bitfield = EncodingUtils.clearBit(__isset_bitfield, __SUCCESS_ISSET_ID);
    }

    /** Returns true if field success is set (has been assigned a value) and false otherwise */
    public boolean isSetSuccess() {
      return EncodingUtils.testBit(__isset_bitfield, __SUCCESS_ISSET_ID);
    }

    public void setSuccessIsSet(boolean value) {
      __isset_bitfield = EncodingUtils.setBit(__isset_bitfield, __SUCCESS_ISSET_ID, value);
    }

    public org.apache.airavata.model.error.InvalidRequestException getIre() {
      return this.ire;
    }

    public deleteProject_result setIre(org.apache.airavata.model.error.InvalidRequestException ire) {
      this.ire = ire;
      return this;
    }

    public void unsetIre() {
      this.ire = null;
    }

    /** Returns true if field ire is set (has been assigned a value) and false otherwise */
    public boolean isSetIre() {
      return this.ire != null;
    }

    public void setIreIsSet(boolean value) {
      if (!value) {
        this.ire = null;
      }
    }

    public org.apache.airavata.model.error.AiravataClientException getAce() {
      return this.ace;
    }

    public deleteProject_result setAce(org.apache.airavata.model.error.AiravataClientException ace) {
      this.ace = ace;
      return this;
    }

    public void unsetAce() {
      this.ace = null;
    }

    /** Returns true if field ace is set (has been assigned a value) and false otherwise */
    public boolean isSetAce() {
      return this.ace != null;
    }

    public void setAceIsSet(boolean value) {
      if (!value) {
        this.ace = null;
      }
    }

    public org.apache.airavata.model.error.AiravataSystemException getAse() {
      return this.ase;
    }

    public deleteProject_result setAse(org.apache.airavata.model.error.AiravataSystemException ase) {
      this.ase = ase;
      return this;
    }

    public void unsetAse() {
      this.ase = null;
    }

    /** Returns true if field ase is set (has been assigned a value) and false otherwise */
    public boolean isSetAse() {
      return this.ase != null;
    }

    public void setAseIsSet(boolean value) {
      if (!value) {
        this.ase = null;
      }
    }

    public org.apache.airavata.model.error.ProjectNotFoundException getPnfe() {
      return this.pnfe;
    }

    public deleteProject_result setPnfe(org.apache.airavata.model.error.ProjectNotFoundException pnfe) {
      this.pnfe = pnfe;
      return this;
    }

    public void unsetPnfe() {
      this.pnfe = null;
    }

    /** Returns true if field pnfe is set (has been assigned a value) and false otherwise */
    public boolean isSetPnfe() {
      return this.pnfe != null;
    }

    public void setPnfeIsSet(boolean value) {
      if (!value) {
        this.pnfe = null;
      }
    }

    public org.apache.airavata.model.error.AuthorizationException getAe() {
      return this.ae;
    }

    public deleteProject_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, Object value) {
      switch (field) {
      case SUCCESS:
        if (value == null) {
          unsetSuccess();
        } else {
          setSuccess((Boolean)value);
        }
        break;

      case IRE:
        if (value == null) {
          unsetIre();
        } else {
          setIre((org.apache.airavata.model.error.InvalidRequestException)value);
        }
        break;

      case ACE:
        if (value == null) {
          unsetAce();
        } else {
          setAce((org.apache.airavata.model.error.AiravataClientException)value);
        }
        break;

      case ASE:
        if (value == null) {
          unsetAse();
        } else {
          setAse((org.apache.airavata.model.error.AiravataSystemException)value);
        }
        break;

      case PNFE:
        if (value == null) {
          unsetPnfe();
        } else {
          setPnfe((org.apache.airavata.model.error.ProjectNotFoundException)value);
        }
        break;

      case AE:
        if (value == null) {
          unsetAe();
        } else {
          setAe((org.apache.airavata.model.error.AuthorizationException)value);
        }
        break;

      }
    }

    public Object getFieldValue(_Fields field) {
      switch (field) {
      case SUCCESS:
        return Boolean.valueOf(isSuccess());

      case IRE:
        return getIre();

      case ACE:
        return getAce();

      case ASE:
        return getAse();

      case PNFE:
        return getPnfe();

      case AE:
        return getAe();

      }
      throw new IllegalStateException();
    }

    /** Returns true if field corresponding to fieldID is set (has been assigned a value) and false otherwise */
    public boolean isSet(_Fields field) {
      if (field == null) {
        throw new IllegalArgumentException();
      }

      switch (field) {
      case SUCCESS:
        return isSetSuccess();
      case IRE:
        return isSetIre();
      case ACE:
        return isSetAce();
      case ASE:
        return isSetAse();
      case PNFE:
        return isSetPnfe();
      case AE:
        return isSetAe();
      }
      throw new IllegalStateException();
    }

    @Override
    public boolean equals(Object that) {
      if (that == null)
        return false;
      if (that instanceof deleteProject_result)
        return this.equals((deleteProject_result)that);
      return false;
    }

    public boolean equals(deleteProject_result that) {
      if (that == null)
        return false;

      boolean this_present_success = true;
      boolean that_present_success = true;
      if (this_present_success || that_present_success) {
        if (!(this_present_success && that_present_success))
          return false;
        if (this.success != that.success)
          return false;
      }

      boolean this_present_ire = true && this.isSetIre();
      boolean that_present_ire = true && that.isSetIre();
      if (this_present_ire || that_present_ire) {
        if (!(this_present_ire && that_present_ire))
          return false;
        if (!this.ire.equals(that.ire))
          return false;
      }

      boolean this_present_ace = true && this.isSetAce();
      boolean that_present_ace = true && that.isSetAce();
      if (this_present_ace || that_present_ace) {
        if (!(this_present_ace && that_present_ace))
          return false;
        if (!this.ace.equals(that.ace))
          return false;
      }

      boolean this_present_ase = true && this.isSetAse();
      boolean that_present_ase = true && that.isSetAse();
      if (this_present_ase || that_present_ase) {
        if (!(this_present_ase && that_present_ase))
          return false;
        if (!this.ase.equals(that.ase))
          return false;
      }

      boolean this_present_pnfe = true && this.isSetPnfe();
      boolean that_present_pnfe = true && that.isSetPnfe();
      if (this_present_pnfe || that_present_pnfe) {
        if (!(this_present_pnfe && that_present_pnfe))
          return false;
        if (!this.pnfe.equals(that.pnfe))
          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() {
      List<Object> list = new ArrayList<Object>();

      boolean present_success = true;
      list.add(present_success);
      if (present_success)
        list.add(success);

      boolean present_ire = true && (isSetIre());
      list.add(present_ire);
      if (present_ire)
        list.add(ire);

      boolean present_ace = true && (isSetAce());
      list.add(present_ace);
      if (present_ace)
        list.add(ace);

      boolean present_ase = true && (isSetAse());
      list.add(present_ase);
      if (present_ase)
        list.add(ase);

      boolean present_pnfe = true && (isSetPnfe());
      list.add(present_pnfe);
      if (present_pnfe)
        list.add(pnfe);

      boolean present_ae = true && (isSetAe());
      list.add(present_ae);
      if (present_ae)
        list.add(ae);

      return list.hashCode();
    }

    @Override
    public int compareTo(deleteProject_result other) {
      if (!getClass().equals(other.getClass())) {
        return getClass().getName().compareTo(other.getClass().getName());
      }

      int lastComparison = 0;

      lastComparison = Boolean.valueOf(isSetSuccess()).compareTo(other.isSetSuccess());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetSuccess()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.success, other.success);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = Boolean.valueOf(isSetIre()).compareTo(other.isSetIre());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetIre()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.ire, other.ire);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = Boolean.valueOf(isSetAce()).compareTo(other.isSetAce());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetAce()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.ace, other.ace);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = Boolean.valueOf(isSetAse()).compareTo(other.isSetAse());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetAse()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.ase, other.ase);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = Boolean.valueOf(isSetPnfe()).compareTo(other.isSetPnfe());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetPnfe()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.pnfe, other.pnfe);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = 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 {
      schemes.get(iprot.getScheme()).getScheme().read(iprot, this);
    }

    public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException {
      schemes.get(oprot.getScheme()).getScheme().write(oprot, this);
      }

    @Override
    public String toString() {
      StringBuilder sb = new StringBuilder("deleteProject_result(");
      boolean first = true;

      sb.append("success:");
      sb.append(this.success);
      first = false;
      if (!first) sb.append(", ");
      sb.append("ire:");
      if (this.ire == null) {
        sb.append("null");
      } else {
        sb.append(this.ire);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("ace:");
      if (this.ace == null) {
        sb.append("null");
      } else {
        sb.append(this.ace);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("ase:");
      if (this.ase == null) {
        sb.append("null");
      } else {
        sb.append(this.ase);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("pnfe:");
      if (this.pnfe == null) {
        sb.append("null");
      } else {
        sb.append(this.pnfe);
      }
      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, 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 deleteProject_resultStandardSchemeFactory implements SchemeFactory {
      public deleteProject_resultStandardScheme getScheme() {
        return new deleteProject_resultStandardScheme();
      }
    }

    private static class deleteProject_resultStandardScheme extends StandardScheme<deleteProject_result> {

      public void read(org.apache.thrift.protocol.TProtocol iprot, deleteProject_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: // IRE
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.ire = new org.apache.airavata.model.error.InvalidRequestException();
                struct.ire.read(iprot);
                struct.setIreIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 2: // ACE
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.ace = new org.apache.airavata.model.error.AiravataClientException();
                struct.ace.read(iprot);
                struct.setAceIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 3: // ASE
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.ase = new org.apache.airavata.model.error.AiravataSystemException();
                struct.ase.read(iprot);
                struct.setAseIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 4: // PNFE
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.pnfe = new org.apache.airavata.model.error.ProjectNotFoundException();
                struct.pnfe.read(iprot);
                struct.setPnfeIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 5: // 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, deleteProject_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.ire != null) {
          oprot.writeFieldBegin(IRE_FIELD_DESC);
          struct.ire.write(oprot);
          oprot.writeFieldEnd();
        }
        if (struct.ace != null) {
          oprot.writeFieldBegin(ACE_FIELD_DESC);
          struct.ace.write(oprot);
          oprot.writeFieldEnd();
        }
        if (struct.ase != null) {
          oprot.writeFieldBegin(ASE_FIELD_DESC);
          struct.ase.write(oprot);
          oprot.writeFieldEnd();
        }
        if (struct.pnfe != null) {
          oprot.writeFieldBegin(PNFE_FIELD_DESC);
          struct.pnfe.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 deleteProject_resultTupleSchemeFactory implements SchemeFactory {
      public deleteProject_resultTupleScheme getScheme() {
        return new deleteProject_resultTupleScheme();
      }
    }

    private static class deleteProject_resultTupleScheme extends TupleScheme<deleteProject_result> {

      @Override
      public void write(org.apache.thrift.protocol.TProtocol prot, deleteProject_result struct) throws org.apache.thrift.TException {
        TTupleProtocol oprot = (TTupleProtocol) prot;
        BitSet optionals = new BitSet();
        if (struct.isSetSuccess()) {
          optionals.set(0);
        }
        if (struct.isSetIre()) {
          optionals.set(1);
        }
        if (struct.isSetAce()) {
          optionals.set(2);
        }
        if (struct.isSetAse()) {
          optionals.set(3);
        }
        if (struct.isSetPnfe()) {
          optionals.set(4);
        }
        if (struct.isSetAe()) {
          optionals.set(5);
        }
        oprot.writeBitSet(optionals, 6);
        if (struct.isSetSuccess()) {
          oprot.writeBool(struct.success);
        }
        if (struct.isSetIre()) {
          struct.ire.write(oprot);
        }
        if (struct.isSetAce()) {
          struct.ace.write(oprot);
        }
        if (struct.isSetAse()) {
          struct.ase.write(oprot);
        }
        if (struct.isSetPnfe()) {
          struct.pnfe.write(oprot);
        }
        if (struct.isSetAe()) {
          struct.ae.write(oprot);
        }
      }

      @Override
      public void read(org.apache.thrift.protocol.TProtocol prot, deleteProject_result struct) throws org.apache.thrift.TException {
        TTupleProtocol iprot = (TTupleProtocol) prot;
        BitSet incoming = iprot.readBitSet(6);
        if (incoming.get(0)) {
          struct.success = iprot.readBool();
          struct.setSuccessIsSet(true);
        }
        if (incoming.get(1)) {
          struct.ire = new org.apache.airavata.model.error.InvalidRequestException();
          struct.ire.read(iprot);
          struct.setIreIsSet(true);
        }
        if (incoming.get(2)) {
          struct.ace = new org.apache.airavata.model.error.AiravataClientException();
          struct.ace.read(iprot);
          struct.setAceIsSet(true);
        }
        if (incoming.get(3)) {
          struct.ase = new org.apache.airavata.model.error.AiravataSystemException();
          struct.ase.read(iprot);
          struct.setAseIsSet(true);
        }
        if (incoming.get(4)) {
          struct.pnfe = new org.apache.airavata.model.error.ProjectNotFoundException();
          struct.pnfe.read(iprot);
          struct.setPnfeIsSet(true);
        }
        if (incoming.get(5)) {
          struct.ae = new org.apache.airavata.model.error.AuthorizationException();
          struct.ae.read(iprot);
          struct.setAeIsSet(true);
        }
      }
    }

  }

  public static class getUserProjects_args implements org.apache.thrift.TBase<getUserProjects_args, getUserProjects_args._Fields>, java.io.Serializable, Cloneable, Comparable<getUserProjects_args>   {
    private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("getUserProjects_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.protocol.TField USER_NAME_FIELD_DESC = new org.apache.thrift.protocol.TField("userName", org.apache.thrift.protocol.TType.STRING, (short)3);
    private static final org.apache.thrift.protocol.TField LIMIT_FIELD_DESC = new org.apache.thrift.protocol.TField("limit", org.apache.thrift.protocol.TType.I32, (short)4);
    private static final org.apache.thrift.protocol.TField OFFSET_FIELD_DESC = new org.apache.thrift.protocol.TField("offset", org.apache.thrift.protocol.TType.I32, (short)5);

    private static final Map<Class<? extends IScheme>, SchemeFactory> schemes = new HashMap<Class<? extends IScheme>, SchemeFactory>();
    static {
      schemes.put(StandardScheme.class, new getUserProjects_argsStandardSchemeFactory());
      schemes.put(TupleScheme.class, new getUserProjects_argsTupleSchemeFactory());
    }

    public org.apache.airavata.model.security.AuthzToken authzToken; // required
    public String gatewayId; // required
    public String userName; // required
    public int limit; // required
    public int offset; // required

    /** 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"),
      USER_NAME((short)3, "userName"),
      LIMIT((short)4, "limit"),
      OFFSET((short)5, "offset");

      private static final Map<String, _Fields> byName = new HashMap<String, _Fields>();

      static {
        for (_Fields field : EnumSet.allOf(_Fields.class)) {
          byName.put(field.getFieldName(), field);
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, or null if its not found.
       */
      public static _Fields findByThriftId(int fieldId) {
        switch(fieldId) {
          case 1: // AUTHZ_TOKEN
            return AUTHZ_TOKEN;
          case 2: // GATEWAY_ID
            return GATEWAY_ID;
          case 3: // USER_NAME
            return USER_NAME;
          case 4: // LIMIT
            return LIMIT;
          case 5: // OFFSET
            return OFFSET;
          default:
            return null;
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, throwing an exception
       * if it is not found.
       */
      public static _Fields findByThriftIdOrThrow(int fieldId) {
        _Fields fields = findByThriftId(fieldId);
        if (fields == null) throw new IllegalArgumentException("Field " + fieldId + " doesn't exist!");
        return fields;
      }

      /**
       * Find the _Fields constant that matches name, or null if its not found.
       */
      public static _Fields findByName(String name) {
        return byName.get(name);
      }

      private final short _thriftId;
      private final String _fieldName;

      _Fields(short thriftId, String fieldName) {
        _thriftId = thriftId;
        _fieldName = fieldName;
      }

      public short getThriftFieldId() {
        return _thriftId;
      }

      public String getFieldName() {
        return _fieldName;
      }
    }

    // isset id assignments
    private static final int __LIMIT_ISSET_ID = 0;
    private static final int __OFFSET_ISSET_ID = 1;
    private byte __isset_bitfield = 0;
    public static final Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
    static {
      Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new EnumMap<_Fields, org.apache.thrift.meta_data.FieldMetaData>(_Fields.class);
      tmpMap.put(_Fields.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)));
      tmpMap.put(_Fields.USER_NAME, new org.apache.thrift.meta_data.FieldMetaData("userName", org.apache.thrift.TFieldRequirementType.REQUIRED, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING)));
      tmpMap.put(_Fields.LIMIT, new org.apache.thrift.meta_data.FieldMetaData("limit", org.apache.thrift.TFieldRequirementType.REQUIRED, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.I32)));
      tmpMap.put(_Fields.OFFSET, new org.apache.thrift.meta_data.FieldMetaData("offset", org.apache.thrift.TFieldRequirementType.REQUIRED, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.I32)));
      metaDataMap = Collections.unmodifiableMap(tmpMap);
      org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(getUserProjects_args.class, metaDataMap);
    }

    public getUserProjects_args() {
    }

    public getUserProjects_args(
      org.apache.airavata.model.security.AuthzToken authzToken,
      String gatewayId,
      String userName,
      int limit,
      int offset)
    {
      this();
      this.authzToken = authzToken;
      this.gatewayId = gatewayId;
      this.userName = userName;
      this.limit = limit;
      setLimitIsSet(true);
      this.offset = offset;
      setOffsetIsSet(true);
    }

    /**
     * Performs a deep copy on <i>other</i>.
     */
    public getUserProjects_args(getUserProjects_args other) {
      __isset_bitfield = other.__isset_bitfield;
      if (other.isSetAuthzToken()) {
        this.authzToken = new org.apache.airavata.model.security.AuthzToken(other.authzToken);
      }
      if (other.isSetGatewayId()) {
        this.gatewayId = other.gatewayId;
      }
      if (other.isSetUserName()) {
        this.userName = other.userName;
      }
      this.limit = other.limit;
      this.offset = other.offset;
    }

    public getUserProjects_args deepCopy() {
      return new getUserProjects_args(this);
    }

    @Override
    public void clear() {
      this.authzToken = null;
      this.gatewayId = null;
      this.userName = null;
      setLimitIsSet(false);
      this.limit = 0;
      setOffsetIsSet(false);
      this.offset = 0;
    }

    public org.apache.airavata.model.security.AuthzToken getAuthzToken() {
      return this.authzToken;
    }

    public getUserProjects_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 String getGatewayId() {
      return this.gatewayId;
    }

    public getUserProjects_args setGatewayId(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 String getUserName() {
      return this.userName;
    }

    public getUserProjects_args setUserName(String userName) {
      this.userName = userName;
      return this;
    }

    public void unsetUserName() {
      this.userName = null;
    }

    /** Returns true if field userName is set (has been assigned a value) and false otherwise */
    public boolean isSetUserName() {
      return this.userName != null;
    }

    public void setUserNameIsSet(boolean value) {
      if (!value) {
        this.userName = null;
      }
    }

    public int getLimit() {
      return this.limit;
    }

    public getUserProjects_args setLimit(int limit) {
      this.limit = limit;
      setLimitIsSet(true);
      return this;
    }

    public void unsetLimit() {
      __isset_bitfield = EncodingUtils.clearBit(__isset_bitfield, __LIMIT_ISSET_ID);
    }

    /** Returns true if field limit is set (has been assigned a value) and false otherwise */
    public boolean isSetLimit() {
      return EncodingUtils.testBit(__isset_bitfield, __LIMIT_ISSET_ID);
    }

    public void setLimitIsSet(boolean value) {
      __isset_bitfield = EncodingUtils.setBit(__isset_bitfield, __LIMIT_ISSET_ID, value);
    }

    public int getOffset() {
      return this.offset;
    }

    public getUserProjects_args setOffset(int offset) {
      this.offset = offset;
      setOffsetIsSet(true);
      return this;
    }

    public void unsetOffset() {
      __isset_bitfield = EncodingUtils.clearBit(__isset_bitfield, __OFFSET_ISSET_ID);
    }

    /** Returns true if field offset is set (has been assigned a value) and false otherwise */
    public boolean isSetOffset() {
      return EncodingUtils.testBit(__isset_bitfield, __OFFSET_ISSET_ID);
    }

    public void setOffsetIsSet(boolean value) {
      __isset_bitfield = EncodingUtils.setBit(__isset_bitfield, __OFFSET_ISSET_ID, value);
    }

    public void setFieldValue(_Fields field, 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((String)value);
        }
        break;

      case USER_NAME:
        if (value == null) {
          unsetUserName();
        } else {
          setUserName((String)value);
        }
        break;

      case LIMIT:
        if (value == null) {
          unsetLimit();
        } else {
          setLimit((Integer)value);
        }
        break;

      case OFFSET:
        if (value == null) {
          unsetOffset();
        } else {
          setOffset((Integer)value);
        }
        break;

      }
    }

    public Object getFieldValue(_Fields field) {
      switch (field) {
      case AUTHZ_TOKEN:
        return getAuthzToken();

      case GATEWAY_ID:
        return getGatewayId();

      case USER_NAME:
        return getUserName();

      case LIMIT:
        return Integer.valueOf(getLimit());

      case OFFSET:
        return Integer.valueOf(getOffset());

      }
      throw new IllegalStateException();
    }

    /** Returns true if field corresponding to fieldID is set (has been assigned a value) and false otherwise */
    public boolean isSet(_Fields field) {
      if (field == null) {
        throw new IllegalArgumentException();
      }

      switch (field) {
      case AUTHZ_TOKEN:
        return isSetAuthzToken();
      case GATEWAY_ID:
        return isSetGatewayId();
      case USER_NAME:
        return isSetUserName();
      case LIMIT:
        return isSetLimit();
      case OFFSET:
        return isSetOffset();
      }
      throw new IllegalStateException();
    }

    @Override
    public boolean equals(Object that) {
      if (that == null)
        return false;
      if (that instanceof getUserProjects_args)
        return this.equals((getUserProjects_args)that);
      return false;
    }

    public boolean equals(getUserProjects_args that) {
      if (that == null)
        return false;

      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;
      }

      boolean this_present_userName = true && this.isSetUserName();
      boolean that_present_userName = true && that.isSetUserName();
      if (this_present_userName || that_present_userName) {
        if (!(this_present_userName && that_present_userName))
          return false;
        if (!this.userName.equals(that.userName))
          return false;
      }

      boolean this_present_limit = true;
      boolean that_present_limit = true;
      if (this_present_limit || that_present_limit) {
        if (!(this_present_limit && that_present_limit))
          return false;
        if (this.limit != that.limit)
          return false;
      }

      boolean this_present_offset = true;
      boolean that_present_offset = true;
      if (this_present_offset || that_present_offset) {
        if (!(this_present_offset && that_present_offset))
          return false;
        if (this.offset != that.offset)
          return false;
      }

      return true;
    }

    @Override
    public int hashCode() {
      List<Object> list = new ArrayList<Object>();

      boolean present_authzToken = true && (isSetAuthzToken());
      list.add(present_authzToken);
      if (present_authzToken)
        list.add(authzToken);

      boolean present_gatewayId = true && (isSetGatewayId());
      list.add(present_gatewayId);
      if (present_gatewayId)
        list.add(gatewayId);

      boolean present_userName = true && (isSetUserName());
      list.add(present_userName);
      if (present_userName)
        list.add(userName);

      boolean present_limit = true;
      list.add(present_limit);
      if (present_limit)
        list.add(limit);

      boolean present_offset = true;
      list.add(present_offset);
      if (present_offset)
        list.add(offset);

      return list.hashCode();
    }

    @Override
    public int compareTo(getUserProjects_args other) {
      if (!getClass().equals(other.getClass())) {
        return getClass().getName().compareTo(other.getClass().getName());
      }

      int lastComparison = 0;

      lastComparison = 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 = 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;
        }
      }
      lastComparison = Boolean.valueOf(isSetUserName()).compareTo(other.isSetUserName());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetUserName()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.userName, other.userName);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = Boolean.valueOf(isSetLimit()).compareTo(other.isSetLimit());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetLimit()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.limit, other.limit);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = Boolean.valueOf(isSetOffset()).compareTo(other.isSetOffset());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetOffset()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.offset, other.offset);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      return 0;
    }

    public _Fields fieldForId(int fieldId) {
      return _Fields.findByThriftId(fieldId);
    }

    public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
      schemes.get(iprot.getScheme()).getScheme().read(iprot, this);
    }

    public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException {
      schemes.get(oprot.getScheme()).getScheme().write(oprot, this);
    }

    @Override
    public String toString() {
      StringBuilder sb = new StringBuilder("getUserProjects_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;
      if (!first) sb.append(", ");
      sb.append("userName:");
      if (this.userName == null) {
        sb.append("null");
      } else {
        sb.append(this.userName);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("limit:");
      sb.append(this.limit);
      first = false;
      if (!first) sb.append(", ");
      sb.append("offset:");
      sb.append(this.offset);
      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());
      }
      if (userName == null) {
        throw new org.apache.thrift.protocol.TProtocolException("Required field 'userName' was not present! Struct: " + toString());
      }
      // alas, we cannot check 'limit' because it's a primitive and you chose the non-beans generator.
      // alas, we cannot check 'offset' because it's a primitive and you chose the non-beans generator.
      // 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, 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 getUserProjects_argsStandardSchemeFactory implements SchemeFactory {
      public getUserProjects_argsStandardScheme getScheme() {
        return new getUserProjects_argsStandardScheme();
      }
    }

    private static class getUserProjects_argsStandardScheme extends StandardScheme<getUserProjects_args> {

      public void read(org.apache.thrift.protocol.TProtocol iprot, getUserProjects_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;
            case 3: // USER_NAME
              if (schemeField.type == org.apache.thrift.protocol.TType.STRING) {
                struct.userName = iprot.readString();
                struct.setUserNameIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 4: // LIMIT
              if (schemeField.type == org.apache.thrift.protocol.TType.I32) {
                struct.limit = iprot.readI32();
                struct.setLimitIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 5: // OFFSET
              if (schemeField.type == org.apache.thrift.protocol.TType.I32) {
                struct.offset = iprot.readI32();
                struct.setOffsetIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            default:
              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
          }
          iprot.readFieldEnd();
        }
        iprot.readStructEnd();

        // check for required fields of primitive type, which can't be checked in the validate method
        if (!struct.isSetLimit()) {
          throw new org.apache.thrift.protocol.TProtocolException("Required field 'limit' was not found in serialized data! Struct: " + toString());
        }
        if (!struct.isSetOffset()) {
          throw new org.apache.thrift.protocol.TProtocolException("Required field 'offset' was not found in serialized data! Struct: " + toString());
        }
        struct.validate();
      }

      public void write(org.apache.thrift.protocol.TProtocol oprot, getUserProjects_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();
        }
        if (struct.userName != null) {
          oprot.writeFieldBegin(USER_NAME_FIELD_DESC);
          oprot.writeString(struct.userName);
          oprot.writeFieldEnd();
        }
        oprot.writeFieldBegin(LIMIT_FIELD_DESC);
        oprot.writeI32(struct.limit);
        oprot.writeFieldEnd();
        oprot.writeFieldBegin(OFFSET_FIELD_DESC);
        oprot.writeI32(struct.offset);
        oprot.writeFieldEnd();
        oprot.writeFieldStop();
        oprot.writeStructEnd();
      }

    }

    private static class getUserProjects_argsTupleSchemeFactory implements SchemeFactory {
      public getUserProjects_argsTupleScheme getScheme() {
        return new getUserProjects_argsTupleScheme();
      }
    }

    private static class getUserProjects_argsTupleScheme extends TupleScheme<getUserProjects_args> {

      @Override
      public void write(org.apache.thrift.protocol.TProtocol prot, getUserProjects_args struct) throws org.apache.thrift.TException {
        TTupleProtocol oprot = (TTupleProtocol) prot;
        struct.authzToken.write(oprot);
        oprot.writeString(struct.gatewayId);
        oprot.writeString(struct.userName);
        oprot.writeI32(struct.limit);
        oprot.writeI32(struct.offset);
      }

      @Override
      public void read(org.apache.thrift.protocol.TProtocol prot, getUserProjects_args struct) throws org.apache.thrift.TException {
        TTupleProtocol iprot = (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);
        struct.userName = iprot.readString();
        struct.setUserNameIsSet(true);
        struct.limit = iprot.readI32();
        struct.setLimitIsSet(true);
        struct.offset = iprot.readI32();
        struct.setOffsetIsSet(true);
      }
    }

  }

  public static class getUserProjects_result implements org.apache.thrift.TBase<getUserProjects_result, getUserProjects_result._Fields>, java.io.Serializable, Cloneable, Comparable<getUserProjects_result>   {
    private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("getUserProjects_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 IRE_FIELD_DESC = new org.apache.thrift.protocol.TField("ire", org.apache.thrift.protocol.TType.STRUCT, (short)1);
    private static final org.apache.thrift.protocol.TField ACE_FIELD_DESC = new org.apache.thrift.protocol.TField("ace", org.apache.thrift.protocol.TType.STRUCT, (short)2);
    private static final org.apache.thrift.protocol.TField ASE_FIELD_DESC = new org.apache.thrift.protocol.TField("ase", org.apache.thrift.protocol.TType.STRUCT, (short)3);
    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)4);

    private static final Map<Class<? extends IScheme>, SchemeFactory> schemes = new HashMap<Class<? extends IScheme>, SchemeFactory>();
    static {
      schemes.put(StandardScheme.class, new getUserProjects_resultStandardSchemeFactory());
      schemes.put(TupleScheme.class, new getUserProjects_resultTupleSchemeFactory());
    }

    public List<org.apache.airavata.model.workspace.Project> success; // required
    public org.apache.airavata.model.error.InvalidRequestException ire; // required
    public org.apache.airavata.model.error.AiravataClientException ace; // required
    public org.apache.airavata.model.error.AiravataSystemException ase; // 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"),
      IRE((short)1, "ire"),
      ACE((short)2, "ace"),
      ASE((short)3, "ase"),
      AE((short)4, "ae");

      private static final Map<String, _Fields> byName = new HashMap<String, _Fields>();

      static {
        for (_Fields field : EnumSet.allOf(_Fields.class)) {
          byName.put(field.getFieldName(), field);
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, or null if its not found.
       */
      public static _Fields findByThriftId(int fieldId) {
        switch(fieldId) {
          case 0: // SUCCESS
            return SUCCESS;
          case 1: // IRE
            return IRE;
          case 2: // ACE
            return ACE;
          case 3: // ASE
            return ASE;
          case 4: // 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 IllegalArgumentException("Field " + fieldId + " doesn't exist!");
        return fields;
      }

      /**
       * Find the _Fields constant that matches name, or null if its not found.
       */
      public static _Fields findByName(String name) {
        return byName.get(name);
      }

      private final short _thriftId;
      private final String _fieldName;

      _Fields(short thriftId, String fieldName) {
        _thriftId = thriftId;
        _fieldName = fieldName;
      }

      public short getThriftFieldId() {
        return _thriftId;
      }

      public String getFieldName() {
        return _fieldName;
      }
    }

    // isset id assignments
    public static final Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
    static {
      Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new EnumMap<_Fields, org.apache.thrift.meta_data.FieldMetaData>(_Fields.class);
      tmpMap.put(_Fields.SUCCESS, new org.apache.thrift.meta_data.FieldMetaData("success", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.ListMetaData(org.apache.thrift.protocol.TType.LIST, 
              new org.apache.thrift.meta_data.StructMetaData(org.apache.thrift.protocol.TType.STRUCT, org.apache.airavata.model.workspace.Project.class))));
      tmpMap.put(_Fields.IRE, new org.apache.thrift.meta_data.FieldMetaData("ire", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRUCT)));
      tmpMap.put(_Fields.ACE, new org.apache.thrift.meta_data.FieldMetaData("ace", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRUCT)));
      tmpMap.put(_Fields.ASE, new org.apache.thrift.meta_data.FieldMetaData("ase", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRUCT)));
      tmpMap.put(_Fields.AE, new org.apache.thrift.meta_data.FieldMetaData("ae", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRUCT)));
      metaDataMap = Collections.unmodifiableMap(tmpMap);
      org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(getUserProjects_result.class, metaDataMap);
    }

    public getUserProjects_result() {
    }

    public getUserProjects_result(
      List<org.apache.airavata.model.workspace.Project> success,
      org.apache.airavata.model.error.InvalidRequestException ire,
      org.apache.airavata.model.error.AiravataClientException ace,
      org.apache.airavata.model.error.AiravataSystemException ase,
      org.apache.airavata.model.error.AuthorizationException ae)
    {
      this();
      this.success = success;
      this.ire = ire;
      this.ace = ace;
      this.ase = ase;
      this.ae = ae;
    }

    /**
     * Performs a deep copy on <i>other</i>.
     */
    public getUserProjects_result(getUserProjects_result other) {
      if (other.isSetSuccess()) {
        List<org.apache.airavata.model.workspace.Project> __this__success = new ArrayList<org.apache.airavata.model.workspace.Project>(other.success.size());
        for (org.apache.airavata.model.workspace.Project other_element : other.success) {
          __this__success.add(new org.apache.airavata.model.workspace.Project(other_element));
        }
        this.success = __this__success;
      }
      if (other.isSetIre()) {
        this.ire = new org.apache.airavata.model.error.InvalidRequestException(other.ire);
      }
      if (other.isSetAce()) {
        this.ace = new org.apache.airavata.model.error.AiravataClientException(other.ace);
      }
      if (other.isSetAse()) {
        this.ase = new org.apache.airavata.model.error.AiravataSystemException(other.ase);
      }
      if (other.isSetAe()) {
        this.ae = new org.apache.airavata.model.error.AuthorizationException(other.ae);
      }
    }

    public getUserProjects_result deepCopy() {
      return new getUserProjects_result(this);
    }

    @Override
    public void clear() {
      this.success = null;
      this.ire = null;
      this.ace = null;
      this.ase = null;
      this.ae = null;
    }

    public int getSuccessSize() {
      return (this.success == null) ? 0 : this.success.size();
    }

    public java.util.Iterator<org.apache.airavata.model.workspace.Project> getSuccessIterator() {
      return (this.success == null) ? null : this.success.iterator();
    }

    public void addToSuccess(org.apache.airavata.model.workspace.Project elem) {
      if (this.success == null) {
        this.success = new ArrayList<org.apache.airavata.model.workspace.Project>();
      }
      this.success.add(elem);
    }

    public List<org.apache.airavata.model.workspace.Project> getSuccess() {
      return this.success;
    }

    public getUserProjects_result setSuccess(List<org.apache.airavata.model.workspace.Project> 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.model.error.InvalidRequestException getIre() {
      return this.ire;
    }

    public getUserProjects_result setIre(org.apache.airavata.model.error.InvalidRequestException ire) {
      this.ire = ire;
      return this;
    }

    public void unsetIre() {
      this.ire = null;
    }

    /** Returns true if field ire is set (has been assigned a value) and false otherwise */
    public boolean isSetIre() {
      return this.ire != null;
    }

    public void setIreIsSet(boolean value) {
      if (!value) {
        this.ire = null;
      }
    }

    public org.apache.airavata.model.error.AiravataClientException getAce() {
      return this.ace;
    }

    public getUserProjects_result setAce(org.apache.airavata.model.error.AiravataClientException ace) {
      this.ace = ace;
      return this;
    }

    public void unsetAce() {
      this.ace = null;
    }

    /** Returns true if field ace is set (has been assigned a value) and false otherwise */
    public boolean isSetAce() {
      return this.ace != null;
    }

    public void setAceIsSet(boolean value) {
      if (!value) {
        this.ace = null;
      }
    }

    public org.apache.airavata.model.error.AiravataSystemException getAse() {
      return this.ase;
    }

    public getUserProjects_result setAse(org.apache.airavata.model.error.AiravataSystemException ase) {
      this.ase = ase;
      return this;
    }

    public void unsetAse() {
      this.ase = null;
    }

    /** Returns true if field ase is set (has been assigned a value) and false otherwise */
    public boolean isSetAse() {
      return this.ase != null;
    }

    public void setAseIsSet(boolean value) {
      if (!value) {
        this.ase = null;
      }
    }

    public org.apache.airavata.model.error.AuthorizationException getAe() {
      return this.ae;
    }

    public getUserProjects_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, Object value) {
      switch (field) {
      case SUCCESS:
        if (value == null) {
          unsetSuccess();
        } else {
          setSuccess((List<org.apache.airavata.model.workspace.Project>)value);
        }
        break;

      case IRE:
        if (value == null) {
          unsetIre();
        } else {
          setIre((org.apache.airavata.model.error.InvalidRequestException)value);
        }
        break;

      case ACE:
        if (value == null) {
          unsetAce();
        } else {
          setAce((org.apache.airavata.model.error.AiravataClientException)value);
        }
        break;

      case ASE:
        if (value == null) {
          unsetAse();
        } else {
          setAse((org.apache.airavata.model.error.AiravataSystemException)value);
        }
        break;

      case AE:
        if (value == null) {
          unsetAe();
        } else {
          setAe((org.apache.airavata.model.error.AuthorizationException)value);
        }
        break;

      }
    }

    public Object getFieldValue(_Fields field) {
      switch (field) {
      case SUCCESS:
        return getSuccess();

      case IRE:
        return getIre();

      case ACE:
        return getAce();

      case ASE:
        return getAse();

      case AE:
        return getAe();

      }
      throw new IllegalStateException();
    }

    /** Returns true if field corresponding to fieldID is set (has been assigned a value) and false otherwise */
    public boolean isSet(_Fields field) {
      if (field == null) {
        throw new IllegalArgumentException();
      }

      switch (field) {
      case SUCCESS:
        return isSetSuccess();
      case IRE:
        return isSetIre();
      case ACE:
        return isSetAce();
      case ASE:
        return isSetAse();
      case AE:
        return isSetAe();
      }
      throw new IllegalStateException();
    }

    @Override
    public boolean equals(Object that) {
      if (that == null)
        return false;
      if (that instanceof getUserProjects_result)
        return this.equals((getUserProjects_result)that);
      return false;
    }

    public boolean equals(getUserProjects_result that) {
      if (that == null)
        return false;

      boolean this_present_success = true && this.isSetSuccess();
      boolean that_present_success = true && that.isSetSuccess();
      if (this_present_success || that_present_success) {
        if (!(this_present_success && that_present_success))
          return false;
        if (!this.success.equals(that.success))
          return false;
      }

      boolean this_present_ire = true && this.isSetIre();
      boolean that_present_ire = true && that.isSetIre();
      if (this_present_ire || that_present_ire) {
        if (!(this_present_ire && that_present_ire))
          return false;
        if (!this.ire.equals(that.ire))
          return false;
      }

      boolean this_present_ace = true && this.isSetAce();
      boolean that_present_ace = true && that.isSetAce();
      if (this_present_ace || that_present_ace) {
        if (!(this_present_ace && that_present_ace))
          return false;
        if (!this.ace.equals(that.ace))
          return false;
      }

      boolean this_present_ase = true && this.isSetAse();
      boolean that_present_ase = true && that.isSetAse();
      if (this_present_ase || that_present_ase) {
        if (!(this_present_ase && that_present_ase))
          return false;
        if (!this.ase.equals(that.ase))
          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() {
      List<Object> list = new ArrayList<Object>();

      boolean present_success = true && (isSetSuccess());
      list.add(present_success);
      if (present_success)
        list.add(success);

      boolean present_ire = true && (isSetIre());
      list.add(present_ire);
      if (present_ire)
        list.add(ire);

      boolean present_ace = true && (isSetAce());
      list.add(present_ace);
      if (present_ace)
        list.add(ace);

      boolean present_ase = true && (isSetAse());
      list.add(present_ase);
      if (present_ase)
        list.add(ase);

      boolean present_ae = true && (isSetAe());
      list.add(present_ae);
      if (present_ae)
        list.add(ae);

      return list.hashCode();
    }

    @Override
    public int compareTo(getUserProjects_result other) {
      if (!getClass().equals(other.getClass())) {
        return getClass().getName().compareTo(other.getClass().getName());
      }

      int lastComparison = 0;

      lastComparison = Boolean.valueOf(isSetSuccess()).compareTo(other.isSetSuccess());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetSuccess()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.success, other.success);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = Boolean.valueOf(isSetIre()).compareTo(other.isSetIre());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetIre()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.ire, other.ire);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = Boolean.valueOf(isSetAce()).compareTo(other.isSetAce());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetAce()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.ace, other.ace);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = Boolean.valueOf(isSetAse()).compareTo(other.isSetAse());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetAse()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.ase, other.ase);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = 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 {
      schemes.get(iprot.getScheme()).getScheme().read(iprot, this);
    }

    public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException {
      schemes.get(oprot.getScheme()).getScheme().write(oprot, this);
      }

    @Override
    public String toString() {
      StringBuilder sb = new StringBuilder("getUserProjects_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("ire:");
      if (this.ire == null) {
        sb.append("null");
      } else {
        sb.append(this.ire);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("ace:");
      if (this.ace == null) {
        sb.append("null");
      } else {
        sb.append(this.ace);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("ase:");
      if (this.ase == null) {
        sb.append("null");
      } else {
        sb.append(this.ase);
      }
      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, 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 getUserProjects_resultStandardSchemeFactory implements SchemeFactory {
      public getUserProjects_resultStandardScheme getScheme() {
        return new getUserProjects_resultStandardScheme();
      }
    }

    private static class getUserProjects_resultStandardScheme extends StandardScheme<getUserProjects_result> {

      public void read(org.apache.thrift.protocol.TProtocol iprot, getUserProjects_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 _list18 = iprot.readListBegin();
                  struct.success = new ArrayList<org.apache.airavata.model.workspace.Project>(_list18.size);
                  org.apache.airavata.model.workspace.Project _elem19;
                  for (int _i20 = 0; _i20 < _list18.size; ++_i20)
                  {
                    _elem19 = new org.apache.airavata.model.workspace.Project();
                    _elem19.read(iprot);
                    struct.success.add(_elem19);
                  }
                  iprot.readListEnd();
                }
                struct.setSuccessIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 1: // IRE
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.ire = new org.apache.airavata.model.error.InvalidRequestException();
                struct.ire.read(iprot);
                struct.setIreIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 2: // ACE
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.ace = new org.apache.airavata.model.error.AiravataClientException();
                struct.ace.read(iprot);
                struct.setAceIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 3: // ASE
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.ase = new org.apache.airavata.model.error.AiravataSystemException();
                struct.ase.read(iprot);
                struct.setAseIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 4: // 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, getUserProjects_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.Project _iter21 : struct.success)
            {
              _iter21.write(oprot);
            }
            oprot.writeListEnd();
          }
          oprot.writeFieldEnd();
        }
        if (struct.ire != null) {
          oprot.writeFieldBegin(IRE_FIELD_DESC);
          struct.ire.write(oprot);
          oprot.writeFieldEnd();
        }
        if (struct.ace != null) {
          oprot.writeFieldBegin(ACE_FIELD_DESC);
          struct.ace.write(oprot);
          oprot.writeFieldEnd();
        }
        if (struct.ase != null) {
          oprot.writeFieldBegin(ASE_FIELD_DESC);
          struct.ase.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 getUserProjects_resultTupleSchemeFactory implements SchemeFactory {
      public getUserProjects_resultTupleScheme getScheme() {
        return new getUserProjects_resultTupleScheme();
      }
    }

    private static class getUserProjects_resultTupleScheme extends TupleScheme<getUserProjects_result> {

      @Override
      public void write(org.apache.thrift.protocol.TProtocol prot, getUserProjects_result struct) throws org.apache.thrift.TException {
        TTupleProtocol oprot = (TTupleProtocol) prot;
        BitSet optionals = new BitSet();
        if (struct.isSetSuccess()) {
          optionals.set(0);
        }
        if (struct.isSetIre()) {
          optionals.set(1);
        }
        if (struct.isSetAce()) {
          optionals.set(2);
        }
        if (struct.isSetAse()) {
          optionals.set(3);
        }
        if (struct.isSetAe()) {
          optionals.set(4);
        }
        oprot.writeBitSet(optionals, 5);
        if (struct.isSetSuccess()) {
          {
            oprot.writeI32(struct.success.size());
            for (org.apache.airavata.model.workspace.Project _iter22 : struct.success)
            {
              _iter22.write(oprot);
            }
          }
        }
        if (struct.isSetIre()) {
          struct.ire.write(oprot);
        }
        if (struct.isSetAce()) {
          struct.ace.write(oprot);
        }
        if (struct.isSetAse()) {
          struct.ase.write(oprot);
        }
        if (struct.isSetAe()) {
          struct.ae.write(oprot);
        }
      }

      @Override
      public void read(org.apache.thrift.protocol.TProtocol prot, getUserProjects_result struct) throws org.apache.thrift.TException {
        TTupleProtocol iprot = (TTupleProtocol) prot;
        BitSet incoming = iprot.readBitSet(5);
        if (incoming.get(0)) {
          {
            org.apache.thrift.protocol.TList _list23 = new org.apache.thrift.protocol.TList(org.apache.thrift.protocol.TType.STRUCT, iprot.readI32());
            struct.success = new ArrayList<org.apache.airavata.model.workspace.Project>(_list23.size);
            org.apache.airavata.model.workspace.Project _elem24;
            for (int _i25 = 0; _i25 < _list23.size; ++_i25)
            {
              _elem24 = new org.apache.airavata.model.workspace.Project();
              _elem24.read(iprot);
              struct.success.add(_elem24);
            }
          }
          struct.setSuccessIsSet(true);
        }
        if (incoming.get(1)) {
          struct.ire = new org.apache.airavata.model.error.InvalidRequestException();
          struct.ire.read(iprot);
          struct.setIreIsSet(true);
        }
        if (incoming.get(2)) {
          struct.ace = new org.apache.airavata.model.error.AiravataClientException();
          struct.ace.read(iprot);
          struct.setAceIsSet(true);
        }
        if (incoming.get(3)) {
          struct.ase = new org.apache.airavata.model.error.AiravataSystemException();
          struct.ase.read(iprot);
          struct.setAseIsSet(true);
        }
        if (incoming.get(4)) {
          struct.ae = new org.apache.airavata.model.error.AuthorizationException();
          struct.ae.read(iprot);
          struct.setAeIsSet(true);
        }
      }
    }

  }

  public static class searchProjectsByProjectName_args implements org.apache.thrift.TBase<searchProjectsByProjectName_args, searchProjectsByProjectName_args._Fields>, java.io.Serializable, Cloneable, Comparable<searchProjectsByProjectName_args>   {
    private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("searchProjectsByProjectName_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.protocol.TField USER_NAME_FIELD_DESC = new org.apache.thrift.protocol.TField("userName", org.apache.thrift.protocol.TType.STRING, (short)3);
    private static final org.apache.thrift.protocol.TField PROJECT_NAME_FIELD_DESC = new org.apache.thrift.protocol.TField("projectName", org.apache.thrift.protocol.TType.STRING, (short)4);
    private static final org.apache.thrift.protocol.TField LIMIT_FIELD_DESC = new org.apache.thrift.protocol.TField("limit", org.apache.thrift.protocol.TType.I32, (short)5);
    private static final org.apache.thrift.protocol.TField OFFSET_FIELD_DESC = new org.apache.thrift.protocol.TField("offset", org.apache.thrift.protocol.TType.I32, (short)6);

    private static final Map<Class<? extends IScheme>, SchemeFactory> schemes = new HashMap<Class<? extends IScheme>, SchemeFactory>();
    static {
      schemes.put(StandardScheme.class, new searchProjectsByProjectName_argsStandardSchemeFactory());
      schemes.put(TupleScheme.class, new searchProjectsByProjectName_argsTupleSchemeFactory());
    }

    public org.apache.airavata.model.security.AuthzToken authzToken; // required
    public String gatewayId; // required
    public String userName; // required
    public String projectName; // required
    public int limit; // required
    public int offset; // required

    /** 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"),
      USER_NAME((short)3, "userName"),
      PROJECT_NAME((short)4, "projectName"),
      LIMIT((short)5, "limit"),
      OFFSET((short)6, "offset");

      private static final Map<String, _Fields> byName = new HashMap<String, _Fields>();

      static {
        for (_Fields field : EnumSet.allOf(_Fields.class)) {
          byName.put(field.getFieldName(), field);
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, or null if its not found.
       */
      public static _Fields findByThriftId(int fieldId) {
        switch(fieldId) {
          case 1: // AUTHZ_TOKEN
            return AUTHZ_TOKEN;
          case 2: // GATEWAY_ID
            return GATEWAY_ID;
          case 3: // USER_NAME
            return USER_NAME;
          case 4: // PROJECT_NAME
            return PROJECT_NAME;
          case 5: // LIMIT
            return LIMIT;
          case 6: // OFFSET
            return OFFSET;
          default:
            return null;
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, throwing an exception
       * if it is not found.
       */
      public static _Fields findByThriftIdOrThrow(int fieldId) {
        _Fields fields = findByThriftId(fieldId);
        if (fields == null) throw new IllegalArgumentException("Field " + fieldId + " doesn't exist!");
        return fields;
      }

      /**
       * Find the _Fields constant that matches name, or null if its not found.
       */
      public static _Fields findByName(String name) {
        return byName.get(name);
      }

      private final short _thriftId;
      private final String _fieldName;

      _Fields(short thriftId, String fieldName) {
        _thriftId = thriftId;
        _fieldName = fieldName;
      }

      public short getThriftFieldId() {
        return _thriftId;
      }

      public String getFieldName() {
        return _fieldName;
      }
    }

    // isset id assignments
    private static final int __LIMIT_ISSET_ID = 0;
    private static final int __OFFSET_ISSET_ID = 1;
    private byte __isset_bitfield = 0;
    public static final Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
    static {
      Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new EnumMap<_Fields, org.apache.thrift.meta_data.FieldMetaData>(_Fields.class);
      tmpMap.put(_Fields.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)));
      tmpMap.put(_Fields.USER_NAME, new org.apache.thrift.meta_data.FieldMetaData("userName", org.apache.thrift.TFieldRequirementType.REQUIRED, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING)));
      tmpMap.put(_Fields.PROJECT_NAME, new org.apache.thrift.meta_data.FieldMetaData("projectName", org.apache.thrift.TFieldRequirementType.REQUIRED, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING)));
      tmpMap.put(_Fields.LIMIT, new org.apache.thrift.meta_data.FieldMetaData("limit", org.apache.thrift.TFieldRequirementType.REQUIRED, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.I32)));
      tmpMap.put(_Fields.OFFSET, new org.apache.thrift.meta_data.FieldMetaData("offset", org.apache.thrift.TFieldRequirementType.REQUIRED, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.I32)));
      metaDataMap = Collections.unmodifiableMap(tmpMap);
      org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(searchProjectsByProjectName_args.class, metaDataMap);
    }

    public searchProjectsByProjectName_args() {
    }

    public searchProjectsByProjectName_args(
      org.apache.airavata.model.security.AuthzToken authzToken,
      String gatewayId,
      String userName,
      String projectName,
      int limit,
      int offset)
    {
      this();
      this.authzToken = authzToken;
      this.gatewayId = gatewayId;
      this.userName = userName;
      this.projectName = projectName;
      this.limit = limit;
      setLimitIsSet(true);
      this.offset = offset;
      setOffsetIsSet(true);
    }

    /**
     * Performs a deep copy on <i>other</i>.
     */
    public searchProjectsByProjectName_args(searchProjectsByProjectName_args other) {
      __isset_bitfield = other.__isset_bitfield;
      if (other.isSetAuthzToken()) {
        this.authzToken = new org.apache.airavata.model.security.AuthzToken(other.authzToken);
      }
      if (other.isSetGatewayId()) {
        this.gatewayId = other.gatewayId;
      }
      if (other.isSetUserName()) {
        this.userName = other.userName;
      }
      if (other.isSetProjectName()) {
        this.projectName = other.projectName;
      }
      this.limit = other.limit;
      this.offset = other.offset;
    }

    public searchProjectsByProjectName_args deepCopy() {
      return new searchProjectsByProjectName_args(this);
    }

    @Override
    public void clear() {
      this.authzToken = null;
      this.gatewayId = null;
      this.userName = null;
      this.projectName = null;
      setLimitIsSet(false);
      this.limit = 0;
      setOffsetIsSet(false);
      this.offset = 0;
    }

    public org.apache.airavata.model.security.AuthzToken getAuthzToken() {
      return this.authzToken;
    }

    public searchProjectsByProjectName_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 String getGatewayId() {
      return this.gatewayId;
    }

    public searchProjectsByProjectName_args setGatewayId(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 String getUserName() {
      return this.userName;
    }

    public searchProjectsByProjectName_args setUserName(String userName) {
      this.userName = userName;
      return this;
    }

    public void unsetUserName() {
      this.userName = null;
    }

    /** Returns true if field userName is set (has been assigned a value) and false otherwise */
    public boolean isSetUserName() {
      return this.userName != null;
    }

    public void setUserNameIsSet(boolean value) {
      if (!value) {
        this.userName = null;
      }
    }

    public String getProjectName() {
      return this.projectName;
    }

    public searchProjectsByProjectName_args setProjectName(String projectName) {
      this.projectName = projectName;
      return this;
    }

    public void unsetProjectName() {
      this.projectName = null;
    }

    /** Returns true if field projectName is set (has been assigned a value) and false otherwise */
    public boolean isSetProjectName() {
      return this.projectName != null;
    }

    public void setProjectNameIsSet(boolean value) {
      if (!value) {
        this.projectName = null;
      }
    }

    public int getLimit() {
      return this.limit;
    }

    public searchProjectsByProjectName_args setLimit(int limit) {
      this.limit = limit;
      setLimitIsSet(true);
      return this;
    }

    public void unsetLimit() {
      __isset_bitfield = EncodingUtils.clearBit(__isset_bitfield, __LIMIT_ISSET_ID);
    }

    /** Returns true if field limit is set (has been assigned a value) and false otherwise */
    public boolean isSetLimit() {
      return EncodingUtils.testBit(__isset_bitfield, __LIMIT_ISSET_ID);
    }

    public void setLimitIsSet(boolean value) {
      __isset_bitfield = EncodingUtils.setBit(__isset_bitfield, __LIMIT_ISSET_ID, value);
    }

    public int getOffset() {
      return this.offset;
    }

    public searchProjectsByProjectName_args setOffset(int offset) {
      this.offset = offset;
      setOffsetIsSet(true);
      return this;
    }

    public void unsetOffset() {
      __isset_bitfield = EncodingUtils.clearBit(__isset_bitfield, __OFFSET_ISSET_ID);
    }

    /** Returns true if field offset is set (has been assigned a value) and false otherwise */
    public boolean isSetOffset() {
      return EncodingUtils.testBit(__isset_bitfield, __OFFSET_ISSET_ID);
    }

    public void setOffsetIsSet(boolean value) {
      __isset_bitfield = EncodingUtils.setBit(__isset_bitfield, __OFFSET_ISSET_ID, value);
    }

    public void setFieldValue(_Fields field, 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((String)value);
        }
        break;

      case USER_NAME:
        if (value == null) {
          unsetUserName();
        } else {
          setUserName((String)value);
        }
        break;

      case PROJECT_NAME:
        if (value == null) {
          unsetProjectName();
        } else {
          setProjectName((String)value);
        }
        break;

      case LIMIT:
        if (value == null) {
          unsetLimit();
        } else {
          setLimit((Integer)value);
        }
        break;

      case OFFSET:
        if (value == null) {
          unsetOffset();
        } else {
          setOffset((Integer)value);
        }
        break;

      }
    }

    public Object getFieldValue(_Fields field) {
      switch (field) {
      case AUTHZ_TOKEN:
        return getAuthzToken();

      case GATEWAY_ID:
        return getGatewayId();

      case USER_NAME:
        return getUserName();

      case PROJECT_NAME:
        return getProjectName();

      case LIMIT:
        return Integer.valueOf(getLimit());

      case OFFSET:
        return Integer.valueOf(getOffset());

      }
      throw new IllegalStateException();
    }

    /** Returns true if field corresponding to fieldID is set (has been assigned a value) and false otherwise */
    public boolean isSet(_Fields field) {
      if (field == null) {
        throw new IllegalArgumentException();
      }

      switch (field) {
      case AUTHZ_TOKEN:
        return isSetAuthzToken();
      case GATEWAY_ID:
        return isSetGatewayId();
      case USER_NAME:
        return isSetUserName();
      case PROJECT_NAME:
        return isSetProjectName();
      case LIMIT:
        return isSetLimit();
      case OFFSET:
        return isSetOffset();
      }
      throw new IllegalStateException();
    }

    @Override
    public boolean equals(Object that) {
      if (that == null)
        return false;
      if (that instanceof searchProjectsByProjectName_args)
        return this.equals((searchProjectsByProjectName_args)that);
      return false;
    }

    public boolean equals(searchProjectsByProjectName_args that) {
      if (that == null)
        return false;

      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;
      }

      boolean this_present_userName = true && this.isSetUserName();
      boolean that_present_userName = true && that.isSetUserName();
      if (this_present_userName || that_present_userName) {
        if (!(this_present_userName && that_present_userName))
          return false;
        if (!this.userName.equals(that.userName))
          return false;
      }

      boolean this_present_projectName = true && this.isSetProjectName();
      boolean that_present_projectName = true && that.isSetProjectName();
      if (this_present_projectName || that_present_projectName) {
        if (!(this_present_projectName && that_present_projectName))
          return false;
        if (!this.projectName.equals(that.projectName))
          return false;
      }

      boolean this_present_limit = true;
      boolean that_present_limit = true;
      if (this_present_limit || that_present_limit) {
        if (!(this_present_limit && that_present_limit))
          return false;
        if (this.limit != that.limit)
          return false;
      }

      boolean this_present_offset = true;
      boolean that_present_offset = true;
      if (this_present_offset || that_present_offset) {
        if (!(this_present_offset && that_present_offset))
          return false;
        if (this.offset != that.offset)
          return false;
      }

      return true;
    }

    @Override
    public int hashCode() {
      List<Object> list = new ArrayList<Object>();

      boolean present_authzToken = true && (isSetAuthzToken());
      list.add(present_authzToken);
      if (present_authzToken)
        list.add(authzToken);

      boolean present_gatewayId = true && (isSetGatewayId());
      list.add(present_gatewayId);
      if (present_gatewayId)
        list.add(gatewayId);

      boolean present_userName = true && (isSetUserName());
      list.add(present_userName);
      if (present_userName)
        list.add(userName);

      boolean present_projectName = true && (isSetProjectName());
      list.add(present_projectName);
      if (present_projectName)
        list.add(projectName);

      boolean present_limit = true;
      list.add(present_limit);
      if (present_limit)
        list.add(limit);

      boolean present_offset = true;
      list.add(present_offset);
      if (present_offset)
        list.add(offset);

      return list.hashCode();
    }

    @Override
    public int compareTo(searchProjectsByProjectName_args other) {
      if (!getClass().equals(other.getClass())) {
        return getClass().getName().compareTo(other.getClass().getName());
      }

      int lastComparison = 0;

      lastComparison = 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 = 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;
        }
      }
      lastComparison = Boolean.valueOf(isSetUserName()).compareTo(other.isSetUserName());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetUserName()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.userName, other.userName);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = Boolean.valueOf(isSetProjectName()).compareTo(other.isSetProjectName());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetProjectName()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.projectName, other.projectName);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = Boolean.valueOf(isSetLimit()).compareTo(other.isSetLimit());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetLimit()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.limit, other.limit);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = Boolean.valueOf(isSetOffset()).compareTo(other.isSetOffset());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetOffset()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.offset, other.offset);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      return 0;
    }

    public _Fields fieldForId(int fieldId) {
      return _Fields.findByThriftId(fieldId);
    }

    public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
      schemes.get(iprot.getScheme()).getScheme().read(iprot, this);
    }

    public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException {
      schemes.get(oprot.getScheme()).getScheme().write(oprot, this);
    }

    @Override
    public String toString() {
      StringBuilder sb = new StringBuilder("searchProjectsByProjectName_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;
      if (!first) sb.append(", ");
      sb.append("userName:");
      if (this.userName == null) {
        sb.append("null");
      } else {
        sb.append(this.userName);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("projectName:");
      if (this.projectName == null) {
        sb.append("null");
      } else {
        sb.append(this.projectName);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("limit:");
      sb.append(this.limit);
      first = false;
      if (!first) sb.append(", ");
      sb.append("offset:");
      sb.append(this.offset);
      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());
      }
      if (userName == null) {
        throw new org.apache.thrift.protocol.TProtocolException("Required field 'userName' was not present! Struct: " + toString());
      }
      if (projectName == null) {
        throw new org.apache.thrift.protocol.TProtocolException("Required field 'projectName' was not present! Struct: " + toString());
      }
      // alas, we cannot check 'limit' because it's a primitive and you chose the non-beans generator.
      // alas, we cannot check 'offset' because it's a primitive and you chose the non-beans generator.
      // 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, 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 searchProjectsByProjectName_argsStandardSchemeFactory implements SchemeFactory {
      public searchProjectsByProjectName_argsStandardScheme getScheme() {
        return new searchProjectsByProjectName_argsStandardScheme();
      }
    }

    private static class searchProjectsByProjectName_argsStandardScheme extends StandardScheme<searchProjectsByProjectName_args> {

      public void read(org.apache.thrift.protocol.TProtocol iprot, searchProjectsByProjectName_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;
            case 3: // USER_NAME
              if (schemeField.type == org.apache.thrift.protocol.TType.STRING) {
                struct.userName = iprot.readString();
                struct.setUserNameIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 4: // PROJECT_NAME
              if (schemeField.type == org.apache.thrift.protocol.TType.STRING) {
                struct.projectName = iprot.readString();
                struct.setProjectNameIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 5: // LIMIT
              if (schemeField.type == org.apache.thrift.protocol.TType.I32) {
                struct.limit = iprot.readI32();
                struct.setLimitIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 6: // OFFSET
              if (schemeField.type == org.apache.thrift.protocol.TType.I32) {
                struct.offset = iprot.readI32();
                struct.setOffsetIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            default:
              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
          }
          iprot.readFieldEnd();
        }
        iprot.readStructEnd();

        // check for required fields of primitive type, which can't be checked in the validate method
        if (!struct.isSetLimit()) {
          throw new org.apache.thrift.protocol.TProtocolException("Required field 'limit' was not found in serialized data! Struct: " + toString());
        }
        if (!struct.isSetOffset()) {
          throw new org.apache.thrift.protocol.TProtocolException("Required field 'offset' was not found in serialized data! Struct: " + toString());
        }
        struct.validate();
      }

      public void write(org.apache.thrift.protocol.TProtocol oprot, searchProjectsByProjectName_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();
        }
        if (struct.userName != null) {
          oprot.writeFieldBegin(USER_NAME_FIELD_DESC);
          oprot.writeString(struct.userName);
          oprot.writeFieldEnd();
        }
        if (struct.projectName != null) {
          oprot.writeFieldBegin(PROJECT_NAME_FIELD_DESC);
          oprot.writeString(struct.projectName);
          oprot.writeFieldEnd();
        }
        oprot.writeFieldBegin(LIMIT_FIELD_DESC);
        oprot.writeI32(struct.limit);
        oprot.writeFieldEnd();
        oprot.writeFieldBegin(OFFSET_FIELD_DESC);
        oprot.writeI32(struct.offset);
        oprot.writeFieldEnd();
        oprot.writeFieldStop();
        oprot.writeStructEnd();
      }

    }

    private static class searchProjectsByProjectName_argsTupleSchemeFactory implements SchemeFactory {
      public searchProjectsByProjectName_argsTupleScheme getScheme() {
        return new searchProjectsByProjectName_argsTupleScheme();
      }
    }

    private static class searchProjectsByProjectName_argsTupleScheme extends TupleScheme<searchProjectsByProjectName_args> {

      @Override
      public void write(org.apache.thrift.protocol.TProtocol prot, searchProjectsByProjectName_args struct) throws org.apache.thrift.TException {
        TTupleProtocol oprot = (TTupleProtocol) prot;
        struct.authzToken.write(oprot);
        oprot.writeString(struct.gatewayId);
        oprot.writeString(struct.userName);
        oprot.writeString(struct.projectName);
        oprot.writeI32(struct.limit);
        oprot.writeI32(struct.offset);
      }

      @Override
      public void read(org.apache.thrift.protocol.TProtocol prot, searchProjectsByProjectName_args struct) throws org.apache.thrift.TException {
        TTupleProtocol iprot = (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);
        struct.userName = iprot.readString();
        struct.setUserNameIsSet(true);
        struct.projectName = iprot.readString();
        struct.setProjectNameIsSet(true);
        struct.limit = iprot.readI32();
        struct.setLimitIsSet(true);
        struct.offset = iprot.readI32();
        struct.setOffsetIsSet(true);
      }
    }

  }

  public static class searchProjectsByProjectName_result implements org.apache.thrift.TBase<searchProjectsByProjectName_result, searchProjectsByProjectName_result._Fields>, java.io.Serializable, Cloneable, Comparable<searchProjectsByProjectName_result>   {
    private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("searchProjectsByProjectName_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 IRE_FIELD_DESC = new org.apache.thrift.protocol.TField("ire", org.apache.thrift.protocol.TType.STRUCT, (short)1);
    private static final org.apache.thrift.protocol.TField ACE_FIELD_DESC = new org.apache.thrift.protocol.TField("ace", org.apache.thrift.protocol.TType.STRUCT, (short)2);
    private static final org.apache.thrift.protocol.TField ASE_FIELD_DESC = new org.apache.thrift.protocol.TField("ase", org.apache.thrift.protocol.TType.STRUCT, (short)3);
    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)4);

    private static final Map<Class<? extends IScheme>, SchemeFactory> schemes = new HashMap<Class<? extends IScheme>, SchemeFactory>();
    static {
      schemes.put(StandardScheme.class, new searchProjectsByProjectName_resultStandardSchemeFactory());
      schemes.put(TupleScheme.class, new searchProjectsByProjectName_resultTupleSchemeFactory());
    }

    public List<org.apache.airavata.model.workspace.Project> success; // required
    public org.apache.airavata.model.error.InvalidRequestException ire; // required
    public org.apache.airavata.model.error.AiravataClientException ace; // required
    public org.apache.airavata.model.error.AiravataSystemException ase; // 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"),
      IRE((short)1, "ire"),
      ACE((short)2, "ace"),
      ASE((short)3, "ase"),
      AE((short)4, "ae");

      private static final Map<String, _Fields> byName = new HashMap<String, _Fields>();

      static {
        for (_Fields field : EnumSet.allOf(_Fields.class)) {
          byName.put(field.getFieldName(), field);
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, or null if its not found.
       */
      public static _Fields findByThriftId(int fieldId) {
        switch(fieldId) {
          case 0: // SUCCESS
            return SUCCESS;
          case 1: // IRE
            return IRE;
          case 2: // ACE
            return ACE;
          case 3: // ASE
            return ASE;
          case 4: // 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 IllegalArgumentException("Field " + fieldId + " doesn't exist!");
        return fields;
      }

      /**
       * Find the _Fields constant that matches name, or null if its not found.
       */
      public static _Fields findByName(String name) {
        return byName.get(name);
      }

      private final short _thriftId;
      private final String _fieldName;

      _Fields(short thriftId, String fieldName) {
        _thriftId = thriftId;
        _fieldName = fieldName;
      }

      public short getThriftFieldId() {
        return _thriftId;
      }

      public String getFieldName() {
        return _fieldName;
      }
    }

    // isset id assignments
    public static final Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
    static {
      Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new EnumMap<_Fields, org.apache.thrift.meta_data.FieldMetaData>(_Fields.class);
      tmpMap.put(_Fields.SUCCESS, new org.apache.thrift.meta_data.FieldMetaData("success", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.ListMetaData(org.apache.thrift.protocol.TType.LIST, 
              new org.apache.thrift.meta_data.StructMetaData(org.apache.thrift.protocol.TType.STRUCT, org.apache.airavata.model.workspace.Project.class))));
      tmpMap.put(_Fields.IRE, new org.apache.thrift.meta_data.FieldMetaData("ire", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRUCT)));
      tmpMap.put(_Fields.ACE, new org.apache.thrift.meta_data.FieldMetaData("ace", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRUCT)));
      tmpMap.put(_Fields.ASE, new org.apache.thrift.meta_data.FieldMetaData("ase", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRUCT)));
      tmpMap.put(_Fields.AE, new org.apache.thrift.meta_data.FieldMetaData("ae", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRUCT)));
      metaDataMap = Collections.unmodifiableMap(tmpMap);
      org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(searchProjectsByProjectName_result.class, metaDataMap);
    }

    public searchProjectsByProjectName_result() {
    }

    public searchProjectsByProjectName_result(
      List<org.apache.airavata.model.workspace.Project> success,
      org.apache.airavata.model.error.InvalidRequestException ire,
      org.apache.airavata.model.error.AiravataClientException ace,
      org.apache.airavata.model.error.AiravataSystemException ase,
      org.apache.airavata.model.error.AuthorizationException ae)
    {
      this();
      this.success = success;
      this.ire = ire;
      this.ace = ace;
      this.ase = ase;
      this.ae = ae;
    }

    /**
     * Performs a deep copy on <i>other</i>.
     */
    public searchProjectsByProjectName_result(searchProjectsByProjectName_result other) {
      if (other.isSetSuccess()) {
        List<org.apache.airavata.model.workspace.Project> __this__success = new ArrayList<org.apache.airavata.model.workspace.Project>(other.success.size());
        for (org.apache.airavata.model.workspace.Project other_element : other.success) {
          __this__success.add(new org.apache.airavata.model.workspace.Project(other_element));
        }
        this.success = __this__success;
      }
      if (other.isSetIre()) {
        this.ire = new org.apache.airavata.model.error.InvalidRequestException(other.ire);
      }
      if (other.isSetAce()) {
        this.ace = new org.apache.airavata.model.error.AiravataClientException(other.ace);
      }
      if (other.isSetAse()) {
        this.ase = new org.apache.airavata.model.error.AiravataSystemException(other.ase);
      }
      if (other.isSetAe()) {
        this.ae = new org.apache.airavata.model.error.AuthorizationException(other.ae);
      }
    }

    public searchProjectsByProjectName_result deepCopy() {
      return new searchProjectsByProjectName_result(this);
    }

    @Override
    public void clear() {
      this.success = null;
      this.ire = null;
      this.ace = null;
      this.ase = null;
      this.ae = null;
    }

    public int getSuccessSize() {
      return (this.success == null) ? 0 : this.success.size();
    }

    public java.util.Iterator<org.apache.airavata.model.workspace.Project> getSuccessIterator() {
      return (this.success == null) ? null : this.success.iterator();
    }

    public void addToSuccess(org.apache.airavata.model.workspace.Project elem) {
      if (this.success == null) {
        this.success = new ArrayList<org.apache.airavata.model.workspace.Project>();
      }
      this.success.add(elem);
    }

    public List<org.apache.airavata.model.workspace.Project> getSuccess() {
      return this.success;
    }

    public searchProjectsByProjectName_result setSuccess(List<org.apache.airavata.model.workspace.Project> 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.model.error.InvalidRequestException getIre() {
      return this.ire;
    }

    public searchProjectsByProjectName_result setIre(org.apache.airavata.model.error.InvalidRequestException ire) {
      this.ire = ire;
      return this;
    }

    public void unsetIre() {
      this.ire = null;
    }

    /** Returns true if field ire is set (has been assigned a value) and false otherwise */
    public boolean isSetIre() {
      return this.ire != null;
    }

    public void setIreIsSet(boolean value) {
      if (!value) {
        this.ire = null;
      }
    }

    public org.apache.airavata.model.error.AiravataClientException getAce() {
      return this.ace;
    }

    public searchProjectsByProjectName_result setAce(org.apache.airavata.model.error.AiravataClientException ace) {
      this.ace = ace;
      return this;
    }

    public void unsetAce() {
      this.ace = null;
    }

    /** Returns true if field ace is set (has been assigned a value) and false otherwise */
    public boolean isSetAce() {
      return this.ace != null;
    }

    public void setAceIsSet(boolean value) {
      if (!value) {
        this.ace = null;
      }
    }

    public org.apache.airavata.model.error.AiravataSystemException getAse() {
      return this.ase;
    }

    public searchProjectsByProjectName_result setAse(org.apache.airavata.model.error.AiravataSystemException ase) {
      this.ase = ase;
      return this;
    }

    public void unsetAse() {
      this.ase = null;
    }

    /** Returns true if field ase is set (has been assigned a value) and false otherwise */
    public boolean isSetAse() {
      return this.ase != null;
    }

    public void setAseIsSet(boolean value) {
      if (!value) {
        this.ase = null;
      }
    }

    public org.apache.airavata.model.error.AuthorizationException getAe() {
      return this.ae;
    }

    public searchProjectsByProjectName_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, Object value) {
      switch (field) {
      case SUCCESS:
        if (value == null) {
          unsetSuccess();
        } else {
          setSuccess((List<org.apache.airavata.model.workspace.Project>)value);
        }
        break;

      case IRE:
        if (value == null) {
          unsetIre();
        } else {
          setIre((org.apache.airavata.model.error.InvalidRequestException)value);
        }
        break;

      case ACE:
        if (value == null) {
          unsetAce();
        } else {
          setAce((org.apache.airavata.model.error.AiravataClientException)value);
        }
        break;

      case ASE:
        if (value == null) {
          unsetAse();
        } else {
          setAse((org.apache.airavata.model.error.AiravataSystemException)value);
        }
        break;

      case AE:
        if (value == null) {
          unsetAe();
        } else {
          setAe((org.apache.airavata.model.error.AuthorizationException)value);
        }
        break;

      }
    }

    public Object getFieldValue(_Fields field) {
      switch (field) {
      case SUCCESS:
        return getSuccess();

      case IRE:
        return getIre();

      case ACE:
        return getAce();

      case ASE:
        return getAse();

      case AE:
        return getAe();

      }
      throw new IllegalStateException();
    }

    /** Returns true if field corresponding to fieldID is set (has been assigned a value) and false otherwise */
    public boolean isSet(_Fields field) {
      if (field == null) {
        throw new IllegalArgumentException();
      }

      switch (field) {
      case SUCCESS:
        return isSetSuccess();
      case IRE:
        return isSetIre();
      case ACE:
        return isSetAce();
      case ASE:
        return isSetAse();
      case AE:
        return isSetAe();
      }
      throw new IllegalStateException();
    }

    @Override
    public boolean equals(Object that) {
      if (that == null)
        return false;
      if (that instanceof searchProjectsByProjectName_result)
        return this.equals((searchProjectsByProjectName_result)that);
      return false;
    }

    public boolean equals(searchProjectsByProjectName_result that) {
      if (that == null)
        return false;

      boolean this_present_success = true && this.isSetSuccess();
      boolean that_present_success = true && that.isSetSuccess();
      if (this_present_success || that_present_success) {
        if (!(this_present_success && that_present_success))
          return false;
        if (!this.success.equals(that.success))
          return false;
      }

      boolean this_present_ire = true && this.isSetIre();
      boolean that_present_ire = true && that.isSetIre();
      if (this_present_ire || that_present_ire) {
        if (!(this_present_ire && that_present_ire))
          return false;
        if (!this.ire.equals(that.ire))
          return false;
      }

      boolean this_present_ace = true && this.isSetAce();
      boolean that_present_ace = true && that.isSetAce();
      if (this_present_ace || that_present_ace) {
        if (!(this_present_ace && that_present_ace))
          return false;
        if (!this.ace.equals(that.ace))
          return false;
      }

      boolean this_present_ase = true && this.isSetAse();
      boolean that_present_ase = true && that.isSetAse();
      if (this_present_ase || that_present_ase) {
        if (!(this_present_ase && that_present_ase))
          return false;
        if (!this.ase.equals(that.ase))
          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() {
      List<Object> list = new ArrayList<Object>();

      boolean present_success = true && (isSetSuccess());
      list.add(present_success);
      if (present_success)
        list.add(success);

      boolean present_ire = true && (isSetIre());
      list.add(present_ire);
      if (present_ire)
        list.add(ire);

      boolean present_ace = true && (isSetAce());
      list.add(present_ace);
      if (present_ace)
        list.add(ace);

      boolean present_ase = true && (isSetAse());
      list.add(present_ase);
      if (present_ase)
        list.add(ase);

      boolean present_ae = true && (isSetAe());
      list.add(present_ae);
      if (present_ae)
        list.add(ae);

      return list.hashCode();
    }

    @Override
    public int compareTo(searchProjectsByProjectName_result other) {
      if (!getClass().equals(other.getClass())) {
        return getClass().getName().compareTo(other.getClass().getName());
      }

      int lastComparison = 0;

      lastComparison = Boolean.valueOf(isSetSuccess()).compareTo(other.isSetSuccess());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetSuccess()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.success, other.success);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = Boolean.valueOf(isSetIre()).compareTo(other.isSetIre());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetIre()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.ire, other.ire);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = Boolean.valueOf(isSetAce()).compareTo(other.isSetAce());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetAce()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.ace, other.ace);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = Boolean.valueOf(isSetAse()).compareTo(other.isSetAse());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetAse()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.ase, other.ase);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = 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 {
      schemes.get(iprot.getScheme()).getScheme().read(iprot, this);
    }

    public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException {
      schemes.get(oprot.getScheme()).getScheme().write(oprot, this);
      }

    @Override
    public String toString() {
      StringBuilder sb = new StringBuilder("searchProjectsByProjectName_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("ire:");
      if (this.ire == null) {
        sb.append("null");
      } else {
        sb.append(this.ire);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("ace:");
      if (this.ace == null) {
        sb.append("null");
      } else {
        sb.append(this.ace);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("ase:");
      if (this.ase == null) {
        sb.append("null");
      } else {
        sb.append(this.ase);
      }
      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, 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 searchProjectsByProjectName_resultStandardSchemeFactory implements SchemeFactory {
      public searchProjectsByProjectName_resultStandardScheme getScheme() {
        return new searchProjectsByProjectName_resultStandardScheme();
      }
    }

    private static class searchProjectsByProjectName_resultStandardScheme extends StandardScheme<searchProjectsByProjectName_result> {

      public void read(org.apache.thrift.protocol.TProtocol iprot, searchProjectsByProjectName_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 _list26 = iprot.readListBegin();
                  struct.success = new ArrayList<org.apache.airavata.model.workspace.Project>(_list26.size);
                  org.apache.airavata.model.workspace.Project _elem27;
                  for (int _i28 = 0; _i28 < _list26.size; ++_i28)
                  {
                    _elem27 = new org.apache.airavata.model.workspace.Project();
                    _elem27.read(iprot);
                    struct.success.add(_elem27);
                  }
                  iprot.readListEnd();
                }
                struct.setSuccessIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 1: // IRE
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.ire = new org.apache.airavata.model.error.InvalidRequestException();
                struct.ire.read(iprot);
                struct.setIreIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 2: // ACE
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.ace = new org.apache.airavata.model.error.AiravataClientException();
                struct.ace.read(iprot);
                struct.setAceIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 3: // ASE
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.ase = new org.apache.airavata.model.error.AiravataSystemException();
                struct.ase.read(iprot);
                struct.setAseIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 4: // 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, searchProjectsByProjectName_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.Project _iter29 : struct.success)
            {
              _iter29.write(oprot);
            }
            oprot.writeListEnd();
          }
          oprot.writeFieldEnd();
        }
        if (struct.ire != null) {
          oprot.writeFieldBegin(IRE_FIELD_DESC);
          struct.ire.write(oprot);
          oprot.writeFieldEnd();
        }
        if (struct.ace != null) {
          oprot.writeFieldBegin(ACE_FIELD_DESC);
          struct.ace.write(oprot);
          oprot.writeFieldEnd();
        }
        if (struct.ase != null) {
          oprot.writeFieldBegin(ASE_FIELD_DESC);
          struct.ase.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 searchProjectsByProjectName_resultTupleSchemeFactory implements SchemeFactory {
      public searchProjectsByProjectName_resultTupleScheme getScheme() {
        return new searchProjectsByProjectName_resultTupleScheme();
      }
    }

    private static class searchProjectsByProjectName_resultTupleScheme extends TupleScheme<searchProjectsByProjectName_result> {

      @Override
      public void write(org.apache.thrift.protocol.TProtocol prot, searchProjectsByProjectName_result struct) throws org.apache.thrift.TException {
        TTupleProtocol oprot = (TTupleProtocol) prot;
        BitSet optionals = new BitSet();
        if (struct.isSetSuccess()) {
          optionals.set(0);
        }
        if (struct.isSetIre()) {
          optionals.set(1);
        }
        if (struct.isSetAce()) {
          optionals.set(2);
        }
        if (struct.isSetAse()) {
          optionals.set(3);
        }
        if (struct.isSetAe()) {
          optionals.set(4);
        }
        oprot.writeBitSet(optionals, 5);
        if (struct.isSetSuccess()) {
          {
            oprot.writeI32(struct.success.size());
            for (org.apache.airavata.model.workspace.Project _iter30 : struct.success)
            {
              _iter30.write(oprot);
            }
          }
        }
        if (struct.isSetIre()) {
          struct.ire.write(oprot);
        }
        if (struct.isSetAce()) {
          struct.ace.write(oprot);
        }
        if (struct.isSetAse()) {
          struct.ase.write(oprot);
        }
        if (struct.isSetAe()) {
          struct.ae.write(oprot);
        }
      }

      @Override
      public void read(org.apache.thrift.protocol.TProtocol prot, searchProjectsByProjectName_result struct) throws org.apache.thrift.TException {
        TTupleProtocol iprot = (TTupleProtocol) prot;
        BitSet incoming = iprot.readBitSet(5);
        if (incoming.get(0)) {
          {
            org.apache.thrift.protocol.TList _list31 = new org.apache.thrift.protocol.TList(org.apache.thrift.protocol.TType.STRUCT, iprot.readI32());
            struct.success = new ArrayList<org.apache.airavata.model.workspace.Project>(_list31.size);
            org.apache.airavata.model.workspace.Project _elem32;
            for (int _i33 = 0; _i33 < _list31.size; ++_i33)
            {
              _elem32 = new org.apache.airavata.model.workspace.Project();
              _elem32.read(iprot);
              struct.success.add(_elem32);
            }
          }
          struct.setSuccessIsSet(true);
        }
        if (incoming.get(1)) {
          struct.ire = new org.apache.airavata.model.error.InvalidRequestException();
          struct.ire.read(iprot);
          struct.setIreIsSet(true);
        }
        if (incoming.get(2)) {
          struct.ace = new org.apache.airavata.model.error.AiravataClientException();
          struct.ace.read(iprot);
          struct.setAceIsSet(true);
        }
        if (incoming.get(3)) {
          struct.ase = new org.apache.airavata.model.error.AiravataSystemException();
          struct.ase.read(iprot);
          struct.setAseIsSet(true);
        }
        if (incoming.get(4)) {
          struct.ae = new org.apache.airavata.model.error.AuthorizationException();
          struct.ae.read(iprot);
          struct.setAeIsSet(true);
        }
      }
    }

  }

  public static class searchProjectsByProjectDesc_args implements org.apache.thrift.TBase<searchProjectsByProjectDesc_args, searchProjectsByProjectDesc_args._Fields>, java.io.Serializable, Cloneable, Comparable<searchProjectsByProjectDesc_args>   {
    private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("searchProjectsByProjectDesc_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.protocol.TField USER_NAME_FIELD_DESC = new org.apache.thrift.protocol.TField("userName", org.apache.thrift.protocol.TType.STRING, (short)3);
    private static final org.apache.thrift.protocol.TField DESCRIPTION_FIELD_DESC = new org.apache.thrift.protocol.TField("description", org.apache.thrift.protocol.TType.STRING, (short)4);
    private static final org.apache.thrift.protocol.TField LIMIT_FIELD_DESC = new org.apache.thrift.protocol.TField("limit", org.apache.thrift.protocol.TType.I32, (short)5);
    private static final org.apache.thrift.protocol.TField OFFSET_FIELD_DESC = new org.apache.thrift.protocol.TField("offset", org.apache.thrift.protocol.TType.I32, (short)6);

    private static final Map<Class<? extends IScheme>, SchemeFactory> schemes = new HashMap<Class<? extends IScheme>, SchemeFactory>();
    static {
      schemes.put(StandardScheme.class, new searchProjectsByProjectDesc_argsStandardSchemeFactory());
      schemes.put(TupleScheme.class, new searchProjectsByProjectDesc_argsTupleSchemeFactory());
    }

    public org.apache.airavata.model.security.AuthzToken authzToken; // required
    public String gatewayId; // required
    public String userName; // required
    public String description; // required
    public int limit; // required
    public int offset; // required

    /** 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"),
      USER_NAME((short)3, "userName"),
      DESCRIPTION((short)4, "description"),
      LIMIT((short)5, "limit"),
      OFFSET((short)6, "offset");

      private static final Map<String, _Fields> byName = new HashMap<String, _Fields>();

      static {
        for (_Fields field : EnumSet.allOf(_Fields.class)) {
          byName.put(field.getFieldName(), field);
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, or null if its not found.
       */
      public static _Fields findByThriftId(int fieldId) {
        switch(fieldId) {
          case 1: // AUTHZ_TOKEN
            return AUTHZ_TOKEN;
          case 2: // GATEWAY_ID
            return GATEWAY_ID;
          case 3: // USER_NAME
            return USER_NAME;
          case 4: // DESCRIPTION
            return DESCRIPTION;
          case 5: // LIMIT
            return LIMIT;
          case 6: // OFFSET
            return OFFSET;
          default:
            return null;
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, throwing an exception
       * if it is not found.
       */
      public static _Fields findByThriftIdOrThrow(int fieldId) {
        _Fields fields = findByThriftId(fieldId);
        if (fields == null) throw new IllegalArgumentException("Field " + fieldId + " doesn't exist!");
        return fields;
      }

      /**
       * Find the _Fields constant that matches name, or null if its not found.
       */
      public static _Fields findByName(String name) {
        return byName.get(name);
      }

      private final short _thriftId;
      private final String _fieldName;

      _Fields(short thriftId, String fieldName) {
        _thriftId = thriftId;
        _fieldName = fieldName;
      }

      public short getThriftFieldId() {
        return _thriftId;
      }

      public String getFieldName() {
        return _fieldName;
      }
    }

    // isset id assignments
    private static final int __LIMIT_ISSET_ID = 0;
    private static final int __OFFSET_ISSET_ID = 1;
    private byte __isset_bitfield = 0;
    public static final Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
    static {
      Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new EnumMap<_Fields, org.apache.thrift.meta_data.FieldMetaData>(_Fields.class);
      tmpMap.put(_Fields.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)));
      tmpMap.put(_Fields.USER_NAME, new org.apache.thrift.meta_data.FieldMetaData("userName", org.apache.thrift.TFieldRequirementType.REQUIRED, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING)));
      tmpMap.put(_Fields.DESCRIPTION, new org.apache.thrift.meta_data.FieldMetaData("description", org.apache.thrift.TFieldRequirementType.REQUIRED, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING)));
      tmpMap.put(_Fields.LIMIT, new org.apache.thrift.meta_data.FieldMetaData("limit", org.apache.thrift.TFieldRequirementType.REQUIRED, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.I32)));
      tmpMap.put(_Fields.OFFSET, new org.apache.thrift.meta_data.FieldMetaData("offset", org.apache.thrift.TFieldRequirementType.REQUIRED, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.I32)));
      metaDataMap = Collections.unmodifiableMap(tmpMap);
      org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(searchProjectsByProjectDesc_args.class, metaDataMap);
    }

    public searchProjectsByProjectDesc_args() {
    }

    public searchProjectsByProjectDesc_args(
      org.apache.airavata.model.security.AuthzToken authzToken,
      String gatewayId,
      String userName,
      String description,
      int limit,
      int offset)
    {
      this();
      this.authzToken = authzToken;
      this.gatewayId = gatewayId;
      this.userName = userName;
      this.description = description;
      this.limit = limit;
      setLimitIsSet(true);
      this.offset = offset;
      setOffsetIsSet(true);
    }

    /**
     * Performs a deep copy on <i>other</i>.
     */
    public searchProjectsByProjectDesc_args(searchProjectsByProjectDesc_args other) {
      __isset_bitfield = other.__isset_bitfield;
      if (other.isSetAuthzToken()) {
        this.authzToken = new org.apache.airavata.model.security.AuthzToken(other.authzToken);
      }
      if (other.isSetGatewayId()) {
        this.gatewayId = other.gatewayId;
      }
      if (other.isSetUserName()) {
        this.userName = other.userName;
      }
      if (other.isSetDescription()) {
        this.description = other.description;
      }
      this.limit = other.limit;
      this.offset = other.offset;
    }

    public searchProjectsByProjectDesc_args deepCopy() {
      return new searchProjectsByProjectDesc_args(this);
    }

    @Override
    public void clear() {
      this.authzToken = null;
      this.gatewayId = null;
      this.userName = null;
      this.description = null;
      setLimitIsSet(false);
      this.limit = 0;
      setOffsetIsSet(false);
      this.offset = 0;
    }

    public org.apache.airavata.model.security.AuthzToken getAuthzToken() {
      return this.authzToken;
    }

    public searchProjectsByProjectDesc_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 String getGatewayId() {
      return this.gatewayId;
    }

    public searchProjectsByProjectDesc_args setGatewayId(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 String getUserName() {
      return this.userName;
    }

    public searchProjectsByProjectDesc_args setUserName(String userName) {
      this.userName = userName;
      return this;
    }

    public void unsetUserName() {
      this.userName = null;
    }

    /** Returns true if field userName is set (has been assigned a value) and false otherwise */
    public boolean isSetUserName() {
      return this.userName != null;
    }

    public void setUserNameIsSet(boolean value) {
      if (!value) {
        this.userName = null;
      }
    }

    public String getDescription() {
      return this.description;
    }

    public searchProjectsByProjectDesc_args setDescription(String description) {
      this.description = description;
      return this;
    }

    public void unsetDescription() {
      this.description = null;
    }

    /** Returns true if field description is set (has been assigned a value) and false otherwise */
    public boolean isSetDescription() {
      return this.description != null;
    }

    public void setDescriptionIsSet(boolean value) {
      if (!value) {
        this.description = null;
      }
    }

    public int getLimit() {
      return this.limit;
    }

    public searchProjectsByProjectDesc_args setLimit(int limit) {
      this.limit = limit;
      setLimitIsSet(true);
      return this;
    }

    public void unsetLimit() {
      __isset_bitfield = EncodingUtils.clearBit(__isset_bitfield, __LIMIT_ISSET_ID);
    }

    /** Returns true if field limit is set (has been assigned a value) and false otherwise */
    public boolean isSetLimit() {
      return EncodingUtils.testBit(__isset_bitfield, __LIMIT_ISSET_ID);
    }

    public void setLimitIsSet(boolean value) {
      __isset_bitfield = EncodingUtils.setBit(__isset_bitfield, __LIMIT_ISSET_ID, value);
    }

    public int getOffset() {
      return this.offset;
    }

    public searchProjectsByProjectDesc_args setOffset(int offset) {
      this.offset = offset;
      setOffsetIsSet(true);
      return this;
    }

    public void unsetOffset() {
      __isset_bitfield = EncodingUtils.clearBit(__isset_bitfield, __OFFSET_ISSET_ID);
    }

    /** Returns true if field offset is set (has been assigned a value) and false otherwise */
    public boolean isSetOffset() {
      return EncodingUtils.testBit(__isset_bitfield, __OFFSET_ISSET_ID);
    }

    public void setOffsetIsSet(boolean value) {
      __isset_bitfield = EncodingUtils.setBit(__isset_bitfield, __OFFSET_ISSET_ID, value);
    }

    public void setFieldValue(_Fields field, 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((String)value);
        }
        break;

      case USER_NAME:
        if (value == null) {
          unsetUserName();
        } else {
          setUserName((String)value);
        }
        break;

      case DESCRIPTION:
        if (value == null) {
          unsetDescription();
        } else {
          setDescription((String)value);
        }
        break;

      case LIMIT:
        if (value == null) {
          unsetLimit();
        } else {
          setLimit((Integer)value);
        }
        break;

      case OFFSET:
        if (value == null) {
          unsetOffset();
        } else {
          setOffset((Integer)value);
        }
        break;

      }
    }

    public Object getFieldValue(_Fields field) {
      switch (field) {
      case AUTHZ_TOKEN:
        return getAuthzToken();

      case GATEWAY_ID:
        return getGatewayId();

      case USER_NAME:
        return getUserName();

      case DESCRIPTION:
        return getDescription();

      case LIMIT:
        return Integer.valueOf(getLimit());

      case OFFSET:
        return Integer.valueOf(getOffset());

      }
      throw new IllegalStateException();
    }

    /** Returns true if field corresponding to fieldID is set (has been assigned a value) and false otherwise */
    public boolean isSet(_Fields field) {
      if (field == null) {
        throw new IllegalArgumentException();
      }

      switch (field) {
      case AUTHZ_TOKEN:
        return isSetAuthzToken();
      case GATEWAY_ID:
        return isSetGatewayId();
      case USER_NAME:
        return isSetUserName();
      case DESCRIPTION:
        return isSetDescription();
      case LIMIT:
        return isSetLimit();
      case OFFSET:
        return isSetOffset();
      }
      throw new IllegalStateException();
    }

    @Override
    public boolean equals(Object that) {
      if (that == null)
        return false;
      if (that instanceof searchProjectsByProjectDesc_args)
        return this.equals((searchProjectsByProjectDesc_args)that);
      return false;
    }

    public boolean equals(searchProjectsByProjectDesc_args that) {
      if (that == null)
        return false;

      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;
      }

      boolean this_present_userName = true && this.isSetUserName();
      boolean that_present_userName = true && that.isSetUserName();
      if (this_present_userName || that_present_userName) {
        if (!(this_present_userName && that_present_userName))
          return false;
        if (!this.userName.equals(that.userName))
          return false;
      }

      boolean this_present_description = true && this.isSetDescription();
      boolean that_present_description = true && that.isSetDescription();
      if (this_present_description || that_present_description) {
        if (!(this_present_description && that_present_description))
          return false;
        if (!this.description.equals(that.description))
          return false;
      }

      boolean this_present_limit = true;
      boolean that_present_limit = true;
      if (this_present_limit || that_present_limit) {
        if (!(this_present_limit && that_present_limit))
          return false;
        if (this.limit != that.limit)
          return false;
      }

      boolean this_present_offset = true;
      boolean that_present_offset = true;
      if (this_present_offset || that_present_offset) {
        if (!(this_present_offset && that_present_offset))
          return false;
        if (this.offset != that.offset)
          return false;
      }

      return true;
    }

    @Override
    public int hashCode() {
      List<Object> list = new ArrayList<Object>();

      boolean present_authzToken = true && (isSetAuthzToken());
      list.add(present_authzToken);
      if (present_authzToken)
        list.add(authzToken);

      boolean present_gatewayId = true && (isSetGatewayId());
      list.add(present_gatewayId);
      if (present_gatewayId)
        list.add(gatewayId);

      boolean present_userName = true && (isSetUserName());
      list.add(present_userName);
      if (present_userName)
        list.add(userName);

      boolean present_description = true && (isSetDescription());
      list.add(present_description);
      if (present_description)
        list.add(description);

      boolean present_limit = true;
      list.add(present_limit);
      if (present_limit)
        list.add(limit);

      boolean present_offset = true;
      list.add(present_offset);
      if (present_offset)
        list.add(offset);

      return list.hashCode();
    }

    @Override
    public int compareTo(searchProjectsByProjectDesc_args other) {
      if (!getClass().equals(other.getClass())) {
        return getClass().getName().compareTo(other.getClass().getName());
      }

      int lastComparison = 0;

      lastComparison = 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 = 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;
        }
      }
      lastComparison = Boolean.valueOf(isSetUserName()).compareTo(other.isSetUserName());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetUserName()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.userName, other.userName);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = Boolean.valueOf(isSetDescription()).compareTo(other.isSetDescription());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetDescription()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.description, other.description);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = Boolean.valueOf(isSetLimit()).compareTo(other.isSetLimit());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetLimit()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.limit, other.limit);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = Boolean.valueOf(isSetOffset()).compareTo(other.isSetOffset());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetOffset()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.offset, other.offset);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      return 0;
    }

    public _Fields fieldForId(int fieldId) {
      return _Fields.findByThriftId(fieldId);
    }

    public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
      schemes.get(iprot.getScheme()).getScheme().read(iprot, this);
    }

    public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException {
      schemes.get(oprot.getScheme()).getScheme().write(oprot, this);
    }

    @Override
    public String toString() {
      StringBuilder sb = new StringBuilder("searchProjectsByProjectDesc_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;
      if (!first) sb.append(", ");
      sb.append("userName:");
      if (this.userName == null) {
        sb.append("null");
      } else {
        sb.append(this.userName);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("description:");
      if (this.description == null) {
        sb.append("null");
      } else {
        sb.append(this.description);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("limit:");
      sb.append(this.limit);
      first = false;
      if (!first) sb.append(", ");
      sb.append("offset:");
      sb.append(this.offset);
      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());
      }
      if (userName == null) {
        throw new org.apache.thrift.protocol.TProtocolException("Required field 'userName' was not present! Struct: " + toString());
      }
      if (description == null) {
        throw new org.apache.thrift.protocol.TProtocolException("Required field 'description' was not present! Struct: " + toString());
      }
      // alas, we cannot check 'limit' because it's a primitive and you chose the non-beans generator.
      // alas, we cannot check 'offset' because it's a primitive and you chose the non-beans generator.
      // 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, 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 searchProjectsByProjectDesc_argsStandardSchemeFactory implements SchemeFactory {
      public searchProjectsByProjectDesc_argsStandardScheme getScheme() {
        return new searchProjectsByProjectDesc_argsStandardScheme();
      }
    }

    private static class searchProjectsByProjectDesc_argsStandardScheme extends StandardScheme<searchProjectsByProjectDesc_args> {

      public void read(org.apache.thrift.protocol.TProtocol iprot, searchProjectsByProjectDesc_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;
            case 3: // USER_NAME
              if (schemeField.type == org.apache.thrift.protocol.TType.STRING) {
                struct.userName = iprot.readString();
                struct.setUserNameIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 4: // DESCRIPTION
              if (schemeField.type == org.apache.thrift.protocol.TType.STRING) {
                struct.description = iprot.readString();
                struct.setDescriptionIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 5: // LIMIT
              if (schemeField.type == org.apache.thrift.protocol.TType.I32) {
                struct.limit = iprot.readI32();
                struct.setLimitIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 6: // OFFSET
              if (schemeField.type == org.apache.thrift.protocol.TType.I32) {
                struct.offset = iprot.readI32();
                struct.setOffsetIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            default:
              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
          }
          iprot.readFieldEnd();
        }
        iprot.readStructEnd();

        // check for required fields of primitive type, which can't be checked in the validate method
        if (!struct.isSetLimit()) {
          throw new org.apache.thrift.protocol.TProtocolException("Required field 'limit' was not found in serialized data! Struct: " + toString());
        }
        if (!struct.isSetOffset()) {
          throw new org.apache.thrift.protocol.TProtocolException("Required field 'offset' was not found in serialized data! Struct: " + toString());
        }
        struct.validate();
      }

      public void write(org.apache.thrift.protocol.TProtocol oprot, searchProjectsByProjectDesc_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();
        }
        if (struct.userName != null) {
          oprot.writeFieldBegin(USER_NAME_FIELD_DESC);
          oprot.writeString(struct.userName);
          oprot.writeFieldEnd();
        }
        if (struct.description != null) {
          oprot.writeFieldBegin(DESCRIPTION_FIELD_DESC);
          oprot.writeString(struct.description);
          oprot.writeFieldEnd();
        }
        oprot.writeFieldBegin(LIMIT_FIELD_DESC);
        oprot.writeI32(struct.limit);
        oprot.writeFieldEnd();
        oprot.writeFieldBegin(OFFSET_FIELD_DESC);
        oprot.writeI32(struct.offset);
        oprot.writeFieldEnd();
        oprot.writeFieldStop();
        oprot.writeStructEnd();
      }

    }

    private static class searchProjectsByProjectDesc_argsTupleSchemeFactory implements SchemeFactory {
      public searchProjectsByProjectDesc_argsTupleScheme getScheme() {
        return new searchProjectsByProjectDesc_argsTupleScheme();
      }
    }

    private static class searchProjectsByProjectDesc_argsTupleScheme extends TupleScheme<searchProjectsByProjectDesc_args> {

      @Override
      public void write(org.apache.thrift.protocol.TProtocol prot, searchProjectsByProjectDesc_args struct) throws org.apache.thrift.TException {
        TTupleProtocol oprot = (TTupleProtocol) prot;
        struct.authzToken.write(oprot);
        oprot.writeString(struct.gatewayId);
        oprot.writeString(struct.userName);
        oprot.writeString(struct.description);
        oprot.writeI32(struct.limit);
        oprot.writeI32(struct.offset);
      }

      @Override
      public void read(org.apache.thrift.protocol.TProtocol prot, searchProjectsByProjectDesc_args struct) throws org.apache.thrift.TException {
        TTupleProtocol iprot = (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);
        struct.userName = iprot.readString();
        struct.setUserNameIsSet(true);
        struct.description = iprot.readString();
        struct.setDescriptionIsSet(true);
        struct.limit = iprot.readI32();
        struct.setLimitIsSet(true);
        struct.offset = iprot.readI32();
        struct.setOffsetIsSet(true);
      }
    }

  }

  public static class searchProjectsByProjectDesc_result implements org.apache.thrift.TBase<searchProjectsByProjectDesc_result, searchProjectsByProjectDesc_result._Fields>, java.io.Serializable, Cloneable, Comparable<searchProjectsByProjectDesc_result>   {
    private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("searchProjectsByProjectDesc_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 IRE_FIELD_DESC = new org.apache.thrift.protocol.TField("ire", org.apache.thrift.protocol.TType.STRUCT, (short)1);
    private static final org.apache.thrift.protocol.TField ACE_FIELD_DESC = new org.apache.thrift.protocol.TField("ace", org.apache.thrift.protocol.TType.STRUCT, (short)2);
    private static final org.apache.thrift.protocol.TField ASE_FIELD_DESC = new org.apache.thrift.protocol.TField("ase", org.apache.thrift.protocol.TType.STRUCT, (short)3);
    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)4);

    private static final Map<Class<? extends IScheme>, SchemeFactory> schemes = new HashMap<Class<? extends IScheme>, SchemeFactory>();
    static {
      schemes.put(StandardScheme.class, new searchProjectsByProjectDesc_resultStandardSchemeFactory());
      schemes.put(TupleScheme.class, new searchProjectsByProjectDesc_resultTupleSchemeFactory());
    }

    public List<org.apache.airavata.model.workspace.Project> success; // required
    public org.apache.airavata.model.error.InvalidRequestException ire; // required
    public org.apache.airavata.model.error.AiravataClientException ace; // required
    public org.apache.airavata.model.error.AiravataSystemException ase; // 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"),
      IRE((short)1, "ire"),
      ACE((short)2, "ace"),
      ASE((short)3, "ase"),
      AE((short)4, "ae");

      private static final Map<String, _Fields> byName = new HashMap<String, _Fields>();

      static {
        for (_Fields field : EnumSet.allOf(_Fields.class)) {
          byName.put(field.getFieldName(), field);
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, or null if its not found.
       */
      public static _Fields findByThriftId(int fieldId) {
        switch(fieldId) {
          case 0: // SUCCESS
            return SUCCESS;
          case 1: // IRE
            return IRE;
          case 2: // ACE
            return ACE;
          case 3: // ASE
            return ASE;
          case 4: // 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 IllegalArgumentException("Field " + fieldId + " doesn't exist!");
        return fields;
      }

      /**
       * Find the _Fields constant that matches name, or null if its not found.
       */
      public static _Fields findByName(String name) {
        return byName.get(name);
      }

      private final short _thriftId;
      private final String _fieldName;

      _Fields(short thriftId, String fieldName) {
        _thriftId = thriftId;
        _fieldName = fieldName;
      }

      public short getThriftFieldId() {
        return _thriftId;
      }

      public String getFieldName() {
        return _fieldName;
      }
    }

    // isset id assignments
    public static final Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
    static {
      Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new EnumMap<_Fields, org.apache.thrift.meta_data.FieldMetaData>(_Fields.class);
      tmpMap.put(_Fields.SUCCESS, new org.apache.thrift.meta_data.FieldMetaData("success", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.ListMetaData(org.apache.thrift.protocol.TType.LIST, 
              new org.apache.thrift.meta_data.StructMetaData(org.apache.thrift.protocol.TType.STRUCT, org.apache.airavata.model.workspace.Project.class))));
      tmpMap.put(_Fields.IRE, new org.apache.thrift.meta_data.FieldMetaData("ire", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRUCT)));
      tmpMap.put(_Fields.ACE, new org.apache.thrift.meta_data.FieldMetaData("ace", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRUCT)));
      tmpMap.put(_Fields.ASE, new org.apache.thrift.meta_data.FieldMetaData("ase", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRUCT)));
      tmpMap.put(_Fields.AE, new org.apache.thrift.meta_data.FieldMetaData("ae", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRUCT)));
      metaDataMap = Collections.unmodifiableMap(tmpMap);
      org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(searchProjectsByProjectDesc_result.class, metaDataMap);
    }

    public searchProjectsByProjectDesc_result() {
    }

    public searchProjectsByProjectDesc_result(
      List<org.apache.airavata.model.workspace.Project> success,
      org.apache.airavata.model.error.InvalidRequestException ire,
      org.apache.airavata.model.error.AiravataClientException ace,
      org.apache.airavata.model.error.AiravataSystemException ase,
      org.apache.airavata.model.error.AuthorizationException ae)
    {
      this();
      this.success = success;
      this.ire = ire;
      this.ace = ace;
      this.ase = ase;
      this.ae = ae;
    }

    /**
     * Performs a deep copy on <i>other</i>.
     */
    public searchProjectsByProjectDesc_result(searchProjectsByProjectDesc_result other) {
      if (other.isSetSuccess()) {
        List<org.apache.airavata.model.workspace.Project> __this__success = new ArrayList<org.apache.airavata.model.workspace.Project>(other.success.size());
        for (org.apache.airavata.model.workspace.Project other_element : other.success) {
          __this__success.add(new org.apache.airavata.model.workspace.Project(other_element));
        }
        this.success = __this__success;
      }
      if (other.isSetIre()) {
        this.ire = new org.apache.airavata.model.error.InvalidRequestException(other.ire);
      }
      if (other.isSetAce()) {
        this.ace = new org.apache.airavata.model.error.AiravataClientException(other.ace);
      }
      if (other.isSetAse()) {
        this.ase = new org.apache.airavata.model.error.AiravataSystemException(other.ase);
      }
      if (other.isSetAe()) {
        this.ae = new org.apache.airavata.model.error.AuthorizationException(other.ae);
      }
    }

    public searchProjectsByProjectDesc_result deepCopy() {
      return new searchProjectsByProjectDesc_result(this);
    }

    @Override
    public void clear() {
      this.success = null;
      this.ire = null;
      this.ace = null;
      this.ase = null;
      this.ae = null;
    }

    public int getSuccessSize() {
      return (this.success == null) ? 0 : this.success.size();
    }

    public java.util.Iterator<org.apache.airavata.model.workspace.Project> getSuccessIterator() {
      return (this.success == null) ? null : this.success.iterator();
    }

    public void addToSuccess(org.apache.airavata.model.workspace.Project elem) {
      if (this.success == null) {
        this.success = new ArrayList<org.apache.airavata.model.workspace.Project>();
      }
      this.success.add(elem);
    }

    public List<org.apache.airavata.model.workspace.Project> getSuccess() {
      return this.success;
    }

    public searchProjectsByProjectDesc_result setSuccess(List<org.apache.airavata.model.workspace.Project> 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.model.error.InvalidRequestException getIre() {
      return this.ire;
    }

    public searchProjectsByProjectDesc_result setIre(org.apache.airavata.model.error.InvalidRequestException ire) {
      this.ire = ire;
      return this;
    }

    public void unsetIre() {
      this.ire = null;
    }

    /** Returns true if field ire is set (has been assigned a value) and false otherwise */
    public boolean isSetIre() {
      return this.ire != null;
    }

    public void setIreIsSet(boolean value) {
      if (!value) {
        this.ire = null;
      }
    }

    public org.apache.airavata.model.error.AiravataClientException getAce() {
      return this.ace;
    }

    public searchProjectsByProjectDesc_result setAce(org.apache.airavata.model.error.AiravataClientException ace) {
      this.ace = ace;
      return this;
    }

    public void unsetAce() {
      this.ace = null;
    }

    /** Returns true if field ace is set (has been assigned a value) and false otherwise */
    public boolean isSetAce() {
      return this.ace != null;
    }

    public void setAceIsSet(boolean value) {
      if (!value) {
        this.ace = null;
      }
    }

    public org.apache.airavata.model.error.AiravataSystemException getAse() {
      return this.ase;
    }

    public searchProjectsByProjectDesc_result setAse(org.apache.airavata.model.error.AiravataSystemException ase) {
      this.ase = ase;
      return this;
    }

    public void unsetAse() {
      this.ase = null;
    }

    /** Returns true if field ase is set (has been assigned a value) and false otherwise */
    public boolean isSetAse() {
      return this.ase != null;
    }

    public void setAseIsSet(boolean value) {
      if (!value) {
        this.ase = null;
      }
    }

    public org.apache.airavata.model.error.AuthorizationException getAe() {
      return this.ae;
    }

    public searchProjectsByProjectDesc_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, Object value) {
      switch (field) {
      case SUCCESS:
        if (value == null) {
          unsetSuccess();
        } else {
          setSuccess((List<org.apache.airavata.model.workspace.Project>)value);
        }
        break;

      case IRE:
        if (value == null) {
          unsetIre();
        } else {
          setIre((org.apache.airavata.model.error.InvalidRequestException)value);
        }
        break;

      case ACE:
        if (value == null) {
          unsetAce();
        } else {
          setAce((org.apache.airavata.model.error.AiravataClientException)value);
        }
        break;

      case ASE:
        if (value == null) {
          unsetAse();
        } else {
          setAse((org.apache.airavata.model.error.AiravataSystemException)value);
        }
        break;

      case AE:
        if (value == null) {
          unsetAe();
        } else {
          setAe((org.apache.airavata.model.error.AuthorizationException)value);
        }
        break;

      }
    }

    public Object getFieldValue(_Fields field) {
      switch (field) {
      case SUCCESS:
        return getSuccess();

      case IRE:
        return getIre();

      case ACE:
        return getAce();

      case ASE:
        return getAse();

      case AE:
        return getAe();

      }
      throw new IllegalStateException();
    }

    /** Returns true if field corresponding to fieldID is set (has been assigned a value) and false otherwise */
    public boolean isSet(_Fields field) {
      if (field == null) {
        throw new IllegalArgumentException();
      }

      switch (field) {
      case SUCCESS:
        return isSetSuccess();
      case IRE:
        return isSetIre();
      case ACE:
        return isSetAce();
      case ASE:
        return isSetAse();
      case AE:
        return isSetAe();
      }
      throw new IllegalStateException();
    }

    @Override
    public boolean equals(Object that) {
      if (that == null)
        return false;
      if (that instanceof searchProjectsByProjectDesc_result)
        return this.equals((searchProjectsByProjectDesc_result)that);
      return false;
    }

    public boolean equals(searchProjectsByProjectDesc_result that) {
      if (that == null)
        return false;

      boolean this_present_success = true && this.isSetSuccess();
      boolean that_present_success = true && that.isSetSuccess();
      if (this_present_success || that_present_success) {
        if (!(this_present_success && that_present_success))
          return false;
        if (!this.success.equals(that.success))
          return false;
      }

      boolean this_present_ire = true && this.isSetIre();
      boolean that_present_ire = true && that.isSetIre();
      if (this_present_ire || that_present_ire) {
        if (!(this_present_ire && that_present_ire))
          return false;
        if (!this.ire.equals(that.ire))
          return false;
      }

      boolean this_present_ace = true && this.isSetAce();
      boolean that_present_ace = true && that.isSetAce();
      if (this_present_ace || that_present_ace) {
        if (!(this_present_ace && that_present_ace))
          return false;
        if (!this.ace.equals(that.ace))
          return false;
      }

      boolean this_present_ase = true && this.isSetAse();
      boolean that_present_ase = true && that.isSetAse();
      if (this_present_ase || that_present_ase) {
        if (!(this_present_ase && that_present_ase))
          return false;
        if (!this.ase.equals(that.ase))
          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() {
      List<Object> list = new ArrayList<Object>();

      boolean present_success = true && (isSetSuccess());
      list.add(present_success);
      if (present_success)
        list.add(success);

      boolean present_ire = true && (isSetIre());
      list.add(present_ire);
      if (present_ire)
        list.add(ire);

      boolean present_ace = true && (isSetAce());
      list.add(present_ace);
      if (present_ace)
        list.add(ace);

      boolean present_ase = true && (isSetAse());
      list.add(present_ase);
      if (present_ase)
        list.add(ase);

      boolean present_ae = true && (isSetAe());
      list.add(present_ae);
      if (present_ae)
        list.add(ae);

      return list.hashCode();
    }

    @Override
    public int compareTo(searchProjectsByProjectDesc_result other) {
      if (!getClass().equals(other.getClass())) {
        return getClass().getName().compareTo(other.getClass().getName());
      }

      int lastComparison = 0;

      lastComparison = Boolean.valueOf(isSetSuccess()).compareTo(other.isSetSuccess());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetSuccess()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.success, other.success);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = Boolean.valueOf(isSetIre()).compareTo(other.isSetIre());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetIre()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.ire, other.ire);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = Boolean.valueOf(isSetAce()).compareTo(other.isSetAce());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetAce()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.ace, other.ace);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = Boolean.valueOf(isSetAse()).compareTo(other.isSetAse());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetAse()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.ase, other.ase);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = 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 {
      schemes.get(iprot.getScheme()).getScheme().read(iprot, this);
    }

    public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException {
      schemes.get(oprot.getScheme()).getScheme().write(oprot, this);
      }

    @Override
    public String toString() {
      StringBuilder sb = new StringBuilder("searchProjectsByProjectDesc_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("ire:");
      if (this.ire == null) {
        sb.append("null");
      } else {
        sb.append(this.ire);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("ace:");
      if (this.ace == null) {
        sb.append("null");
      } else {
        sb.append(this.ace);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("ase:");
      if (this.ase == null) {
        sb.append("null");
      } else {
        sb.append(this.ase);
      }
      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, 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 searchProjectsByProjectDesc_resultStandardSchemeFactory implements SchemeFactory {
      public searchProjectsByProjectDesc_resultStandardScheme getScheme() {
        return new searchProjectsByProjectDesc_resultStandardScheme();
      }
    }

    private static class searchProjectsByProjectDesc_resultStandardScheme extends StandardScheme<searchProjectsByProjectDesc_result> {

      public void read(org.apache.thrift.protocol.TProtocol iprot, searchProjectsByProjectDesc_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 _list34 = iprot.readListBegin();
                  struct.success = new ArrayList<org.apache.airavata.model.workspace.Project>(_list34.size);
                  org.apache.airavata.model.workspace.Project _elem35;
                  for (int _i36 = 0; _i36 < _list34.size; ++_i36)
                  {
                    _elem35 = new org.apache.airavata.model.workspace.Project();
                    _elem35.read(iprot);
                    struct.success.add(_elem35);
                  }
                  iprot.readListEnd();
                }
                struct.setSuccessIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 1: // IRE
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.ire = new org.apache.airavata.model.error.InvalidRequestException();
                struct.ire.read(iprot);
                struct.setIreIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 2: // ACE
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.ace = new org.apache.airavata.model.error.AiravataClientException();
                struct.ace.read(iprot);
                struct.setAceIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 3: // ASE
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.ase = new org.apache.airavata.model.error.AiravataSystemException();
                struct.ase.read(iprot);
                struct.setAseIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 4: // 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, searchProjectsByProjectDesc_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.Project _iter37 : struct.success)
            {
              _iter37.write(oprot);
            }
            oprot.writeListEnd();
          }
          oprot.writeFieldEnd();
        }
        if (struct.ire != null) {
          oprot.writeFieldBegin(IRE_FIELD_DESC);
          struct.ire.write(oprot);
          oprot.writeFieldEnd();
        }
        if (struct.ace != null) {
          oprot.writeFieldBegin(ACE_FIELD_DESC);
          struct.ace.write(oprot);
          oprot.writeFieldEnd();
        }
        if (struct.ase != null) {
          oprot.writeFieldBegin(ASE_FIELD_DESC);
          struct.ase.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 searchProjectsByProjectDesc_resultTupleSchemeFactory implements SchemeFactory {
      public searchProjectsByProjectDesc_resultTupleScheme getScheme() {
        return new searchProjectsByProjectDesc_resultTupleScheme();
      }
    }

    private static class searchProjectsByProjectDesc_resultTupleScheme extends TupleScheme<searchProjectsByProjectDesc_result> {

      @Override
      public void write(org.apache.thrift.protocol.TProtocol prot, searchProjectsByProjectDesc_result struct) throws org.apache.thrift.TException {
        TTupleProtocol oprot = (TTupleProtocol) prot;
        BitSet optionals = new BitSet();
        if (struct.isSetSuccess()) {
          optionals.set(0);
        }
        if (struct.isSetIre()) {
          optionals.set(1);
        }
        if (struct.isSetAce()) {
          optionals.set(2);
        }
        if (struct.isSetAse()) {
          optionals.set(3);
        }
        if (struct.isSetAe()) {
          optionals.set(4);
        }
        oprot.writeBitSet(optionals, 5);
        if (struct.isSetSuccess()) {
          {
            oprot.writeI32(struct.success.size());
            for (org.apache.airavata.model.workspace.Project _iter38 : struct.success)
            {
              _iter38.write(oprot);
            }
          }
        }
        if (struct.isSetIre()) {
          struct.ire.write(oprot);
        }
        if (struct.isSetAce()) {
          struct.ace.write(oprot);
        }
        if (struct.isSetAse()) {
          struct.ase.write(oprot);
        }
        if (struct.isSetAe()) {
          struct.ae.write(oprot);
        }
      }

      @Override
      public void read(org.apache.thrift.protocol.TProtocol prot, searchProjectsByProjectDesc_result struct) throws org.apache.thrift.TException {
        TTupleProtocol iprot = (TTupleProtocol) prot;
        BitSet incoming = iprot.readBitSet(5);
        if (incoming.get(0)) {
          {
            org.apache.thrift.protocol.TList _list39 = new org.apache.thrift.protocol.TList(org.apache.thrift.protocol.TType.STRUCT, iprot.readI32());
            struct.success = new ArrayList<org.apache.airavata.model.workspace.Project>(_list39.size);
            org.apache.airavata.model.workspace.Project _elem40;
            for (int _i41 = 0; _i41 < _list39.size; ++_i41)
            {
              _elem40 = new org.apache.airavata.model.workspace.Project();
              _elem40.read(iprot);
              struct.success.add(_elem40);
            }
          }
          struct.setSuccessIsSet(true);
        }
        if (incoming.get(1)) {
          struct.ire = new org.apache.airavata.model.error.InvalidRequestException();
          struct.ire.read(iprot);
          struct.setIreIsSet(true);
        }
        if (incoming.get(2)) {
          struct.ace = new org.apache.airavata.model.error.AiravataClientException();
          struct.ace.read(iprot);
          struct.setAceIsSet(true);
        }
        if (incoming.get(3)) {
          struct.ase = new org.apache.airavata.model.error.AiravataSystemException();
          struct.ase.read(iprot);
          struct.setAseIsSet(true);
        }
        if (incoming.get(4)) {
          struct.ae = new org.apache.airavata.model.error.AuthorizationException();
          struct.ae.read(iprot);
          struct.setAeIsSet(true);
        }
      }
    }

  }

  public static class searchExperimentsByName_args implements org.apache.thrift.TBase<searchExperimentsByName_args, searchExperimentsByName_args._Fields>, java.io.Serializable, Cloneable, Comparable<searchExperimentsByName_args>   {
    private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("searchExperimentsByName_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.protocol.TField USER_NAME_FIELD_DESC = new org.apache.thrift.protocol.TField("userName", org.apache.thrift.protocol.TType.STRING, (short)3);
    private static final org.apache.thrift.protocol.TField EXP_NAME_FIELD_DESC = new org.apache.thrift.protocol.TField("expName", org.apache.thrift.protocol.TType.STRING, (short)4);
    private static final org.apache.thrift.protocol.TField LIMIT_FIELD_DESC = new org.apache.thrift.protocol.TField("limit", org.apache.thrift.protocol.TType.I32, (short)5);
    private static final org.apache.thrift.protocol.TField OFFSET_FIELD_DESC = new org.apache.thrift.protocol.TField("offset", org.apache.thrift.protocol.TType.I32, (short)6);

    private static final Map<Class<? extends IScheme>, SchemeFactory> schemes = new HashMap<Class<? extends IScheme>, SchemeFactory>();
    static {
      schemes.put(StandardScheme.class, new searchExperimentsByName_argsStandardSchemeFactory());
      schemes.put(TupleScheme.class, new searchExperimentsByName_argsTupleSchemeFactory());
    }

    public org.apache.airavata.model.security.AuthzToken authzToken; // required
    public String gatewayId; // required
    public String userName; // required
    public String expName; // required
    public int limit; // required
    public int offset; // required

    /** 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"),
      USER_NAME((short)3, "userName"),
      EXP_NAME((short)4, "expName"),
      LIMIT((short)5, "limit"),
      OFFSET((short)6, "offset");

      private static final Map<String, _Fields> byName = new HashMap<String, _Fields>();

      static {
        for (_Fields field : EnumSet.allOf(_Fields.class)) {
          byName.put(field.getFieldName(), field);
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, or null if its not found.
       */
      public static _Fields findByThriftId(int fieldId) {
        switch(fieldId) {
          case 1: // AUTHZ_TOKEN
            return AUTHZ_TOKEN;
          case 2: // GATEWAY_ID
            return GATEWAY_ID;
          case 3: // USER_NAME
            return USER_NAME;
          case 4: // EXP_NAME
            return EXP_NAME;
          case 5: // LIMIT
            return LIMIT;
          case 6: // OFFSET
            return OFFSET;
          default:
            return null;
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, throwing an exception
       * if it is not found.
       */
      public static _Fields findByThriftIdOrThrow(int fieldId) {
        _Fields fields = findByThriftId(fieldId);
        if (fields == null) throw new IllegalArgumentException("Field " + fieldId + " doesn't exist!");
        return fields;
      }

      /**
       * Find the _Fields constant that matches name, or null if its not found.
       */
      public static _Fields findByName(String name) {
        return byName.get(name);
      }

      private final short _thriftId;
      private final String _fieldName;

      _Fields(short thriftId, String fieldName) {
        _thriftId = thriftId;
        _fieldName = fieldName;
      }

      public short getThriftFieldId() {
        return _thriftId;
      }

      public String getFieldName() {
        return _fieldName;
      }
    }

    // isset id assignments
    private static final int __LIMIT_ISSET_ID = 0;
    private static final int __OFFSET_ISSET_ID = 1;
    private byte __isset_bitfield = 0;
    public static final Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
    static {
      Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new EnumMap<_Fields, org.apache.thrift.meta_data.FieldMetaData>(_Fields.class);
      tmpMap.put(_Fields.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)));
      tmpMap.put(_Fields.USER_NAME, new org.apache.thrift.meta_data.FieldMetaData("userName", org.apache.thrift.TFieldRequirementType.REQUIRED, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING)));
      tmpMap.put(_Fields.EXP_NAME, new org.apache.thrift.meta_data.FieldMetaData("expName", org.apache.thrift.TFieldRequirementType.REQUIRED, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING)));
      tmpMap.put(_Fields.LIMIT, new org.apache.thrift.meta_data.FieldMetaData("limit", org.apache.thrift.TFieldRequirementType.REQUIRED, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.I32)));
      tmpMap.put(_Fields.OFFSET, new org.apache.thrift.meta_data.FieldMetaData("offset", org.apache.thrift.TFieldRequirementType.REQUIRED, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.I32)));
      metaDataMap = Collections.unmodifiableMap(tmpMap);
      org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(searchExperimentsByName_args.class, metaDataMap);
    }

    public searchExperimentsByName_args() {
    }

    public searchExperimentsByName_args(
      org.apache.airavata.model.security.AuthzToken authzToken,
      String gatewayId,
      String userName,
      String expName,
      int limit,
      int offset)
    {
      this();
      this.authzToken = authzToken;
      this.gatewayId = gatewayId;
      this.userName = userName;
      this.expName = expName;
      this.limit = limit;
      setLimitIsSet(true);
      this.offset = offset;
      setOffsetIsSet(true);
    }

    /**
     * Performs a deep copy on <i>other</i>.
     */
    public searchExperimentsByName_args(searchExperimentsByName_args other) {
      __isset_bitfield = other.__isset_bitfield;
      if (other.isSetAuthzToken()) {
        this.authzToken = new org.apache.airavata.model.security.AuthzToken(other.authzToken);
      }
      if (other.isSetGatewayId()) {
        this.gatewayId = other.gatewayId;
      }
      if (other.isSetUserName()) {
        this.userName = other.userName;
      }
      if (other.isSetExpName()) {
        this.expName = other.expName;
      }
      this.limit = other.limit;
      this.offset = other.offset;
    }

    public searchExperimentsByName_args deepCopy() {
      return new searchExperimentsByName_args(this);
    }

    @Override
    public void clear() {
      this.authzToken = null;
      this.gatewayId = null;
      this.userName = null;
      this.expName = null;
      setLimitIsSet(false);
      this.limit = 0;
      setOffsetIsSet(false);
      this.offset = 0;
    }

    public org.apache.airavata.model.security.AuthzToken getAuthzToken() {
      return this.authzToken;
    }

    public searchExperimentsByName_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 String getGatewayId() {
      return this.gatewayId;
    }

    public searchExperimentsByName_args setGatewayId(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 String getUserName() {
      return this.userName;
    }

    public searchExperimentsByName_args setUserName(String userName) {
      this.userName = userName;
      return this;
    }

    public void unsetUserName() {
      this.userName = null;
    }

    /** Returns true if field userName is set (has been assigned a value) and false otherwise */
    public boolean isSetUserName() {
      return this.userName != null;
    }

    public void setUserNameIsSet(boolean value) {
      if (!value) {
        this.userName = null;
      }
    }

    public String getExpName() {
      return this.expName;
    }

    public searchExperimentsByName_args setExpName(String expName) {
      this.expName = expName;
      return this;
    }

    public void unsetExpName() {
      this.expName = null;
    }

    /** Returns true if field expName is set (has been assigned a value) and false otherwise */
    public boolean isSetExpName() {
      return this.expName != null;
    }

    public void setExpNameIsSet(boolean value) {
      if (!value) {
        this.expName = null;
      }
    }

    public int getLimit() {
      return this.limit;
    }

    public searchExperimentsByName_args setLimit(int limit) {
      this.limit = limit;
      setLimitIsSet(true);
      return this;
    }

    public void unsetLimit() {
      __isset_bitfield = EncodingUtils.clearBit(__isset_bitfield, __LIMIT_ISSET_ID);
    }

    /** Returns true if field limit is set (has been assigned a value) and false otherwise */
    public boolean isSetLimit() {
      return EncodingUtils.testBit(__isset_bitfield, __LIMIT_ISSET_ID);
    }

    public void setLimitIsSet(boolean value) {
      __isset_bitfield = EncodingUtils.setBit(__isset_bitfield, __LIMIT_ISSET_ID, value);
    }

    public int getOffset() {
      return this.offset;
    }

    public searchExperimentsByName_args setOffset(int offset) {
      this.offset = offset;
      setOffsetIsSet(true);
      return this;
    }

    public void unsetOffset() {
      __isset_bitfield = EncodingUtils.clearBit(__isset_bitfield, __OFFSET_ISSET_ID);
    }

    /** Returns true if field offset is set (has been assigned a value) and false otherwise */
    public boolean isSetOffset() {
      return EncodingUtils.testBit(__isset_bitfield, __OFFSET_ISSET_ID);
    }

    public void setOffsetIsSet(boolean value) {
      __isset_bitfield = EncodingUtils.setBit(__isset_bitfield, __OFFSET_ISSET_ID, value);
    }

    public void setFieldValue(_Fields field, 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((String)value);
        }
        break;

      case USER_NAME:
        if (value == null) {
          unsetUserName();
        } else {
          setUserName((String)value);
        }
        break;

      case EXP_NAME:
        if (value == null) {
          unsetExpName();
        } else {
          setExpName((String)value);
        }
        break;

      case LIMIT:
        if (value == null) {
          unsetLimit();
        } else {
          setLimit((Integer)value);
        }
        break;

      case OFFSET:
        if (value == null) {
          unsetOffset();
        } else {
          setOffset((Integer)value);
        }
        break;

      }
    }

    public Object getFieldValue(_Fields field) {
      switch (field) {
      case AUTHZ_TOKEN:
        return getAuthzToken();

      case GATEWAY_ID:
        return getGatewayId();

      case USER_NAME:
        return getUserName();

      case EXP_NAME:
        return getExpName();

      case LIMIT:
        return Integer.valueOf(getLimit());

      case OFFSET:
        return Integer.valueOf(getOffset());

      }
      throw new IllegalStateException();
    }

    /** Returns true if field corresponding to fieldID is set (has been assigned a value) and false otherwise */
    public boolean isSet(_Fields field) {
      if (field == null) {
        throw new IllegalArgumentException();
      }

      switch (field) {
      case AUTHZ_TOKEN:
        return isSetAuthzToken();
      case GATEWAY_ID:
        return isSetGatewayId();
      case USER_NAME:
        return isSetUserName();
      case EXP_NAME:
        return isSetExpName();
      case LIMIT:
        return isSetLimit();
      case OFFSET:
        return isSetOffset();
      }
      throw new IllegalStateException();
    }

    @Override
    public boolean equals(Object that) {
      if (that == null)
        return false;
      if (that instanceof searchExperimentsByName_args)
        return this.equals((searchExperimentsByName_args)that);
      return false;
    }

    public boolean equals(searchExperimentsByName_args that) {
      if (that == null)
        return false;

      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;
      }

      boolean this_present_userName = true && this.isSetUserName();
      boolean that_present_userName = true && that.isSetUserName();
      if (this_present_userName || that_present_userName) {
        if (!(this_present_userName && that_present_userName))
          return false;
        if (!this.userName.equals(that.userName))
          return false;
      }

      boolean this_present_expName = true && this.isSetExpName();
      boolean that_present_expName = true && that.isSetExpName();
      if (this_present_expName || that_present_expName) {
        if (!(this_present_expName && that_present_expName))
          return false;
        if (!this.expName.equals(that.expName))
          return false;
      }

      boolean this_present_limit = true;
      boolean that_present_limit = true;
      if (this_present_limit || that_present_limit) {
        if (!(this_present_limit && that_present_limit))
          return false;
        if (this.limit != that.limit)
          return false;
      }

      boolean this_present_offset = true;
      boolean that_present_offset = true;
      if (this_present_offset || that_present_offset) {
        if (!(this_present_offset && that_present_offset))
          return false;
        if (this.offset != that.offset)
          return false;
      }

      return true;
    }

    @Override
    public int hashCode() {
      List<Object> list = new ArrayList<Object>();

      boolean present_authzToken = true && (isSetAuthzToken());
      list.add(present_authzToken);
      if (present_authzToken)
        list.add(authzToken);

      boolean present_gatewayId = true && (isSetGatewayId());
      list.add(present_gatewayId);
      if (present_gatewayId)
        list.add(gatewayId);

      boolean present_userName = true && (isSetUserName());
      list.add(present_userName);
      if (present_userName)
        list.add(userName);

      boolean present_expName = true && (isSetExpName());
      list.add(present_expName);
      if (present_expName)
        list.add(expName);

      boolean present_limit = true;
      list.add(present_limit);
      if (present_limit)
        list.add(limit);

      boolean present_offset = true;
      list.add(present_offset);
      if (present_offset)
        list.add(offset);

      return list.hashCode();
    }

    @Override
    public int compareTo(searchExperimentsByName_args other) {
      if (!getClass().equals(other.getClass())) {
        return getClass().getName().compareTo(other.getClass().getName());
      }

      int lastComparison = 0;

      lastComparison = 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 = 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;
        }
      }
      lastComparison = Boolean.valueOf(isSetUserName()).compareTo(other.isSetUserName());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetUserName()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.userName, other.userName);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = Boolean.valueOf(isSetExpName()).compareTo(other.isSetExpName());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetExpName()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.expName, other.expName);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = Boolean.valueOf(isSetLimit()).compareTo(other.isSetLimit());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetLimit()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.limit, other.limit);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = Boolean.valueOf(isSetOffset()).compareTo(other.isSetOffset());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetOffset()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.offset, other.offset);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      return 0;
    }

    public _Fields fieldForId(int fieldId) {
      return _Fields.findByThriftId(fieldId);
    }

    public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
      schemes.get(iprot.getScheme()).getScheme().read(iprot, this);
    }

    public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException {
      schemes.get(oprot.getScheme()).getScheme().write(oprot, this);
    }

    @Override
    public String toString() {
      StringBuilder sb = new StringBuilder("searchExperimentsByName_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;
      if (!first) sb.append(", ");
      sb.append("userName:");
      if (this.userName == null) {
        sb.append("null");
      } else {
        sb.append(this.userName);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("expName:");
      if (this.expName == null) {
        sb.append("null");
      } else {
        sb.append(this.expName);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("limit:");
      sb.append(this.limit);
      first = false;
      if (!first) sb.append(", ");
      sb.append("offset:");
      sb.append(this.offset);
      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());
      }
      if (userName == null) {
        throw new org.apache.thrift.protocol.TProtocolException("Required field 'userName' was not present! Struct: " + toString());
      }
      if (expName == null) {
        throw new org.apache.thrift.protocol.TProtocolException("Required field 'expName' was not present! Struct: " + toString());
      }
      // alas, we cannot check 'limit' because it's a primitive and you chose the non-beans generator.
      // alas, we cannot check 'offset' because it's a primitive and you chose the non-beans generator.
      // 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, 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 searchExperimentsByName_argsStandardSchemeFactory implements SchemeFactory {
      public searchExperimentsByName_argsStandardScheme getScheme() {
        return new searchExperimentsByName_argsStandardScheme();
      }
    }

    private static class searchExperimentsByName_argsStandardScheme extends StandardScheme<searchExperimentsByName_args> {

      public void read(org.apache.thrift.protocol.TProtocol iprot, searchExperimentsByName_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;
            case 3: // USER_NAME
              if (schemeField.type == org.apache.thrift.protocol.TType.STRING) {
                struct.userName = iprot.readString();
                struct.setUserNameIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 4: // EXP_NAME
              if (schemeField.type == org.apache.thrift.protocol.TType.STRING) {
                struct.expName = iprot.readString();
                struct.setExpNameIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 5: // LIMIT
              if (schemeField.type == org.apache.thrift.protocol.TType.I32) {
                struct.limit = iprot.readI32();
                struct.setLimitIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 6: // OFFSET
              if (schemeField.type == org.apache.thrift.protocol.TType.I32) {
                struct.offset = iprot.readI32();
                struct.setOffsetIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            default:
              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
          }
          iprot.readFieldEnd();
        }
        iprot.readStructEnd();

        // check for required fields of primitive type, which can't be checked in the validate method
        if (!struct.isSetLimit()) {
          throw new org.apache.thrift.protocol.TProtocolException("Required field 'limit' was not found in serialized data! Struct: " + toString());
        }
        if (!struct.isSetOffset()) {
          throw new org.apache.thrift.protocol.TProtocolException("Required field 'offset' was not found in serialized data! Struct: " + toString());
        }
        struct.validate();
      }

      public void write(org.apache.thrift.protocol.TProtocol oprot, searchExperimentsByName_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();
        }
        if (struct.userName != null) {
          oprot.writeFieldBegin(USER_NAME_FIELD_DESC);
          oprot.writeString(struct.userName);
          oprot.writeFieldEnd();
        }
        if (struct.expName != null) {
          oprot.writeFieldBegin(EXP_NAME_FIELD_DESC);
          oprot.writeString(struct.expName);
          oprot.writeFieldEnd();
        }
        oprot.writeFieldBegin(LIMIT_FIELD_DESC);
        oprot.writeI32(struct.limit);
        oprot.writeFieldEnd();
        oprot.writeFieldBegin(OFFSET_FIELD_DESC);
        oprot.writeI32(struct.offset);
        oprot.writeFieldEnd();
        oprot.writeFieldStop();
        oprot.writeStructEnd();
      }

    }

    private static class searchExperimentsByName_argsTupleSchemeFactory implements SchemeFactory {
      public searchExperimentsByName_argsTupleScheme getScheme() {
        return new searchExperimentsByName_argsTupleScheme();
      }
    }

    private static class searchExperimentsByName_argsTupleScheme extends TupleScheme<searchExperimentsByName_args> {

      @Override
      public void write(org.apache.thrift.protocol.TProtocol prot, searchExperimentsByName_args struct) throws org.apache.thrift.TException {
        TTupleProtocol oprot = (TTupleProtocol) prot;
        struct.authzToken.write(oprot);
        oprot.writeString(struct.gatewayId);
        oprot.writeString(struct.userName);
        oprot.writeString(struct.expName);
        oprot.writeI32(struct.limit);
        oprot.writeI32(struct.offset);
      }

      @Override
      public void read(org.apache.thrift.protocol.TProtocol prot, searchExperimentsByName_args struct) throws org.apache.thrift.TException {
        TTupleProtocol iprot = (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);
        struct.userName = iprot.readString();
        struct.setUserNameIsSet(true);
        struct.expName = iprot.readString();
        struct.setExpNameIsSet(true);
        struct.limit = iprot.readI32();
        struct.setLimitIsSet(true);
        struct.offset = iprot.readI32();
        struct.setOffsetIsSet(true);
      }
    }

  }

  public static class searchExperimentsByName_result implements org.apache.thrift.TBase<searchExperimentsByName_result, searchExperimentsByName_result._Fields>, java.io.Serializable, Cloneable, Comparable<searchExperimentsByName_result>   {
    private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("searchExperimentsByName_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 IRE_FIELD_DESC = new org.apache.thrift.protocol.TField("ire", org.apache.thrift.protocol.TType.STRUCT, (short)1);
    private static final org.apache.thrift.protocol.TField ACE_FIELD_DESC = new org.apache.thrift.protocol.TField("ace", org.apache.thrift.protocol.TType.STRUCT, (short)2);
    private static final org.apache.thrift.protocol.TField ASE_FIELD_DESC = new org.apache.thrift.protocol.TField("ase", org.apache.thrift.protocol.TType.STRUCT, (short)3);
    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)4);

    private static final Map<Class<? extends IScheme>, SchemeFactory> schemes = new HashMap<Class<? extends IScheme>, SchemeFactory>();
    static {
      schemes.put(StandardScheme.class, new searchExperimentsByName_resultStandardSchemeFactory());
      schemes.put(TupleScheme.class, new searchExperimentsByName_resultTupleSchemeFactory());
    }

    public List<org.apache.airavata.model.experiment.ExperimentSummaryModel> success; // required
    public org.apache.airavata.model.error.InvalidRequestException ire; // required
    public org.apache.airavata.model.error.AiravataClientException ace; // required
    public org.apache.airavata.model.error.AiravataSystemException ase; // 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"),
      IRE((short)1, "ire"),
      ACE((short)2, "ace"),
      ASE((short)3, "ase"),
      AE((short)4, "ae");

      private static final Map<String, _Fields> byName = new HashMap<String, _Fields>();

      static {
        for (_Fields field : EnumSet.allOf(_Fields.class)) {
          byName.put(field.getFieldName(), field);
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, or null if its not found.
       */
      public static _Fields findByThriftId(int fieldId) {
        switch(fieldId) {
          case 0: // SUCCESS
            return SUCCESS;
          case 1: // IRE
            return IRE;
          case 2: // ACE
            return ACE;
          case 3: // ASE
            return ASE;
          case 4: // 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 IllegalArgumentException("Field " + fieldId + " doesn't exist!");
        return fields;
      }

      /**
       * Find the _Fields constant that matches name, or null if its not found.
       */
      public static _Fields findByName(String name) {
        return byName.get(name);
      }

      private final short _thriftId;
      private final String _fieldName;

      _Fields(short thriftId, String fieldName) {
        _thriftId = thriftId;
        _fieldName = fieldName;
      }

      public short getThriftFieldId() {
        return _thriftId;
      }

      public String getFieldName() {
        return _fieldName;
      }
    }

    // isset id assignments
    public static final Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
    static {
      Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new EnumMap<_Fields, org.apache.thrift.meta_data.FieldMetaData>(_Fields.class);
      tmpMap.put(_Fields.SUCCESS, new org.apache.thrift.meta_data.FieldMetaData("success", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.ListMetaData(org.apache.thrift.protocol.TType.LIST, 
              new org.apache.thrift.meta_data.StructMetaData(org.apache.thrift.protocol.TType.STRUCT, org.apache.airavata.model.experiment.ExperimentSummaryModel.class))));
      tmpMap.put(_Fields.IRE, new org.apache.thrift.meta_data.FieldMetaData("ire", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRUCT)));
      tmpMap.put(_Fields.ACE, new org.apache.thrift.meta_data.FieldMetaData("ace", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRUCT)));
      tmpMap.put(_Fields.ASE, new org.apache.thrift.meta_data.FieldMetaData("ase", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRUCT)));
      tmpMap.put(_Fields.AE, new org.apache.thrift.meta_data.FieldMetaData("ae", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRUCT)));
      metaDataMap = Collections.unmodifiableMap(tmpMap);
      org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(searchExperimentsByName_result.class, metaDataMap);
    }

    public searchExperimentsByName_result() {
    }

    public searchExperimentsByName_result(
      List<org.apache.airavata.model.experiment.ExperimentSummaryModel> success,
      org.apache.airavata.model.error.InvalidRequestException ire,
      org.apache.airavata.model.error.AiravataClientException ace,
      org.apache.airavata.model.error.AiravataSystemException ase,
      org.apache.airavata.model.error.AuthorizationException ae)
    {
      this();
      this.success = success;
      this.ire = ire;
      this.ace = ace;
      this.ase = ase;
      this.ae = ae;
    }

    /**
     * Performs a deep copy on <i>other</i>.
     */
    public searchExperimentsByName_result(searchExperimentsByName_result other) {
      if (other.isSetSuccess()) {
        List<org.apache.airavata.model.experiment.ExperimentSummaryModel> __this__success = new ArrayList<org.apache.airavata.model.experiment.ExperimentSummaryModel>(other.success.size());
        for (org.apache.airavata.model.experiment.ExperimentSummaryModel other_element : other.success) {
          __this__success.add(new org.apache.airavata.model.experiment.ExperimentSummaryModel(other_element));
        }
        this.success = __this__success;
      }
      if (other.isSetIre()) {
        this.ire = new org.apache.airavata.model.error.InvalidRequestException(other.ire);
      }
      if (other.isSetAce()) {
        this.ace = new org.apache.airavata.model.error.AiravataClientException(other.ace);
      }
      if (other.isSetAse()) {
        this.ase = new org.apache.airavata.model.error.AiravataSystemException(other.ase);
      }
      if (other.isSetAe()) {
        this.ae = new org.apache.airavata.model.error.AuthorizationException(other.ae);
      }
    }

    public searchExperimentsByName_result deepCopy() {
      return new searchExperimentsByName_result(this);
    }

    @Override
    public void clear() {
      this.success = null;
      this.ire = null;
      this.ace = null;
      this.ase = null;
      this.ae = null;
    }

    public int getSuccessSize() {
      return (this.success == null) ? 0 : this.success.size();
    }

    public java.util.Iterator<org.apache.airavata.model.experiment.ExperimentSummaryModel> getSuccessIterator() {
      return (this.success == null) ? null : this.success.iterator();
    }

    public void addToSuccess(org.apache.airavata.model.experiment.ExperimentSummaryModel elem) {
      if (this.success == null) {
        this.success = new ArrayList<org.apache.airavata.model.experiment.ExperimentSummaryModel>();
      }
      this.success.add(elem);
    }

    public List<org.apache.airavata.model.experiment.ExperimentSummaryModel> getSuccess() {
      return this.success;
    }

    public searchExperimentsByName_result setSuccess(List<org.apache.airavata.model.experiment.ExperimentSummaryModel> 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.model.error.InvalidRequestException getIre() {
      return this.ire;
    }

    public searchExperimentsByName_result setIre(org.apache.airavata.model.error.InvalidRequestException ire) {
      this.ire = ire;
      return this;
    }

    public void unsetIre() {
      this.ire = null;
    }

    /** Returns true if field ire is set (has been assigned a value) and false otherwise */
    public boolean isSetIre() {
      return this.ire != null;
    }

    public void setIreIsSet(boolean value) {
      if (!value) {
        this.ire = null;
      }
    }

    public org.apache.airavata.model.error.AiravataClientException getAce() {
      return this.ace;
    }

    public searchExperimentsByName_result setAce(org.apache.airavata.model.error.AiravataClientException ace) {
      this.ace = ace;
      return this;
    }

    public void unsetAce() {
      this.ace = null;
    }

    /** Returns true if field ace is set (has been assigned a value) and false otherwise */
    public boolean isSetAce() {
      return this.ace != null;
    }

    public void setAceIsSet(boolean value) {
      if (!value) {
        this.ace = null;
      }
    }

    public org.apache.airavata.model.error.AiravataSystemException getAse() {
      return this.ase;
    }

    public searchExperimentsByName_result setAse(org.apache.airavata.model.error.AiravataSystemException ase) {
      this.ase = ase;
      return this;
    }

    public void unsetAse() {
      this.ase = null;
    }

    /** Returns true if field ase is set (has been assigned a value) and false otherwise */
    public boolean isSetAse() {
      return this.ase != null;
    }

    public void setAseIsSet(boolean value) {
      if (!value) {
        this.ase = null;
      }
    }

    public org.apache.airavata.model.error.AuthorizationException getAe() {
      return this.ae;
    }

    public searchExperimentsByName_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, Object value) {
      switch (field) {
      case SUCCESS:
        if (value == null) {
          unsetSuccess();
        } else {
          setSuccess((List<org.apache.airavata.model.experiment.ExperimentSummaryModel>)value);
        }
        break;

      case IRE:
        if (value == null) {
          unsetIre();
        } else {
          setIre((org.apache.airavata.model.error.InvalidRequestException)value);
        }
        break;

      case ACE:
        if (value == null) {
          unsetAce();
        } else {
          setAce((org.apache.airavata.model.error.AiravataClientException)value);
        }
        break;

      case ASE:
        if (value == null) {
          unsetAse();
        } else {
          setAse((org.apache.airavata.model.error.AiravataSystemException)value);
        }
        break;

      case AE:
        if (value == null) {
          unsetAe();
        } else {
          setAe((org.apache.airavata.model.error.AuthorizationException)value);
        }
        break;

      }
    }

    public Object getFieldValue(_Fields field) {
      switch (field) {
      case SUCCESS:
        return getSuccess();

      case IRE:
        return getIre();

      case ACE:
        return getAce();

      case ASE:
        return getAse();

      case AE:
        return getAe();

      }
      throw new IllegalStateException();
    }

    /** Returns true if field corresponding to fieldID is set (has been assigned a value) and false otherwise */
    public boolean isSet(_Fields field) {
      if (field == null) {
        throw new IllegalArgumentException();
      }

      switch (field) {
      case SUCCESS:
        return isSetSuccess();
      case IRE:
        return isSetIre();
      case ACE:
        return isSetAce();
      case ASE:
        return isSetAse();
      case AE:
        return isSetAe();
      }
      throw new IllegalStateException();
    }

    @Override
    public boolean equals(Object that) {
      if (that == null)
        return false;
      if (that instanceof searchExperimentsByName_result)
        return this.equals((searchExperimentsByName_result)that);
      return false;
    }

    public boolean equals(searchExperimentsByName_result that) {
      if (that == null)
        return false;

      boolean this_present_success = true && this.isSetSuccess();
      boolean that_present_success = true && that.isSetSuccess();
      if (this_present_success || that_present_success) {
        if (!(this_present_success && that_present_success))
          return false;
        if (!this.success.equals(that.success))
          return false;
      }

      boolean this_present_ire = true && this.isSetIre();
      boolean that_present_ire = true && that.isSetIre();
      if (this_present_ire || that_present_ire) {
        if (!(this_present_ire && that_present_ire))
          return false;
        if (!this.ire.equals(that.ire))
          return false;
      }

      boolean this_present_ace = true && this.isSetAce();
      boolean that_present_ace = true && that.isSetAce();
      if (this_present_ace || that_present_ace) {
        if (!(this_present_ace && that_present_ace))
          return false;
        if (!this.ace.equals(that.ace))
          return false;
      }

      boolean this_present_ase = true && this.isSetAse();
      boolean that_present_ase = true && that.isSetAse();
      if (this_present_ase || that_present_ase) {
        if (!(this_present_ase && that_present_ase))
          return false;
        if (!this.ase.equals(that.ase))
          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() {
      List<Object> list = new ArrayList<Object>();

      boolean present_success = true && (isSetSuccess());
      list.add(present_success);
      if (present_success)
        list.add(success);

      boolean present_ire = true && (isSetIre());
      list.add(present_ire);
      if (present_ire)
        list.add(ire);

      boolean present_ace = true && (isSetAce());
      list.add(present_ace);
      if (present_ace)
        list.add(ace);

      boolean present_ase = true && (isSetAse());
      list.add(present_ase);
      if (present_ase)
        list.add(ase);

      boolean present_ae = true && (isSetAe());
      list.add(present_ae);
      if (present_ae)
        list.add(ae);

      return list.hashCode();
    }

    @Override
    public int compareTo(searchExperimentsByName_result other) {
      if (!getClass().equals(other.getClass())) {
        return getClass().getName().compareTo(other.getClass().getName());
      }

      int lastComparison = 0;

      lastComparison = Boolean.valueOf(isSetSuccess()).compareTo(other.isSetSuccess());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetSuccess()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.success, other.success);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = Boolean.valueOf(isSetIre()).compareTo(other.isSetIre());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetIre()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.ire, other.ire);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = Boolean.valueOf(isSetAce()).compareTo(other.isSetAce());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetAce()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.ace, other.ace);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = Boolean.valueOf(isSetAse()).compareTo(other.isSetAse());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetAse()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.ase, other.ase);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = 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 {
      schemes.get(iprot.getScheme()).getScheme().read(iprot, this);
    }

    public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException {
      schemes.get(oprot.getScheme()).getScheme().write(oprot, this);
      }

    @Override
    public String toString() {
      StringBuilder sb = new StringBuilder("searchExperimentsByName_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("ire:");
      if (this.ire == null) {
        sb.append("null");
      } else {
        sb.append(this.ire);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("ace:");
      if (this.ace == null) {
        sb.append("null");
      } else {
        sb.append(this.ace);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("ase:");
      if (this.ase == null) {
        sb.append("null");
      } else {
        sb.append(this.ase);
      }
      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, 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 searchExperimentsByName_resultStandardSchemeFactory implements SchemeFactory {
      public searchExperimentsByName_resultStandardScheme getScheme() {
        return new searchExperimentsByName_resultStandardScheme();
      }
    }

    private static class searchExperimentsByName_resultStandardScheme extends StandardScheme<searchExperimentsByName_result> {

      public void read(org.apache.thrift.protocol.TProtocol iprot, searchExperimentsByName_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 _list42 = iprot.readListBegin();
                  struct.success = new ArrayList<org.apache.airavata.model.experiment.ExperimentSummaryModel>(_list42.size);
                  org.apache.airavata.model.experiment.ExperimentSummaryModel _elem43;
                  for (int _i44 = 0; _i44 < _list42.size; ++_i44)
                  {
                    _elem43 = new org.apache.airavata.model.experiment.ExperimentSummaryModel();
                    _elem43.read(iprot);
                    struct.success.add(_elem43);
                  }
                  iprot.readListEnd();
                }
                struct.setSuccessIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 1: // IRE
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.ire = new org.apache.airavata.model.error.InvalidRequestException();
                struct.ire.read(iprot);
                struct.setIreIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 2: // ACE
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.ace = new org.apache.airavata.model.error.AiravataClientException();
                struct.ace.read(iprot);
                struct.setAceIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 3: // ASE
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.ase = new org.apache.airavata.model.error.AiravataSystemException();
                struct.ase.read(iprot);
                struct.setAseIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 4: // 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, searchExperimentsByName_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.experiment.ExperimentSummaryModel _iter45 : struct.success)
            {
              _iter45.write(oprot);
            }
            oprot.writeListEnd();
          }
          oprot.writeFieldEnd();
        }
        if (struct.ire != null) {
          oprot.writeFieldBegin(IRE_FIELD_DESC);
          struct.ire.write(oprot);
          oprot.writeFieldEnd();
        }
        if (struct.ace != null) {
          oprot.writeFieldBegin(ACE_FIELD_DESC);
          struct.ace.write(oprot);
          oprot.writeFieldEnd();
        }
        if (struct.ase != null) {
          oprot.writeFieldBegin(ASE_FIELD_DESC);
          struct.ase.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 searchExperimentsByName_resultTupleSchemeFactory implements SchemeFactory {
      public searchExperimentsByName_resultTupleScheme getScheme() {
        return new searchExperimentsByName_resultTupleScheme();
      }
    }

    private static class searchExperimentsByName_resultTupleScheme extends TupleScheme<searchExperimentsByName_result> {

      @Override
      public void write(org.apache.thrift.protocol.TProtocol prot, searchExperimentsByName_result struct) throws org.apache.thrift.TException {
        TTupleProtocol oprot = (TTupleProtocol) prot;
        BitSet optionals = new BitSet();
        if (struct.isSetSuccess()) {
          optionals.set(0);
        }
        if (struct.isSetIre()) {
          optionals.set(1);
        }
        if (struct.isSetAce()) {
          optionals.set(2);
        }
        if (struct.isSetAse()) {
          optionals.set(3);
        }
        if (struct.isSetAe()) {
          optionals.set(4);
        }
        oprot.writeBitSet(optionals, 5);
        if (struct.isSetSuccess()) {
          {
            oprot.writeI32(struct.success.size());
            for (org.apache.airavata.model.experiment.ExperimentSummaryModel _iter46 : struct.success)
            {
              _iter46.write(oprot);
            }
          }
        }
        if (struct.isSetIre()) {
          struct.ire.write(oprot);
        }
        if (struct.isSetAce()) {
          struct.ace.write(oprot);
        }
        if (struct.isSetAse()) {
          struct.ase.write(oprot);
        }
        if (struct.isSetAe()) {
          struct.ae.write(oprot);
        }
      }

      @Override
      public void read(org.apache.thrift.protocol.TProtocol prot, searchExperimentsByName_result struct) throws org.apache.thrift.TException {
        TTupleProtocol iprot = (TTupleProtocol) prot;
        BitSet incoming = iprot.readBitSet(5);
        if (incoming.get(0)) {
          {
            org.apache.thrift.protocol.TList _list47 = new org.apache.thrift.protocol.TList(org.apache.thrift.protocol.TType.STRUCT, iprot.readI32());
            struct.success = new ArrayList<org.apache.airavata.model.experiment.ExperimentSummaryModel>(_list47.size);
            org.apache.airavata.model.experiment.ExperimentSummaryModel _elem48;
            for (int _i49 = 0; _i49 < _list47.size; ++_i49)
            {
              _elem48 = new org.apache.airavata.model.experiment.ExperimentSummaryModel();
              _elem48.read(iprot);
              struct.success.add(_elem48);
            }
          }
          struct.setSuccessIsSet(true);
        }
        if (incoming.get(1)) {
          struct.ire = new org.apache.airavata.model.error.InvalidRequestException();
          struct.ire.read(iprot);
          struct.setIreIsSet(true);
        }
        if (incoming.get(2)) {
          struct.ace = new org.apache.airavata.model.error.AiravataClientException();
          struct.ace.read(iprot);
          struct.setAceIsSet(true);
        }
        if (incoming.get(3)) {
          struct.ase = new org.apache.airavata.model.error.AiravataSystemException();
          struct.ase.read(iprot);
          struct.setAseIsSet(true);
        }
        if (incoming.get(4)) {
          struct.ae = new org.apache.airavata.model.error.AuthorizationException();
          struct.ae.read(iprot);
          struct.setAeIsSet(true);
        }
      }
    }

  }

  public static class searchExperimentsByDesc_args implements org.apache.thrift.TBase<searchExperimentsByDesc_args, searchExperimentsByDesc_args._Fields>, java.io.Serializable, Cloneable, Comparable<searchExperimentsByDesc_args>   {
    private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("searchExperimentsByDesc_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.protocol.TField USER_NAME_FIELD_DESC = new org.apache.thrift.protocol.TField("userName", org.apache.thrift.protocol.TType.STRING, (short)3);
    private static final org.apache.thrift.protocol.TField DESCRIPTION_FIELD_DESC = new org.apache.thrift.protocol.TField("description", org.apache.thrift.protocol.TType.STRING, (short)4);
    private static final org.apache.thrift.protocol.TField LIMIT_FIELD_DESC = new org.apache.thrift.protocol.TField("limit", org.apache.thrift.protocol.TType.I32, (short)5);
    private static final org.apache.thrift.protocol.TField OFFSET_FIELD_DESC = new org.apache.thrift.protocol.TField("offset", org.apache.thrift.protocol.TType.I32, (short)6);

    private static final Map<Class<? extends IScheme>, SchemeFactory> schemes = new HashMap<Class<? extends IScheme>, SchemeFactory>();
    static {
      schemes.put(StandardScheme.class, new searchExperimentsByDesc_argsStandardSchemeFactory());
      schemes.put(TupleScheme.class, new searchExperimentsByDesc_argsTupleSchemeFactory());
    }

    public org.apache.airavata.model.security.AuthzToken authzToken; // required
    public String gatewayId; // required
    public String userName; // required
    public String description; // required
    public int limit; // required
    public int offset; // required

    /** 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"),
      USER_NAME((short)3, "userName"),
      DESCRIPTION((short)4, "description"),
      LIMIT((short)5, "limit"),
      OFFSET((short)6, "offset");

      private static final Map<String, _Fields> byName = new HashMap<String, _Fields>();

      static {
        for (_Fields field : EnumSet.allOf(_Fields.class)) {
          byName.put(field.getFieldName(), field);
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, or null if its not found.
       */
      public static _Fields findByThriftId(int fieldId) {
        switch(fieldId) {
          case 1: // AUTHZ_TOKEN
            return AUTHZ_TOKEN;
          case 2: // GATEWAY_ID
            return GATEWAY_ID;
          case 3: // USER_NAME
            return USER_NAME;
          case 4: // DESCRIPTION
            return DESCRIPTION;
          case 5: // LIMIT
            return LIMIT;
          case 6: // OFFSET
            return OFFSET;
          default:
            return null;
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, throwing an exception
       * if it is not found.
       */
      public static _Fields findByThriftIdOrThrow(int fieldId) {
        _Fields fields = findByThriftId(fieldId);
        if (fields == null) throw new IllegalArgumentException("Field " + fieldId + " doesn't exist!");
        return fields;
      }

      /**
       * Find the _Fields constant that matches name, or null if its not found.
       */
      public static _Fields findByName(String name) {
        return byName.get(name);
      }

      private final short _thriftId;
      private final String _fieldName;

      _Fields(short thriftId, String fieldName) {
        _thriftId = thriftId;
        _fieldName = fieldName;
      }

      public short getThriftFieldId() {
        return _thriftId;
      }

      public String getFieldName() {
        return _fieldName;
      }
    }

    // isset id assignments
    private static final int __LIMIT_ISSET_ID = 0;
    private static final int __OFFSET_ISSET_ID = 1;
    private byte __isset_bitfield = 0;
    public static final Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
    static {
      Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new EnumMap<_Fields, org.apache.thrift.meta_data.FieldMetaData>(_Fields.class);
      tmpMap.put(_Fields.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)));
      tmpMap.put(_Fields.USER_NAME, new org.apache.thrift.meta_data.FieldMetaData("userName", org.apache.thrift.TFieldRequirementType.REQUIRED, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING)));
      tmpMap.put(_Fields.DESCRIPTION, new org.apache.thrift.meta_data.FieldMetaData("description", org.apache.thrift.TFieldRequirementType.REQUIRED, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING)));
      tmpMap.put(_Fields.LIMIT, new org.apache.thrift.meta_data.FieldMetaData("limit", org.apache.thrift.TFieldRequirementType.REQUIRED, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.I32)));
      tmpMap.put(_Fields.OFFSET, new org.apache.thrift.meta_data.FieldMetaData("offset", org.apache.thrift.TFieldRequirementType.REQUIRED, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.I32)));
      metaDataMap = Collections.unmodifiableMap(tmpMap);
      org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(searchExperimentsByDesc_args.class, metaDataMap);
    }

    public searchExperimentsByDesc_args() {
    }

    public searchExperimentsByDesc_args(
      org.apache.airavata.model.security.AuthzToken authzToken,
      String gatewayId,
      String userName,
      String description,
      int limit,
      int offset)
    {
      this();
      this.authzToken = authzToken;
      this.gatewayId = gatewayId;
      this.userName = userName;
      this.description = description;
      this.limit = limit;
      setLimitIsSet(true);
      this.offset = offset;
      setOffsetIsSet(true);
    }

    /**
     * Performs a deep copy on <i>other</i>.
     */
    public searchExperimentsByDesc_args(searchExperimentsByDesc_args other) {
      __isset_bitfield = other.__isset_bitfield;
      if (other.isSetAuthzToken()) {
        this.authzToken = new org.apache.airavata.model.security.AuthzToken(other.authzToken);
      }
      if (other.isSetGatewayId()) {
        this.gatewayId = other.gatewayId;
      }
      if (other.isSetUserName()) {
        this.userName = other.userName;
      }
      if (other.isSetDescription()) {
        this.description = other.description;
      }
      this.limit = other.limit;
      this.offset = other.offset;
    }

    public searchExperimentsByDesc_args deepCopy() {
      return new searchExperimentsByDesc_args(this);
    }

    @Override
    public void clear() {
      this.authzToken = null;
      this.gatewayId = null;
      this.userName = null;
      this.description = null;
      setLimitIsSet(false);
      this.limit = 0;
      setOffsetIsSet(false);
      this.offset = 0;
    }

    public org.apache.airavata.model.security.AuthzToken getAuthzToken() {
      return this.authzToken;
    }

    public searchExperimentsByDesc_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 String getGatewayId() {
      return this.gatewayId;
    }

    public searchExperimentsByDesc_args setGatewayId(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 String getUserName() {
      return this.userName;
    }

    public searchExperimentsByDesc_args setUserName(String userName) {
      this.userName = userName;
      return this;
    }

    public void unsetUserName() {
      this.userName = null;
    }

    /** Returns true if field userName is set (has been assigned a value) and false otherwise */
    public boolean isSetUserName() {
      return this.userName != null;
    }

    public void setUserNameIsSet(boolean value) {
      if (!value) {
        this.userName = null;
      }
    }

    public String getDescription() {
      return this.description;
    }

    public searchExperimentsByDesc_args setDescription(String description) {
      this.description = description;
      return this;
    }

    public void unsetDescription() {
      this.description = null;
    }

    /** Returns true if field description is set (has been assigned a value) and false otherwise */
    public boolean isSetDescription() {
      return this.description != null;
    }

    public void setDescriptionIsSet(boolean value) {
      if (!value) {
        this.description = null;
      }
    }

    public int getLimit() {
      return this.limit;
    }

    public searchExperimentsByDesc_args setLimit(int limit) {
      this.limit = limit;
      setLimitIsSet(true);
      return this;
    }

    public void unsetLimit() {
      __isset_bitfield = EncodingUtils.clearBit(__isset_bitfield, __LIMIT_ISSET_ID);
    }

    /** Returns true if field limit is set (has been assigned a value) and false otherwise */
    public boolean isSetLimit() {
      return EncodingUtils.testBit(__isset_bitfield, __LIMIT_ISSET_ID);
    }

    public void setLimitIsSet(boolean value) {
      __isset_bitfield = EncodingUtils.setBit(__isset_bitfield, __LIMIT_ISSET_ID, value);
    }

    public int getOffset() {
      return this.offset;
    }

    public searchExperimentsByDesc_args setOffset(int offset) {
      this.offset = offset;
      setOffsetIsSet(true);
      return this;
    }

    public void unsetOffset() {
      __isset_bitfield = EncodingUtils.clearBit(__isset_bitfield, __OFFSET_ISSET_ID);
    }

    /** Returns true if field offset is set (has been assigned a value) and false otherwise */
    public boolean isSetOffset() {
      return EncodingUtils.testBit(__isset_bitfield, __OFFSET_ISSET_ID);
    }

    public void setOffsetIsSet(boolean value) {
      __isset_bitfield = EncodingUtils.setBit(__isset_bitfield, __OFFSET_ISSET_ID, value);
    }

    public void setFieldValue(_Fields field, 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((String)value);
        }
        break;

      case USER_NAME:
        if (value == null) {
          unsetUserName();
        } else {
          setUserName((String)value);
        }
        break;

      case DESCRIPTION:
        if (value == null) {
          unsetDescription();
        } else {
          setDescription((String)value);
        }
        break;

      case LIMIT:
        if (value == null) {
          unsetLimit();
        } else {
          setLimit((Integer)value);
        }
        break;

      case OFFSET:
        if (value == null) {
          unsetOffset();
        } else {
          setOffset((Integer)value);
        }
        break;

      }
    }

    public Object getFieldValue(_Fields field) {
      switch (field) {
      case AUTHZ_TOKEN:
        return getAuthzToken();

      case GATEWAY_ID:
        return getGatewayId();

      case USER_NAME:
        return getUserName();

      case DESCRIPTION:
        return getDescription();

      case LIMIT:
        return Integer.valueOf(getLimit());

      case OFFSET:
        return Integer.valueOf(getOffset());

      }
      throw new IllegalStateException();
    }

    /** Returns true if field corresponding to fieldID is set (has been assigned a value) and false otherwise */
    public boolean isSet(_Fields field) {
      if (field == null) {
        throw new IllegalArgumentException();
      }

      switch (field) {
      case AUTHZ_TOKEN:
        return isSetAuthzToken();
      case GATEWAY_ID:
        return isSetGatewayId();
      case USER_NAME:
        return isSetUserName();
      case DESCRIPTION:
        return isSetDescription();
      case LIMIT:
        return isSetLimit();
      case OFFSET:
        return isSetOffset();
      }
      throw new IllegalStateException();
    }

    @Override
    public boolean equals(Object that) {
      if (that == null)
        return false;
      if (that instanceof searchExperimentsByDesc_args)
        return this.equals((searchExperimentsByDesc_args)that);
      return false;
    }

    public boolean equals(searchExperimentsByDesc_args that) {
      if (that == null)
        return false;

      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;
      }

      boolean this_present_userName = true && this.isSetUserName();
      boolean that_present_userName = true && that.isSetUserName();
      if (this_present_userName || that_present_userName) {
        if (!(this_present_userName && that_present_userName))
          return false;
        if (!this.userName.equals(that.userName))
          return false;
      }

      boolean this_present_description = true && this.isSetDescription();
      boolean that_present_description = true && that.isSetDescription();
      if (this_present_description || that_present_description) {
        if (!(this_present_description && that_present_description))
          return false;
        if (!this.description.equals(that.description))
          return false;
      }

      boolean this_present_limit = true;
      boolean that_present_limit = true;
      if (this_present_limit || that_present_limit) {
        if (!(this_present_limit && that_present_limit))
          return false;
        if (this.limit != that.limit)
          return false;
      }

      boolean this_present_offset = true;
      boolean that_present_offset = true;
      if (this_present_offset || that_present_offset) {
        if (!(this_present_offset && that_present_offset))
          return false;
        if (this.offset != that.offset)
          return false;
      }

      return true;
    }

    @Override
    public int hashCode() {
      List<Object> list = new ArrayList<Object>();

      boolean present_authzToken = true && (isSetAuthzToken());
      list.add(present_authzToken);
      if (present_authzToken)
        list.add(authzToken);

      boolean present_gatewayId = true && (isSetGatewayId());
      list.add(present_gatewayId);
      if (present_gatewayId)
        list.add(gatewayId);

      boolean present_userName = true && (isSetUserName());
      list.add(present_userName);
      if (present_userName)
        list.add(userName);

      boolean present_description = true && (isSetDescription());
      list.add(present_description);
      if (present_description)
        list.add(description);

      boolean present_limit = true;
      list.add(present_limit);
      if (present_limit)
        list.add(limit);

      boolean present_offset = true;
      list.add(present_offset);
      if (present_offset)
        list.add(offset);

      return list.hashCode();
    }

    @Override
    public int compareTo(searchExperimentsByDesc_args other) {
      if (!getClass().equals(other.getClass())) {
        return getClass().getName().compareTo(other.getClass().getName());
      }

      int lastComparison = 0;

      lastComparison = 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 = 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;
        }
      }
      lastComparison = Boolean.valueOf(isSetUserName()).compareTo(other.isSetUserName());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetUserName()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.userName, other.userName);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = Boolean.valueOf(isSetDescription()).compareTo(other.isSetDescription());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetDescription()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.description, other.description);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = Boolean.valueOf(isSetLimit()).compareTo(other.isSetLimit());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetLimit()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.limit, other.limit);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = Boolean.valueOf(isSetOffset()).compareTo(other.isSetOffset());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetOffset()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.offset, other.offset);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      return 0;
    }

    public _Fields fieldForId(int fieldId) {
      return _Fields.findByThriftId(fieldId);
    }

    public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
      schemes.get(iprot.getScheme()).getScheme().read(iprot, this);
    }

    public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException {
      schemes.get(oprot.getScheme()).getScheme().write(oprot, this);
    }

    @Override
    public String toString() {
      StringBuilder sb = new StringBuilder("searchExperimentsByDesc_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;
      if (!first) sb.append(", ");
      sb.append("userName:");
      if (this.userName == null) {
        sb.append("null");
      } else {
        sb.append(this.userName);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("description:");
      if (this.description == null) {
        sb.append("null");
      } else {
        sb.append(this.description);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("limit:");
      sb.append(this.limit);
      first = false;
      if (!first) sb.append(", ");
      sb.append("offset:");
      sb.append(this.offset);
      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());
      }
      if (userName == null) {
        throw new org.apache.thrift.protocol.TProtocolException("Required field 'userName' was not present! Struct: " + toString());
      }
      if (description == null) {
        throw new org.apache.thrift.protocol.TProtocolException("Required field 'description' was not present! Struct: " + toString());
      }
      // alas, we cannot check 'limit' because it's a primitive and you chose the non-beans generator.
      // alas, we cannot check 'offset' because it's a primitive and you chose the non-beans generator.
      // 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, 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 searchExperimentsByDesc_argsStandardSchemeFactory implements SchemeFactory {
      public searchExperimentsByDesc_argsStandardScheme getScheme() {
        return new searchExperimentsByDesc_argsStandardScheme();
      }
    }

    private static class searchExperimentsByDesc_argsStandardScheme extends StandardScheme<searchExperimentsByDesc_args> {

      public void read(org.apache.thrift.protocol.TProtocol iprot, searchExperimentsByDesc_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;
            case 3: // USER_NAME
              if (schemeField.type == org.apache.thrift.protocol.TType.STRING) {
                struct.userName = iprot.readString();
                struct.setUserNameIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 4: // DESCRIPTION
              if (schemeField.type == org.apache.thrift.protocol.TType.STRING) {
                struct.description = iprot.readString();
                struct.setDescriptionIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 5: // LIMIT
              if (schemeField.type == org.apache.thrift.protocol.TType.I32) {
                struct.limit = iprot.readI32();
                struct.setLimitIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 6: // OFFSET
              if (schemeField.type == org.apache.thrift.protocol.TType.I32) {
                struct.offset = iprot.readI32();
                struct.setOffsetIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            default:
              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
          }
          iprot.readFieldEnd();
        }
        iprot.readStructEnd();

        // check for required fields of primitive type, which can't be checked in the validate method
        if (!struct.isSetLimit()) {
          throw new org.apache.thrift.protocol.TProtocolException("Required field 'limit' was not found in serialized data! Struct: " + toString());
        }
        if (!struct.isSetOffset()) {
          throw new org.apache.thrift.protocol.TProtocolException("Required field 'offset' was not found in serialized data! Struct: " + toString());
        }
        struct.validate();
      }

      public void write(org.apache.thrift.protocol.TProtocol oprot, searchExperimentsByDesc_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();
        }
        if (struct.userName != null) {
          oprot.writeFieldBegin(USER_NAME_FIELD_DESC);
          oprot.writeString(struct.userName);
          oprot.writeFieldEnd();
        }
        if (struct.description != null) {
          oprot.writeFieldBegin(DESCRIPTION_FIELD_DESC);
          oprot.writeString(struct.description);
          oprot.writeFieldEnd();
        }
        oprot.writeFieldBegin(LIMIT_FIELD_DESC);
        oprot.writeI32(struct.limit);
        oprot.writeFieldEnd();
        oprot.writeFieldBegin(OFFSET_FIELD_DESC);
        oprot.writeI32(struct.offset);
        oprot.writeFieldEnd();
        oprot.writeFieldStop();
        oprot.writeStructEnd();
      }

    }

    private static class searchExperimentsByDesc_argsTupleSchemeFactory implements SchemeFactory {
      public searchExperimentsByDesc_argsTupleScheme getScheme() {
        return new searchExperimentsByDesc_argsTupleScheme();
      }
    }

    private static class searchExperimentsByDesc_argsTupleScheme extends TupleScheme<searchExperimentsByDesc_args> {

      @Override
      public void write(org.apache.thrift.protocol.TProtocol prot, searchExperimentsByDesc_args struct) throws org.apache.thrift.TException {
        TTupleProtocol oprot = (TTupleProtocol) prot;
        struct.authzToken.write(oprot);
        oprot.writeString(struct.gatewayId);
        oprot.writeString(struct.userName);
        oprot.writeString(struct.description);
        oprot.writeI32(struct.limit);
        oprot.writeI32(struct.offset);
      }

      @Override
      public void read(org.apache.thrift.protocol.TProtocol prot, searchExperimentsByDesc_args struct) throws org.apache.thrift.TException {
        TTupleProtocol iprot = (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);
        struct.userName = iprot.readString();
        struct.setUserNameIsSet(true);
        struct.description = iprot.readString();
        struct.setDescriptionIsSet(true);
        struct.limit = iprot.readI32();
        struct.setLimitIsSet(true);
        struct.offset = iprot.readI32();
        struct.setOffsetIsSet(true);
      }
    }

  }

  public static class searchExperimentsByDesc_result implements org.apache.thrift.TBase<searchExperimentsByDesc_result, searchExperimentsByDesc_result._Fields>, java.io.Serializable, Cloneable, Comparable<searchExperimentsByDesc_result>   {
    private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("searchExperimentsByDesc_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 IRE_FIELD_DESC = new org.apache.thrift.protocol.TField("ire", org.apache.thrift.protocol.TType.STRUCT, (short)1);
    private static final org.apache.thrift.protocol.TField ACE_FIELD_DESC = new org.apache.thrift.protocol.TField("ace", org.apache.thrift.protocol.TType.STRUCT, (short)2);
    private static final org.apache.thrift.protocol.TField ASE_FIELD_DESC = new org.apache.thrift.protocol.TField("ase", org.apache.thrift.protocol.TType.STRUCT, (short)3);
    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)4);

    private static final Map<Class<? extends IScheme>, SchemeFactory> schemes = new HashMap<Class<? extends IScheme>, SchemeFactory>();
    static {
      schemes.put(StandardScheme.class, new searchExperimentsByDesc_resultStandardSchemeFactory());
      schemes.put(TupleScheme.class, new searchExperimentsByDesc_resultTupleSchemeFactory());
    }

    public List<org.apache.airavata.model.experiment.ExperimentSummaryModel> success; // required
    public org.apache.airavata.model.error.InvalidRequestException ire; // required
    public org.apache.airavata.model.error.AiravataClientException ace; // required
    public org.apache.airavata.model.error.AiravataSystemException ase; // 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"),
      IRE((short)1, "ire"),
      ACE((short)2, "ace"),
      ASE((short)3, "ase"),
      AE((short)4, "ae");

      private static final Map<String, _Fields> byName = new HashMap<String, _Fields>();

      static {
        for (_Fields field : EnumSet.allOf(_Fields.class)) {
          byName.put(field.getFieldName(), field);
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, or null if its not found.
       */
      public static _Fields findByThriftId(int fieldId) {
        switch(fieldId) {
          case 0: // SUCCESS
            return SUCCESS;
          case 1: // IRE
            return IRE;
          case 2: // ACE
            return ACE;
          case 3: // ASE
            return ASE;
          case 4: // 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 IllegalArgumentException("Field " + fieldId + " doesn't exist!");
        return fields;
      }

      /**
       * Find the _Fields constant that matches name, or null if its not found.
       */
      public static _Fields findByName(String name) {
        return byName.get(name);
      }

      private final short _thriftId;
      private final String _fieldName;

      _Fields(short thriftId, String fieldName) {
        _thriftId = thriftId;
        _fieldName = fieldName;
      }

      public short getThriftFieldId() {
        return _thriftId;
      }

      public String getFieldName() {
        return _fieldName;
      }
    }

    // isset id assignments
    public static final Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
    static {
      Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new EnumMap<_Fields, org.apache.thrift.meta_data.FieldMetaData>(_Fields.class);
      tmpMap.put(_Fields.SUCCESS, new org.apache.thrift.meta_data.FieldMetaData("success", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.ListMetaData(org.apache.thrift.protocol.TType.LIST, 
              new org.apache.thrift.meta_data.StructMetaData(org.apache.thrift.protocol.TType.STRUCT, org.apache.airavata.model.experiment.ExperimentSummaryModel.class))));
      tmpMap.put(_Fields.IRE, new org.apache.thrift.meta_data.FieldMetaData("ire", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRUCT)));
      tmpMap.put(_Fields.ACE, new org.apache.thrift.meta_data.FieldMetaData("ace", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRUCT)));
      tmpMap.put(_Fields.ASE, new org.apache.thrift.meta_data.FieldMetaData("ase", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRUCT)));
      tmpMap.put(_Fields.AE, new org.apache.thrift.meta_data.FieldMetaData("ae", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRUCT)));
      metaDataMap = Collections.unmodifiableMap(tmpMap);
      org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(searchExperimentsByDesc_result.class, metaDataMap);
    }

    public searchExperimentsByDesc_result() {
    }

    public searchExperimentsByDesc_result(
      List<org.apache.airavata.model.experiment.ExperimentSummaryModel> success,
      org.apache.airavata.model.error.InvalidRequestException ire,
      org.apache.airavata.model.error.AiravataClientException ace,
      org.apache.airavata.model.error.AiravataSystemException ase,
      org.apache.airavata.model.error.AuthorizationException ae)
    {
      this();
      this.success = success;
      this.ire = ire;
      this.ace = ace;
      this.ase = ase;
      this.ae = ae;
    }

    /**
     * Performs a deep copy on <i>other</i>.
     */
    public searchExperimentsByDesc_result(searchExperimentsByDesc_result other) {
      if (other.isSetSuccess()) {
        List<org.apache.airavata.model.experiment.ExperimentSummaryModel> __this__success = new ArrayList<org.apache.airavata.model.experiment.ExperimentSummaryModel>(other.success.size());
        for (org.apache.airavata.model.experiment.ExperimentSummaryModel other_element : other.success) {
          __this__success.add(new org.apache.airavata.model.experiment.ExperimentSummaryModel(other_element));
        }
        this.success = __this__success;
      }
      if (other.isSetIre()) {
        this.ire = new org.apache.airavata.model.error.InvalidRequestException(other.ire);
      }
      if (other.isSetAce()) {
        this.ace = new org.apache.airavata.model.error.AiravataClientException(other.ace);
      }
      if (other.isSetAse()) {
        this.ase = new org.apache.airavata.model.error.AiravataSystemException(other.ase);
      }
      if (other.isSetAe()) {
        this.ae = new org.apache.airavata.model.error.AuthorizationException(other.ae);
      }
    }

    public searchExperimentsByDesc_result deepCopy() {
      return new searchExperimentsByDesc_result(this);
    }

    @Override
    public void clear() {
      this.success = null;
      this.ire = null;
      this.ace = null;
      this.ase = null;
      this.ae = null;
    }

    public int getSuccessSize() {
      return (this.success == null) ? 0 : this.success.size();
    }

    public java.util.Iterator<org.apache.airavata.model.experiment.ExperimentSummaryModel> getSuccessIterator() {
      return (this.success == null) ? null : this.success.iterator();
    }

    public void addToSuccess(org.apache.airavata.model.experiment.ExperimentSummaryModel elem) {
      if (this.success == null) {
        this.success = new ArrayList<org.apache.airavata.model.experiment.ExperimentSummaryModel>();
      }
      this.success.add(elem);
    }

    public List<org.apache.airavata.model.experiment.ExperimentSummaryModel> getSuccess() {
      return this.success;
    }

    public searchExperimentsByDesc_result setSuccess(List<org.apache.airavata.model.experiment.ExperimentSummaryModel> 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.model.error.InvalidRequestException getIre() {
      return this.ire;
    }

    public searchExperimentsByDesc_result setIre(org.apache.airavata.model.error.InvalidRequestException ire) {
      this.ire = ire;
      return this;
    }

    public void unsetIre() {
      this.ire = null;
    }

    /** Returns true if field ire is set (has been assigned a value) and false otherwise */
    public boolean isSetIre() {
      return this.ire != null;
    }

    public void setIreIsSet(boolean value) {
      if (!value) {
        this.ire = null;
      }
    }

    public org.apache.airavata.model.error.AiravataClientException getAce() {
      return this.ace;
    }

    public searchExperimentsByDesc_result setAce(org.apache.airavata.model.error.AiravataClientException ace) {
      this.ace = ace;
      return this;
    }

    public void unsetAce() {
      this.ace = null;
    }

    /** Returns true if field ace is set (has been assigned a value) and false otherwise */
    public boolean isSetAce() {
      return this.ace != null;
    }

    public void setAceIsSet(boolean value) {
      if (!value) {
        this.ace = null;
      }
    }

    public org.apache.airavata.model.error.AiravataSystemException getAse() {
      return this.ase;
    }

    public searchExperimentsByDesc_result setAse(org.apache.airavata.model.error.AiravataSystemException ase) {
      this.ase = ase;
      return this;
    }

    public void unsetAse() {
      this.ase = null;
    }

    /** Returns true if field ase is set (has been assigned a value) and false otherwise */
    public boolean isSetAse() {
      return this.ase != null;
    }

    public void setAseIsSet(boolean value) {
      if (!value) {
        this.ase = null;
      }
    }

    public org.apache.airavata.model.error.AuthorizationException getAe() {
      return this.ae;
    }

    public searchExperimentsByDesc_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, Object value) {
      switch (field) {
      case SUCCESS:
        if (value == null) {
          unsetSuccess();
        } else {
          setSuccess((List<org.apache.airavata.model.experiment.ExperimentSummaryModel>)value);
        }
        break;

      case IRE:
        if (value == null) {
          unsetIre();
        } else {
          setIre((org.apache.airavata.model.error.InvalidRequestException)value);
        }
        break;

      case ACE:
        if (value == null) {
          unsetAce();
        } else {
          setAce((org.apache.airavata.model.error.AiravataClientException)value);
        }
        break;

      case ASE:
        if (value == null) {
          unsetAse();
        } else {
          setAse((org.apache.airavata.model.error.AiravataSystemException)value);
        }
        break;

      case AE:
        if (value == null) {
          unsetAe();
        } else {
          setAe((org.apache.airavata.model.error.AuthorizationException)value);
        }
        break;

      }
    }

    public Object getFieldValue(_Fields field) {
      switch (field) {
      case SUCCESS:
        return getSuccess();

      case IRE:
        return getIre();

      case ACE:
        return getAce();

      case ASE:
        return getAse();

      case AE:
        return getAe();

      }
      throw new IllegalStateException();
    }

    /** Returns true if field corresponding to fieldID is set (has been assigned a value) and false otherwise */
    public boolean isSet(_Fields field) {
      if (field == null) {
        throw new IllegalArgumentException();
      }

      switch (field) {
      case SUCCESS:
        return isSetSuccess();
      case IRE:
        return isSetIre();
      case ACE:
        return isSetAce();
      case ASE:
        return isSetAse();
      case AE:
        return isSetAe();
      }
      throw new IllegalStateException();
    }

    @Override
    public boolean equals(Object that) {
      if (that == null)
        return false;
      if (that instanceof searchExperimentsByDesc_result)
        return this.equals((searchExperimentsByDesc_result)that);
      return false;
    }

    public boolean equals(searchExperimentsByDesc_result that) {
      if (that == null)
        return false;

      boolean this_present_success = true && this.isSetSuccess();
      boolean that_present_success = true && that.isSetSuccess();
      if (this_present_success || that_present_success) {
        if (!(this_present_success && that_present_success))
          return false;
        if (!this.success.equals(that.success))
          return false;
      }

      boolean this_present_ire = true && this.isSetIre();
      boolean that_present_ire = true && that.isSetIre();
      if (this_present_ire || that_present_ire) {
        if (!(this_present_ire && that_present_ire))
          return false;
        if (!this.ire.equals(that.ire))
          return false;
      }

      boolean this_present_ace = true && this.isSetAce();
      boolean that_present_ace = true && that.isSetAce();
      if (this_present_ace || that_present_ace) {
        if (!(this_present_ace && that_present_ace))
          return false;
        if (!this.ace.equals(that.ace))
          return false;
      }

      boolean this_present_ase = true && this.isSetAse();
      boolean that_present_ase = true && that.isSetAse();
      if (this_present_ase || that_present_ase) {
        if (!(this_present_ase && that_present_ase))
          return false;
        if (!this.ase.equals(that.ase))
          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() {
      List<Object> list = new ArrayList<Object>();

      boolean present_success = true && (isSetSuccess());
      list.add(present_success);
      if (present_success)
        list.add(success);

      boolean present_ire = true && (isSetIre());
      list.add(present_ire);
      if (present_ire)
        list.add(ire);

      boolean present_ace = true && (isSetAce());
      list.add(present_ace);
      if (present_ace)
        list.add(ace);

      boolean present_ase = true && (isSetAse());
      list.add(present_ase);
      if (present_ase)
        list.add(ase);

      boolean present_ae = true && (isSetAe());
      list.add(present_ae);
      if (present_ae)
        list.add(ae);

      return list.hashCode();
    }

    @Override
    public int compareTo(searchExperimentsByDesc_result other) {
      if (!getClass().equals(other.getClass())) {
        return getClass().getName().compareTo(other.getClass().getName());
      }

      int lastComparison = 0;

      lastComparison = Boolean.valueOf(isSetSuccess()).compareTo(other.isSetSuccess());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetSuccess()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.success, other.success);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = Boolean.valueOf(isSetIre()).compareTo(other.isSetIre());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetIre()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.ire, other.ire);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = Boolean.valueOf(isSetAce()).compareTo(other.isSetAce());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetAce()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.ace, other.ace);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = Boolean.valueOf(isSetAse()).compareTo(other.isSetAse());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetAse()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.ase, other.ase);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = 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 {
      schemes.get(iprot.getScheme()).getScheme().read(iprot, this);
    }

    public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException {
      schemes.get(oprot.getScheme()).getScheme().write(oprot, this);
      }

    @Override
    public String toString() {
      StringBuilder sb = new StringBuilder("searchExperimentsByDesc_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("ire:");
      if (this.ire == null) {
        sb.append("null");
      } else {
        sb.append(this.ire);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("ace:");
      if (this.ace == null) {
        sb.append("null");
      } else {
        sb.append(this.ace);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("ase:");
      if (this.ase == null) {
        sb.append("null");
      } else {
        sb.append(this.ase);
      }
      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, 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 searchExperimentsByDesc_resultStandardSchemeFactory implements SchemeFactory {
      public searchExperimentsByDesc_resultStandardScheme getScheme() {
        return new searchExperimentsByDesc_resultStandardScheme();
      }
    }

    private static class searchExperimentsByDesc_resultStandardScheme extends StandardScheme<searchExperimentsByDesc_result> {

      public void read(org.apache.thrift.protocol.TProtocol iprot, searchExperimentsByDesc_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 _list50 = iprot.readListBegin();
                  struct.success = new ArrayList<org.apache.airavata.model.experiment.ExperimentSummaryModel>(_list50.size);
                  org.apache.airavata.model.experiment.ExperimentSummaryModel _elem51;
                  for (int _i52 = 0; _i52 < _list50.size; ++_i52)
                  {
                    _elem51 = new org.apache.airavata.model.experiment.ExperimentSummaryModel();
                    _elem51.read(iprot);
                    struct.success.add(_elem51);
                  }
                  iprot.readListEnd();
                }
                struct.setSuccessIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 1: // IRE
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.ire = new org.apache.airavata.model.error.InvalidRequestException();
                struct.ire.read(iprot);
                struct.setIreIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 2: // ACE
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.ace = new org.apache.airavata.model.error.AiravataClientException();
                struct.ace.read(iprot);
                struct.setAceIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 3: // ASE
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.ase = new org.apache.airavata.model.error.AiravataSystemException();
                struct.ase.read(iprot);
                struct.setAseIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 4: // 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, searchExperimentsByDesc_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.experiment.ExperimentSummaryModel _iter53 : struct.success)
            {
              _iter53.write(oprot);
            }
            oprot.writeListEnd();
          }
          oprot.writeFieldEnd();
        }
        if (struct.ire != null) {
          oprot.writeFieldBegin(IRE_FIELD_DESC);
          struct.ire.write(oprot);
          oprot.writeFieldEnd();
        }
        if (struct.ace != null) {
          oprot.writeFieldBegin(ACE_FIELD_DESC);
          struct.ace.write(oprot);
          oprot.writeFieldEnd();
        }
        if (struct.ase != null) {
          oprot.writeFieldBegin(ASE_FIELD_DESC);
          struct.ase.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 searchExperimentsByDesc_resultTupleSchemeFactory implements SchemeFactory {
      public searchExperimentsByDesc_resultTupleScheme getScheme() {
        return new searchExperimentsByDesc_resultTupleScheme();
      }
    }

    private static class searchExperimentsByDesc_resultTupleScheme extends TupleScheme<searchExperimentsByDesc_result> {

      @Override
      public void write(org.apache.thrift.protocol.TProtocol prot, searchExperimentsByDesc_result struct) throws org.apache.thrift.TException {
        TTupleProtocol oprot = (TTupleProtocol) prot;
        BitSet optionals = new BitSet();
        if (struct.isSetSuccess()) {
          optionals.set(0);
        }
        if (struct.isSetIre()) {
          optionals.set(1);
        }
        if (struct.isSetAce()) {
          optionals.set(2);
        }
        if (struct.isSetAse()) {
          optionals.set(3);
        }
        if (struct.isSetAe()) {
          optionals.set(4);
        }
        oprot.writeBitSet(optionals, 5);
        if (struct.isSetSuccess()) {
          {
            oprot.writeI32(struct.success.size());
            for (org.apache.airavata.model.experiment.ExperimentSummaryModel _iter54 : struct.success)
            {
              _iter54.write(oprot);
            }
          }
        }
        if (struct.isSetIre()) {
          struct.ire.write(oprot);
        }
        if (struct.isSetAce()) {
          struct.ace.write(oprot);
        }
        if (struct.isSetAse()) {
          struct.ase.write(oprot);
        }
        if (struct.isSetAe()) {
          struct.ae.write(oprot);
        }
      }

      @Override
      public void read(org.apache.thrift.protocol.TProtocol prot, searchExperimentsByDesc_result struct) throws org.apache.thrift.TException {
        TTupleProtocol iprot = (TTupleProtocol) prot;
        BitSet incoming = iprot.readBitSet(5);
        if (incoming.get(0)) {
          {
            org.apache.thrift.protocol.TList _list55 = new org.apache.thrift.protocol.TList(org.apache.thrift.protocol.TType.STRUCT, iprot.readI32());
            struct.success = new ArrayList<org.apache.airavata.model.experiment.ExperimentSummaryModel>(_list55.size);
            org.apache.airavata.model.experiment.ExperimentSummaryModel _elem56;
            for (int _i57 = 0; _i57 < _list55.size; ++_i57)
            {
              _elem56 = new org.apache.airavata.model.experiment.ExperimentSummaryModel();
              _elem56.read(iprot);
              struct.success.add(_elem56);
            }
          }
          struct.setSuccessIsSet(true);
        }
        if (incoming.get(1)) {
          struct.ire = new org.apache.airavata.model.error.InvalidRequestException();
          struct.ire.read(iprot);
          struct.setIreIsSet(true);
        }
        if (incoming.get(2)) {
          struct.ace = new org.apache.airavata.model.error.AiravataClientException();
          struct.ace.read(iprot);
          struct.setAceIsSet(true);
        }
        if (incoming.get(3)) {
          struct.ase = new org.apache.airavata.model.error.AiravataSystemException();
          struct.ase.read(iprot);
          struct.setAseIsSet(true);
        }
        if (incoming.get(4)) {
          struct.ae = new org.apache.airavata.model.error.AuthorizationException();
          struct.ae.read(iprot);
          struct.setAeIsSet(true);
        }
      }
    }

  }

  public static class searchExperimentsByApplication_args implements org.apache.thrift.TBase<searchExperimentsByApplication_args, searchExperimentsByApplication_args._Fields>, java.io.Serializable, Cloneable, Comparable<searchExperimentsByApplication_args>   {
    private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("searchExperimentsByApplication_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.protocol.TField USER_NAME_FIELD_DESC = new org.apache.thrift.protocol.TField("userName", org.apache.thrift.protocol.TType.STRING, (short)3);
    private static final org.apache.thrift.protocol.TField APPLICATION_ID_FIELD_DESC = new org.apache.thrift.protocol.TField("applicationId", org.apache.thrift.protocol.TType.STRING, (short)4);
    private static final org.apache.thrift.protocol.TField LIMIT_FIELD_DESC = new org.apache.thrift.protocol.TField("limit", org.apache.thrift.protocol.TType.I32, (short)5);
    private static final org.apache.thrift.protocol.TField OFFSET_FIELD_DESC = new org.apache.thrift.protocol.TField("offset", org.apache.thrift.protocol.TType.I32, (short)6);

    private static final Map<Class<? extends IScheme>, SchemeFactory> schemes = new HashMap<Class<? extends IScheme>, SchemeFactory>();
    static {
      schemes.put(StandardScheme.class, new searchExperimentsByApplication_argsStandardSchemeFactory());
      schemes.put(TupleScheme.class, new searchExperimentsByApplication_argsTupleSchemeFactory());
    }

    public org.apache.airavata.model.security.AuthzToken authzToken; // required
    public String gatewayId; // required
    public String userName; // required
    public String applicationId; // required
    public int limit; // required
    public int offset; // required

    /** 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"),
      USER_NAME((short)3, "userName"),
      APPLICATION_ID((short)4, "applicationId"),
      LIMIT((short)5, "limit"),
      OFFSET((short)6, "offset");

      private static final Map<String, _Fields> byName = new HashMap<String, _Fields>();

      static {
        for (_Fields field : EnumSet.allOf(_Fields.class)) {
          byName.put(field.getFieldName(), field);
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, or null if its not found.
       */
      public static _Fields findByThriftId(int fieldId) {
        switch(fieldId) {
          case 1: // AUTHZ_TOKEN
            return AUTHZ_TOKEN;
          case 2: // GATEWAY_ID
            return GATEWAY_ID;
          case 3: // USER_NAME
            return USER_NAME;
          case 4: // APPLICATION_ID
            return APPLICATION_ID;
          case 5: // LIMIT
            return LIMIT;
          case 6: // OFFSET
            return OFFSET;
          default:
            return null;
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, throwing an exception
       * if it is not found.
       */
      public static _Fields findByThriftIdOrThrow(int fieldId) {
        _Fields fields = findByThriftId(fieldId);
        if (fields == null) throw new IllegalArgumentException("Field " + fieldId + " doesn't exist!");
        return fields;
      }

      /**
       * Find the _Fields constant that matches name, or null if its not found.
       */
      public static _Fields findByName(String name) {
        return byName.get(name);
      }

      private final short _thriftId;
      private final String _fieldName;

      _Fields(short thriftId, String fieldName) {
        _thriftId = thriftId;
        _fieldName = fieldName;
      }

      public short getThriftFieldId() {
        return _thriftId;
      }

      public String getFieldName() {
        return _fieldName;
      }
    }

    // isset id assignments
    private static final int __LIMIT_ISSET_ID = 0;
    private static final int __OFFSET_ISSET_ID = 1;
    private byte __isset_bitfield = 0;
    public static final Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
    static {
      Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new EnumMap<_Fields, org.apache.thrift.meta_data.FieldMetaData>(_Fields.class);
      tmpMap.put(_Fields.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)));
      tmpMap.put(_Fields.USER_NAME, new org.apache.thrift.meta_data.FieldMetaData("userName", org.apache.thrift.TFieldRequirementType.REQUIRED, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING)));
      tmpMap.put(_Fields.APPLICATION_ID, new org.apache.thrift.meta_data.FieldMetaData("applicationId", org.apache.thrift.TFieldRequirementType.REQUIRED, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING)));
      tmpMap.put(_Fields.LIMIT, new org.apache.thrift.meta_data.FieldMetaData("limit", org.apache.thrift.TFieldRequirementType.REQUIRED, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.I32)));
      tmpMap.put(_Fields.OFFSET, new org.apache.thrift.meta_data.FieldMetaData("offset", org.apache.thrift.TFieldRequirementType.REQUIRED, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.I32)));
      metaDataMap = Collections.unmodifiableMap(tmpMap);
      org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(searchExperimentsByApplication_args.class, metaDataMap);
    }

    public searchExperimentsByApplication_args() {
    }

    public searchExperimentsByApplication_args(
      org.apache.airavata.model.security.AuthzToken authzToken,
      String gatewayId,
      String userName,
      String applicationId,
      int limit,
      int offset)
    {
      this();
      this.authzToken = authzToken;
      this.gatewayId = gatewayId;
      this.userName = userName;
      this.applicationId = applicationId;
      this.limit = limit;
      setLimitIsSet(true);
      this.offset = offset;
      setOffsetIsSet(true);
    }

    /**
     * Performs a deep copy on <i>other</i>.
     */
    public searchExperimentsByApplication_args(searchExperimentsByApplication_args other) {
      __isset_bitfield = other.__isset_bitfield;
      if (other.isSetAuthzToken()) {
        this.authzToken = new org.apache.airavata.model.security.AuthzToken(other.authzToken);
      }
      if (other.isSetGatewayId()) {
        this.gatewayId = other.gatewayId;
      }
      if (other.isSetUserName()) {
        this.userName = other.userName;
      }
      if (other.isSetApplicationId()) {
        this.applicationId = other.applicationId;
      }
      this.limit = other.limit;
      this.offset = other.offset;
    }

    public searchExperimentsByApplication_args deepCopy() {
      return new searchExperimentsByApplication_args(this);
    }

    @Override
    public void clear() {
      this.authzToken = null;
      this.gatewayId = null;
      this.userName = null;
      this.applicationId = null;
      setLimitIsSet(false);
      this.limit = 0;
      setOffsetIsSet(false);
      this.offset = 0;
    }

    public org.apache.airavata.model.security.AuthzToken getAuthzToken() {
      return this.authzToken;
    }

    public searchExperimentsByApplication_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 String getGatewayId() {
      return this.gatewayId;
    }

    public searchExperimentsByApplication_args setGatewayId(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 String getUserName() {
      return this.userName;
    }

    public searchExperimentsByApplication_args setUserName(String userName) {
      this.userName = userName;
      return this;
    }

    public void unsetUserName() {
      this.userName = null;
    }

    /** Returns true if field userName is set (has been assigned a value) and false otherwise */
    public boolean isSetUserName() {
      return this.userName != null;
    }

    public void setUserNameIsSet(boolean value) {
      if (!value) {
        this.userName = null;
      }
    }

    public String getApplicationId() {
      return this.applicationId;
    }

    public searchExperimentsByApplication_args setApplicationId(String applicationId) {
      this.applicationId = applicationId;
      return this;
    }

    public void unsetApplicationId() {
      this.applicationId = null;
    }

    /** Returns true if field applicationId is set (has been assigned a value) and false otherwise */
    public boolean isSetApplicationId() {
      return this.applicationId != null;
    }

    public void setApplicationIdIsSet(boolean value) {
      if (!value) {
        this.applicationId = null;
      }
    }

    public int getLimit() {
      return this.limit;
    }

    public searchExperimentsByApplication_args setLimit(int limit) {
      this.limit = limit;
      setLimitIsSet(true);
      return this;
    }

    public void unsetLimit() {
      __isset_bitfield = EncodingUtils.clearBit(__isset_bitfield, __LIMIT_ISSET_ID);
    }

    /** Returns true if field limit is set (has been assigned a value) and false otherwise */
    public boolean isSetLimit() {
      return EncodingUtils.testBit(__isset_bitfield, __LIMIT_ISSET_ID);
    }

    public void setLimitIsSet(boolean value) {
      __isset_bitfield = EncodingUtils.setBit(__isset_bitfield, __LIMIT_ISSET_ID, value);
    }

    public int getOffset() {
      return this.offset;
    }

    public searchExperimentsByApplication_args setOffset(int offset) {
      this.offset = offset;
      setOffsetIsSet(true);
      return this;
    }

    public void unsetOffset() {
      __isset_bitfield = EncodingUtils.clearBit(__isset_bitfield, __OFFSET_ISSET_ID);
    }

    /** Returns true if field offset is set (has been assigned a value) and false otherwise */
    public boolean isSetOffset() {
      return EncodingUtils.testBit(__isset_bitfield, __OFFSET_ISSET_ID);
    }

    public void setOffsetIsSet(boolean value) {
      __isset_bitfield = EncodingUtils.setBit(__isset_bitfield, __OFFSET_ISSET_ID, value);
    }

    public void setFieldValue(_Fields field, 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((String)value);
        }
        break;

      case USER_NAME:
        if (value == null) {
          unsetUserName();
        } else {
          setUserName((String)value);
        }
        break;

      case APPLICATION_ID:
        if (value == null) {
          unsetApplicationId();
        } else {
          setApplicationId((String)value);
        }
        break;

      case LIMIT:
        if (value == null) {
          unsetLimit();
        } else {
          setLimit((Integer)value);
        }
        break;

      case OFFSET:
        if (value == null) {
          unsetOffset();
        } else {
          setOffset((Integer)value);
        }
        break;

      }
    }

    public Object getFieldValue(_Fields field) {
      switch (field) {
      case AUTHZ_TOKEN:
        return getAuthzToken();

      case GATEWAY_ID:
        return getGatewayId();

      case USER_NAME:
        return getUserName();

      case APPLICATION_ID:
        return getApplicationId();

      case LIMIT:
        return Integer.valueOf(getLimit());

      case OFFSET:
        return Integer.valueOf(getOffset());

      }
      throw new IllegalStateException();
    }

    /** Returns true if field corresponding to fieldID is set (has been assigned a value) and false otherwise */
    public boolean isSet(_Fields field) {
      if (field == null) {
        throw new IllegalArgumentException();
      }

      switch (field) {
      case AUTHZ_TOKEN:
        return isSetAuthzToken();
      case GATEWAY_ID:
        return isSetGatewayId();
      case USER_NAME:
        return isSetUserName();
      case APPLICATION_ID:
        return isSetApplicationId();
      case LIMIT:
        return isSetLimit();
      case OFFSET:
        return isSetOffset();
      }
      throw new IllegalStateException();
    }

    @Override
    public boolean equals(Object that) {
      if (that == null)
        return false;
      if (that instanceof searchExperimentsByApplication_args)
        return this.equals((searchExperimentsByApplication_args)that);
      return false;
    }

    public boolean equals(searchExperimentsByApplication_args that) {
      if (that == null)
        return false;

      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;
      }

      boolean this_present_userName = true && this.isSetUserName();
      boolean that_present_userName = true && that.isSetUserName();
      if (this_present_userName || that_present_userName) {
        if (!(this_present_userName && that_present_userName))
          return false;
        if (!this.userName.equals(that.userName))
          return false;
      }

      boolean this_present_applicationId = true && this.isSetApplicationId();
      boolean that_present_applicationId = true && that.isSetApplicationId();
      if (this_present_applicationId || that_present_applicationId) {
        if (!(this_present_applicationId && that_present_applicationId))
          return false;
        if (!this.applicationId.equals(that.applicationId))
          return false;
      }

      boolean this_present_limit = true;
      boolean that_present_limit = true;
      if (this_present_limit || that_present_limit) {
        if (!(this_present_limit && that_present_limit))
          return false;
        if (this.limit != that.limit)
          return false;
      }

      boolean this_present_offset = true;
      boolean that_present_offset = true;
      if (this_present_offset || that_present_offset) {
        if (!(this_present_offset && that_present_offset))
          return false;
        if (this.offset != that.offset)
          return false;
      }

      return true;
    }

    @Override
    public int hashCode() {
      List<Object> list = new ArrayList<Object>();

      boolean present_authzToken = true && (isSetAuthzToken());
      list.add(present_authzToken);
      if (present_authzToken)
        list.add(authzToken);

      boolean present_gatewayId = true && (isSetGatewayId());
      list.add(present_gatewayId);
      if (present_gatewayId)
        list.add(gatewayId);

      boolean present_userName = true && (isSetUserName());
      list.add(present_userName);
      if (present_userName)
        list.add(userName);

      boolean present_applicationId = true && (isSetApplicationId());
      list.add(present_applicationId);
      if (present_applicationId)
        list.add(applicationId);

      boolean present_limit = true;
      list.add(present_limit);
      if (present_limit)
        list.add(limit);

      boolean present_offset = true;
      list.add(present_offset);
      if (present_offset)
        list.add(offset);

      return list.hashCode();
    }

    @Override
    public int compareTo(searchExperimentsByApplication_args other) {
      if (!getClass().equals(other.getClass())) {
        return getClass().getName().compareTo(other.getClass().getName());
      }

      int lastComparison = 0;

      lastComparison = 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 = 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;
        }
      }
      lastComparison = Boolean.valueOf(isSetUserName()).compareTo(other.isSetUserName());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetUserName()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.userName, other.userName);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = Boolean.valueOf(isSetApplicationId()).compareTo(other.isSetApplicationId());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetApplicationId()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.applicationId, other.applicationId);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = Boolean.valueOf(isSetLimit()).compareTo(other.isSetLimit());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetLimit()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.limit, other.limit);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = Boolean.valueOf(isSetOffset()).compareTo(other.isSetOffset());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetOffset()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.offset, other.offset);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      return 0;
    }

    public _Fields fieldForId(int fieldId) {
      return _Fields.findByThriftId(fieldId);
    }

    public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
      schemes.get(iprot.getScheme()).getScheme().read(iprot, this);
    }

    public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException {
      schemes.get(oprot.getScheme()).getScheme().write(oprot, this);
    }

    @Override
    public String toString() {
      StringBuilder sb = new StringBuilder("searchExperimentsByApplication_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;
      if (!first) sb.append(", ");
      sb.append("userName:");
      if (this.userName == null) {
        sb.append("null");
      } else {
        sb.append(this.userName);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("applicationId:");
      if (this.applicationId == null) {
        sb.append("null");
      } else {
        sb.append(this.applicationId);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("limit:");
      sb.append(this.limit);
      first = false;
      if (!first) sb.append(", ");
      sb.append("offset:");
      sb.append(this.offset);
      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());
      }
      if (userName == null) {
        throw new org.apache.thrift.protocol.TProtocolException("Required field 'userName' was not present! Struct: " + toString());
      }
      if (applicationId == null) {
        throw new org.apache.thrift.protocol.TProtocolException("Required field 'applicationId' was not present! Struct: " + toString());
      }
      // alas, we cannot check 'limit' because it's a primitive and you chose the non-beans generator.
      // alas, we cannot check 'offset' because it's a primitive and you chose the non-beans generator.
      // 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, 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 searchExperimentsByApplication_argsStandardSchemeFactory implements SchemeFactory {
      public searchExperimentsByApplication_argsStandardScheme getScheme() {
        return new searchExperimentsByApplication_argsStandardScheme();
      }
    }

    private static class searchExperimentsByApplication_argsStandardScheme extends StandardScheme<searchExperimentsByApplication_args> {

      public void read(org.apache.thrift.protocol.TProtocol iprot, searchExperimentsByApplication_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;
            case 3: // USER_NAME
              if (schemeField.type == org.apache.thrift.protocol.TType.STRING) {
                struct.userName = iprot.readString();
                struct.setUserNameIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 4: // APPLICATION_ID
              if (schemeField.type == org.apache.thrift.protocol.TType.STRING) {
                struct.applicationId = iprot.readString();
                struct.setApplicationIdIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 5: // LIMIT
              if (schemeField.type == org.apache.thrift.protocol.TType.I32) {
                struct.limit = iprot.readI32();
                struct.setLimitIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 6: // OFFSET
              if (schemeField.type == org.apache.thrift.protocol.TType.I32) {
                struct.offset = iprot.readI32();
                struct.setOffsetIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            default:
              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
          }
          iprot.readFieldEnd();
        }
        iprot.readStructEnd();

        // check for required fields of primitive type, which can't be checked in the validate method
        if (!struct.isSetLimit()) {
          throw new org.apache.thrift.protocol.TProtocolException("Required field 'limit' was not found in serialized data! Struct: " + toString());
        }
        if (!struct.isSetOffset()) {
          throw new org.apache.thrift.protocol.TProtocolException("Required field 'offset' was not found in serialized data! Struct: " + toString());
        }
        struct.validate();
      }

      public void write(org.apache.thrift.protocol.TProtocol oprot, searchExperimentsByApplication_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();
        }
        if (struct.userName != null) {
          oprot.writeFieldBegin(USER_NAME_FIELD_DESC);
          oprot.writeString(struct.userName);
          oprot.writeFieldEnd();
        }
        if (struct.applicationId != null) {
          oprot.writeFieldBegin(APPLICATION_ID_FIELD_DESC);
          oprot.writeString(struct.applicationId);
          oprot.writeFieldEnd();
        }
        oprot.writeFieldBegin(LIMIT_FIELD_DESC);
        oprot.writeI32(struct.limit);
        oprot.writeFieldEnd();
        oprot.writeFieldBegin(OFFSET_FIELD_DESC);
        oprot.writeI32(struct.offset);
        oprot.writeFieldEnd();
        oprot.writeFieldStop();
        oprot.writeStructEnd();
      }

    }

    private static class searchExperimentsByApplication_argsTupleSchemeFactory implements SchemeFactory {
      public searchExperimentsByApplication_argsTupleScheme getScheme() {
        return new searchExperimentsByApplication_argsTupleScheme();
      }
    }

    private static class searchExperimentsByApplication_argsTupleScheme extends TupleScheme<searchExperimentsByApplication_args> {

      @Override
      public void write(org.apache.thrift.protocol.TProtocol prot, searchExperimentsByApplication_args struct) throws org.apache.thrift.TException {
        TTupleProtocol oprot = (TTupleProtocol) prot;
        struct.authzToken.write(oprot);
        oprot.writeString(struct.gatewayId);
        oprot.writeString(struct.userName);
        oprot.writeString(struct.applicationId);
        oprot.writeI32(struct.limit);
        oprot.writeI32(struct.offset);
      }

      @Override
      public void read(org.apache.thrift.protocol.TProtocol prot, searchExperimentsByApplication_args struct) throws org.apache.thrift.TException {
        TTupleProtocol iprot = (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);
        struct.userName = iprot.readString();
        struct.setUserNameIsSet(true);
        struct.applicationId = iprot.readString();
        struct.setApplicationIdIsSet(true);
        struct.limit = iprot.readI32();
        struct.setLimitIsSet(true);
        struct.offset = iprot.readI32();
        struct.setOffsetIsSet(true);
      }
    }

  }

  public static class searchExperimentsByApplication_result implements org.apache.thrift.TBase<searchExperimentsByApplication_result, searchExperimentsByApplication_result._Fields>, java.io.Serializable, Cloneable, Comparable<searchExperimentsByApplication_result>   {
    private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("searchExperimentsByApplication_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 IRE_FIELD_DESC = new org.apache.thrift.protocol.TField("ire", org.apache.thrift.protocol.TType.STRUCT, (short)1);
    private static final org.apache.thrift.protocol.TField ACE_FIELD_DESC = new org.apache.thrift.protocol.TField("ace", org.apache.thrift.protocol.TType.STRUCT, (short)2);
    private static final org.apache.thrift.protocol.TField ASE_FIELD_DESC = new org.apache.thrift.protocol.TField("ase", org.apache.thrift.protocol.TType.STRUCT, (short)3);
    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)4);

    private static final Map<Class<? extends IScheme>, SchemeFactory> schemes = new HashMap<Class<? extends IScheme>, SchemeFactory>();
    static {
      schemes.put(StandardScheme.class, new searchExperimentsByApplication_resultStandardSchemeFactory());
      schemes.put(TupleScheme.class, new searchExperimentsByApplication_resultTupleSchemeFactory());
    }

    public List<org.apache.airavata.model.experiment.ExperimentSummaryModel> success; // required
    public org.apache.airavata.model.error.InvalidRequestException ire; // required
    public org.apache.airavata.model.error.AiravataClientException ace; // required
    public org.apache.airavata.model.error.AiravataSystemException ase; // 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"),
      IRE((short)1, "ire"),
      ACE((short)2, "ace"),
      ASE((short)3, "ase"),
      AE((short)4, "ae");

      private static final Map<String, _Fields> byName = new HashMap<String, _Fields>();

      static {
        for (_Fields field : EnumSet.allOf(_Fields.class)) {
          byName.put(field.getFieldName(), field);
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, or null if its not found.
       */
      public static _Fields findByThriftId(int fieldId) {
        switch(fieldId) {
          case 0: // SUCCESS
            return SUCCESS;
          case 1: // IRE
            return IRE;
          case 2: // ACE
            return ACE;
          case 3: // ASE
            return ASE;
          case 4: // 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 IllegalArgumentException("Field " + fieldId + " doesn't exist!");
        return fields;
      }

      /**
       * Find the _Fields constant that matches name, or null if its not found.
       */
      public static _Fields findByName(String name) {
        return byName.get(name);
      }

      private final short _thriftId;
      private final String _fieldName;

      _Fields(short thriftId, String fieldName) {
        _thriftId = thriftId;
        _fieldName = fieldName;
      }

      public short getThriftFieldId() {
        return _thriftId;
      }

      public String getFieldName() {
        return _fieldName;
      }
    }

    // isset id assignments
    public static final Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
    static {
      Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new EnumMap<_Fields, org.apache.thrift.meta_data.FieldMetaData>(_Fields.class);
      tmpMap.put(_Fields.SUCCESS, new org.apache.thrift.meta_data.FieldMetaData("success", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.ListMetaData(org.apache.thrift.protocol.TType.LIST, 
              new org.apache.thrift.meta_data.StructMetaData(org.apache.thrift.protocol.TType.STRUCT, org.apache.airavata.model.experiment.ExperimentSummaryModel.class))));
      tmpMap.put(_Fields.IRE, new org.apache.thrift.meta_data.FieldMetaData("ire", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRUCT)));
      tmpMap.put(_Fields.ACE, new org.apache.thrift.meta_data.FieldMetaData("ace", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRUCT)));
      tmpMap.put(_Fields.ASE, new org.apache.thrift.meta_data.FieldMetaData("ase", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRUCT)));
      tmpMap.put(_Fields.AE, new org.apache.thrift.meta_data.FieldMetaData("ae", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRUCT)));
      metaDataMap = Collections.unmodifiableMap(tmpMap);
      org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(searchExperimentsByApplication_result.class, metaDataMap);
    }

    public searchExperimentsByApplication_result() {
    }

    public searchExperimentsByApplication_result(
      List<org.apache.airavata.model.experiment.ExperimentSummaryModel> success,
      org.apache.airavata.model.error.InvalidRequestException ire,
      org.apache.airavata.model.error.AiravataClientException ace,
      org.apache.airavata.model.error.AiravataSystemException ase,
      org.apache.airavata.model.error.AuthorizationException ae)
    {
      this();
      this.success = success;
      this.ire = ire;
      this.ace = ace;
      this.ase = ase;
      this.ae = ae;
    }

    /**
     * Performs a deep copy on <i>other</i>.
     */
    public searchExperimentsByApplication_result(searchExperimentsByApplication_result other) {
      if (other.isSetSuccess()) {
        List<org.apache.airavata.model.experiment.ExperimentSummaryModel> __this__success = new ArrayList<org.apache.airavata.model.experiment.ExperimentSummaryModel>(other.success.size());
        for (org.apache.airavata.model.experiment.ExperimentSummaryModel other_element : other.success) {
          __this__success.add(new org.apache.airavata.model.experiment.ExperimentSummaryModel(other_element));
        }
        this.success = __this__success;
      }
      if (other.isSetIre()) {
        this.ire = new org.apache.airavata.model.error.InvalidRequestException(other.ire);
      }
      if (other.isSetAce()) {
        this.ace = new org.apache.airavata.model.error.AiravataClientException(other.ace);
      }
      if (other.isSetAse()) {
        this.ase = new org.apache.airavata.model.error.AiravataSystemException(other.ase);
      }
      if (other.isSetAe()) {
        this.ae = new org.apache.airavata.model.error.AuthorizationException(other.ae);
      }
    }

    public searchExperimentsByApplication_result deepCopy() {
      return new searchExperimentsByApplication_result(this);
    }

    @Override
    public void clear() {
      this.success = null;
      this.ire = null;
      this.ace = null;
      this.ase = null;
      this.ae = null;
    }

    public int getSuccessSize() {
      return (this.success == null) ? 0 : this.success.size();
    }

    public java.util.Iterator<org.apache.airavata.model.experiment.ExperimentSummaryModel> getSuccessIterator() {
      return (this.success == null) ? null : this.success.iterator();
    }

    public void addToSuccess(org.apache.airavata.model.experiment.ExperimentSummaryModel elem) {
      if (this.success == null) {
        this.success = new ArrayList<org.apache.airavata.model.experiment.ExperimentSummaryModel>();
      }
      this.success.add(elem);
    }

    public List<org.apache.airavata.model.experiment.ExperimentSummaryModel> getSuccess() {
      return this.success;
    }

    public searchExperimentsByApplication_result setSuccess(List<org.apache.airavata.model.experiment.ExperimentSummaryModel> 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.model.error.InvalidRequestException getIre() {
      return this.ire;
    }

    public searchExperimentsByApplication_result setIre(org.apache.airavata.model.error.InvalidRequestException ire) {
      this.ire = ire;
      return this;
    }

    public void unsetIre() {
      this.ire = null;
    }

    /** Returns true if field ire is set (has been assigned a value) and false otherwise */
    public boolean isSetIre() {
      return this.ire != null;
    }

    public void setIreIsSet(boolean value) {
      if (!value) {
        this.ire = null;
      }
    }

    public org.apache.airavata.model.error.AiravataClientException getAce() {
      return this.ace;
    }

    public searchExperimentsByApplication_result setAce(org.apache.airavata.model.error.AiravataClientException ace) {
      this.ace = ace;
      return this;
    }

    public void unsetAce() {
      this.ace = null;
    }

    /** Returns true if field ace is set (has been assigned a value) and false otherwise */
    public boolean isSetAce() {
      return this.ace != null;
    }

    public void setAceIsSet(boolean value) {
      if (!value) {
        this.ace = null;
      }
    }

    public org.apache.airavata.model.error.AiravataSystemException getAse() {
      return this.ase;
    }

    public searchExperimentsByApplication_result setAse(org.apache.airavata.model.error.AiravataSystemException ase) {
      this.ase = ase;
      return this;
    }

    public void unsetAse() {
      this.ase = null;
    }

    /** Returns true if field ase is set (has been assigned a value) and false otherwise */
    public boolean isSetAse() {
      return this.ase != null;
    }

    public void setAseIsSet(boolean value) {
      if (!value) {
        this.ase = null;
      }
    }

    public org.apache.airavata.model.error.AuthorizationException getAe() {
      return this.ae;
    }

    public searchExperimentsByApplication_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, Object value) {
      switch (field) {
      case SUCCESS:
        if (value == null) {
          unsetSuccess();
        } else {
          setSuccess((List<org.apache.airavata.model.experiment.ExperimentSummaryModel>)value);
        }
        break;

      case IRE:
        if (value == null) {
          unsetIre();
        } else {
          setIre((org.apache.airavata.model.error.InvalidRequestException)value);
        }
        break;

      case ACE:
        if (value == null) {
          unsetAce();
        } else {
          setAce((org.apache.airavata.model.error.AiravataClientException)value);
        }
        break;

      case ASE:
        if (value == null) {
          unsetAse();
        } else {
          setAse((org.apache.airavata.model.error.AiravataSystemException)value);
        }
        break;

      case AE:
        if (value == null) {
          unsetAe();
        } else {
          setAe((org.apache.airavata.model.error.AuthorizationException)value);
        }
        break;

      }
    }

    public Object getFieldValue(_Fields field) {
      switch (field) {
      case SUCCESS:
        return getSuccess();

      case IRE:
        return getIre();

      case ACE:
        return getAce();

      case ASE:
        return getAse();

      case AE:
        return getAe();

      }
      throw new IllegalStateException();
    }

    /** Returns true if field corresponding to fieldID is set (has been assigned a value) and false otherwise */
    public boolean isSet(_Fields field) {
      if (field == null) {
        throw new IllegalArgumentException();
      }

      switch (field) {
      case SUCCESS:
        return isSetSuccess();
      case IRE:
        return isSetIre();
      case ACE:
        return isSetAce();
      case ASE:
        return isSetAse();
      case AE:
        return isSetAe();
      }
      throw new IllegalStateException();
    }

    @Override
    public boolean equals(Object that) {
      if (that == null)
        return false;
      if (that instanceof searchExperimentsByApplication_result)
        return this.equals((searchExperimentsByApplication_result)that);
      return false;
    }

    public boolean equals(searchExperimentsByApplication_result that) {
      if (that == null)
        return false;

      boolean this_present_success = true && this.isSetSuccess();
      boolean that_present_success = true && that.isSetSuccess();
      if (this_present_success || that_present_success) {
        if (!(this_present_success && that_present_success))
          return false;
        if (!this.success.equals(that.success))
          return false;
      }

      boolean this_present_ire = true && this.isSetIre();
      boolean that_present_ire = true && that.isSetIre();
      if (this_present_ire || that_present_ire) {
        if (!(this_present_ire && that_present_ire))
          return false;
        if (!this.ire.equals(that.ire))
          return false;
      }

      boolean this_present_ace = true && this.isSetAce();
      boolean that_present_ace = true && that.isSetAce();
      if (this_present_ace || that_present_ace) {
        if (!(this_present_ace && that_present_ace))
          return false;
        if (!this.ace.equals(that.ace))
          return false;
      }

      boolean this_present_ase = true && this.isSetAse();
      boolean that_present_ase = true && that.isSetAse();
      if (this_present_ase || that_present_ase) {
        if (!(this_present_ase && that_present_ase))
          return false;
        if (!this.ase.equals(that.ase))
          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() {
      List<Object> list = new ArrayList<Object>();

      boolean present_success = true && (isSetSuccess());
      list.add(present_success);
      if (present_success)
        list.add(success);

      boolean present_ire = true && (isSetIre());
      list.add(present_ire);
      if (present_ire)
        list.add(ire);

      boolean present_ace = true && (isSetAce());
      list.add(present_ace);
      if (present_ace)
        list.add(ace);

      boolean present_ase = true && (isSetAse());
      list.add(present_ase);
      if (present_ase)
        list.add(ase);

      boolean present_ae = true && (isSetAe());
      list.add(present_ae);
      if (present_ae)
        list.add(ae);

      return list.hashCode();
    }

    @Override
    public int compareTo(searchExperimentsByApplication_result other) {
      if (!getClass().equals(other.getClass())) {
        return getClass().getName().compareTo(other.getClass().getName());
      }

      int lastComparison = 0;

      lastComparison = Boolean.valueOf(isSetSuccess()).compareTo(other.isSetSuccess());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetSuccess()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.success, other.success);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = Boolean.valueOf(isSetIre()).compareTo(other.isSetIre());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetIre()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.ire, other.ire);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = Boolean.valueOf(isSetAce()).compareTo(other.isSetAce());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetAce()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.ace, other.ace);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = Boolean.valueOf(isSetAse()).compareTo(other.isSetAse());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetAse()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.ase, other.ase);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = 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 {
      schemes.get(iprot.getScheme()).getScheme().read(iprot, this);
    }

    public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException {
      schemes.get(oprot.getScheme()).getScheme().write(oprot, this);
      }

    @Override
    public String toString() {
      StringBuilder sb = new StringBuilder("searchExperimentsByApplication_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("ire:");
      if (this.ire == null) {
        sb.append("null");
      } else {
        sb.append(this.ire);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("ace:");
      if (this.ace == null) {
        sb.append("null");
      } else {
        sb.append(this.ace);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("ase:");
      if (this.ase == null) {
        sb.append("null");
      } else {
        sb.append(this.ase);
      }
      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, 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 searchExperimentsByApplication_resultStandardSchemeFactory implements SchemeFactory {
      public searchExperimentsByApplication_resultStandardScheme getScheme() {
        return new searchExperimentsByApplication_resultStandardScheme();
      }
    }

    private static class searchExperimentsByApplication_resultStandardScheme extends StandardScheme<searchExperimentsByApplication_result> {

      public void read(org.apache.thrift.protocol.TProtocol iprot, searchExperimentsByApplication_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 _list58 = iprot.readListBegin();
                  struct.success = new ArrayList<org.apache.airavata.model.experiment.ExperimentSummaryModel>(_list58.size);
                  org.apache.airavata.model.experiment.ExperimentSummaryModel _elem59;
                  for (int _i60 = 0; _i60 < _list58.size; ++_i60)
                  {
                    _elem59 = new org.apache.airavata.model.experiment.ExperimentSummaryModel();
                    _elem59.read(iprot);
                    struct.success.add(_elem59);
                  }
                  iprot.readListEnd();
                }
                struct.setSuccessIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 1: // IRE
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.ire = new org.apache.airavata.model.error.InvalidRequestException();
                struct.ire.read(iprot);
                struct.setIreIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 2: // ACE
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.ace = new org.apache.airavata.model.error.AiravataClientException();
                struct.ace.read(iprot);
                struct.setAceIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 3: // ASE
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.ase = new org.apache.airavata.model.error.AiravataSystemException();
                struct.ase.read(iprot);
                struct.setAseIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 4: // 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, searchExperimentsByApplication_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.experiment.ExperimentSummaryModel _iter61 : struct.success)
            {
              _iter61.write(oprot);
            }
            oprot.writeListEnd();
          }
          oprot.writeFieldEnd();
        }
        if (struct.ire != null) {
          oprot.writeFieldBegin(IRE_FIELD_DESC);
          struct.ire.write(oprot);
          oprot.writeFieldEnd();
        }
        if (struct.ace != null) {
          oprot.writeFieldBegin(ACE_FIELD_DESC);
          struct.ace.write(oprot);
          oprot.writeFieldEnd();
        }
        if (struct.ase != null) {
          oprot.writeFieldBegin(ASE_FIELD_DESC);
          struct.ase.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 searchExperimentsByApplication_resultTupleSchemeFactory implements SchemeFactory {
      public searchExperimentsByApplication_resultTupleScheme getScheme() {
        return new searchExperimentsByApplication_resultTupleScheme();
      }
    }

    private static class searchExperimentsByApplication_resultTupleScheme extends TupleScheme<searchExperimentsByApplication_result> {

      @Override
      public void write(org.apache.thrift.protocol.TProtocol prot, searchExperimentsByApplication_result struct) throws org.apache.thrift.TException {
        TTupleProtocol oprot = (TTupleProtocol) prot;
        BitSet optionals = new BitSet();
        if (struct.isSetSuccess()) {
          optionals.set(0);
        }
        if (struct.isSetIre()) {
          optionals.set(1);
        }
        if (struct.isSetAce()) {
          optionals.set(2);
        }
        if (struct.isSetAse()) {
          optionals.set(3);
        }
        if (struct.isSetAe()) {
          optionals.set(4);
        }
        oprot.writeBitSet(optionals, 5);
        if (struct.isSetSuccess()) {
          {
            oprot.writeI32(struct.success.size());
            for (org.apache.airavata.model.experiment.ExperimentSummaryModel _iter62 : struct.success)
            {
              _iter62.write(oprot);
            }
          }
        }
        if (struct.isSetIre()) {
          struct.ire.write(oprot);
        }
        if (struct.isSetAce()) {
          struct.ace.write(oprot);
        }
        if (struct.isSetAse()) {
          struct.ase.write(oprot);
        }
        if (struct.isSetAe()) {
          struct.ae.write(oprot);
        }
      }

      @Override
      public void read(org.apache.thrift.protocol.TProtocol prot, searchExperimentsByApplication_result struct) throws org.apache.thrift.TException {
        TTupleProtocol iprot = (TTupleProtocol) prot;
        BitSet incoming = iprot.readBitSet(5);
        if (incoming.get(0)) {
          {
            org.apache.thrift.protocol.TList _list63 = new org.apache.thrift.protocol.TList(org.apache.thrift.protocol.TType.STRUCT, iprot.readI32());
            struct.success = new ArrayList<org.apache.airavata.model.experiment.ExperimentSummaryModel>(_list63.size);
            org.apache.airavata.model.experiment.ExperimentSummaryModel _elem64;
            for (int _i65 = 0; _i65 < _list63.size; ++_i65)
            {
              _elem64 = new org.apache.airavata.model.experiment.ExperimentSummaryModel();
              _elem64.read(iprot);
              struct.success.add(_elem64);
            }
          }
          struct.setSuccessIsSet(true);
        }
        if (incoming.get(1)) {
          struct.ire = new org.apache.airavata.model.error.InvalidRequestException();
          struct.ire.read(iprot);
          struct.setIreIsSet(true);
        }
        if (incoming.get(2)) {
          struct.ace = new org.apache.airavata.model.error.AiravataClientException();
          struct.ace.read(iprot);
          struct.setAceIsSet(true);
        }
        if (incoming.get(3)) {
          struct.ase = new org.apache.airavata.model.error.AiravataSystemException();
          struct.ase.read(iprot);
          struct.setAseIsSet(true);
        }
        if (incoming.get(4)) {
          struct.ae = new org.apache.airavata.model.error.AuthorizationException();
          struct.ae.read(iprot);
          struct.setAeIsSet(true);
        }
      }
    }

  }

  public static class searchExperimentsByStatus_args implements org.apache.thrift.TBase<searchExperimentsByStatus_args, searchExperimentsByStatus_args._Fields>, java.io.Serializable, Cloneable, Comparable<searchExperimentsByStatus_args>   {
    private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("searchExperimentsByStatus_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.protocol.TField USER_NAME_FIELD_DESC = new org.apache.thrift.protocol.TField("userName", org.apache.thrift.protocol.TType.STRING, (short)3);
    private static final org.apache.thrift.protocol.TField EXPERIMENT_STATE_FIELD_DESC = new org.apache.thrift.protocol.TField("experimentState", org.apache.thrift.protocol.TType.I32, (short)4);
    private static final org.apache.thrift.protocol.TField LIMIT_FIELD_DESC = new org.apache.thrift.protocol.TField("limit", org.apache.thrift.protocol.TType.I32, (short)5);
    private static final org.apache.thrift.protocol.TField OFFSET_FIELD_DESC = new org.apache.thrift.protocol.TField("offset", org.apache.thrift.protocol.TType.I32, (short)6);

    private static final Map<Class<? extends IScheme>, SchemeFactory> schemes = new HashMap<Class<? extends IScheme>, SchemeFactory>();
    static {
      schemes.put(StandardScheme.class, new searchExperimentsByStatus_argsStandardSchemeFactory());
      schemes.put(TupleScheme.class, new searchExperimentsByStatus_argsTupleSchemeFactory());
    }

    public org.apache.airavata.model.security.AuthzToken authzToken; // required
    public String gatewayId; // required
    public String userName; // required
    /**
     * 
     * @see org.apache.airavata.model.status.ExperimentState
     */
    public org.apache.airavata.model.status.ExperimentState experimentState; // required
    public int limit; // required
    public int offset; // required

    /** 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"),
      USER_NAME((short)3, "userName"),
      /**
       * 
       * @see org.apache.airavata.model.status.ExperimentState
       */
      EXPERIMENT_STATE((short)4, "experimentState"),
      LIMIT((short)5, "limit"),
      OFFSET((short)6, "offset");

      private static final Map<String, _Fields> byName = new HashMap<String, _Fields>();

      static {
        for (_Fields field : EnumSet.allOf(_Fields.class)) {
          byName.put(field.getFieldName(), field);
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, or null if its not found.
       */
      public static _Fields findByThriftId(int fieldId) {
        switch(fieldId) {
          case 1: // AUTHZ_TOKEN
            return AUTHZ_TOKEN;
          case 2: // GATEWAY_ID
            return GATEWAY_ID;
          case 3: // USER_NAME
            return USER_NAME;
          case 4: // EXPERIMENT_STATE
            return EXPERIMENT_STATE;
          case 5: // LIMIT
            return LIMIT;
          case 6: // OFFSET
            return OFFSET;
          default:
            return null;
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, throwing an exception
       * if it is not found.
       */
      public static _Fields findByThriftIdOrThrow(int fieldId) {
        _Fields fields = findByThriftId(fieldId);
        if (fields == null) throw new IllegalArgumentException("Field " + fieldId + " doesn't exist!");
        return fields;
      }

      /**
       * Find the _Fields constant that matches name, or null if its not found.
       */
      public static _Fields findByName(String name) {
        return byName.get(name);
      }

      private final short _thriftId;
      private final String _fieldName;

      _Fields(short thriftId, String fieldName) {
        _thriftId = thriftId;
        _fieldName = fieldName;
      }

      public short getThriftFieldId() {
        return _thriftId;
      }

      public String getFieldName() {
        return _fieldName;
      }
    }

    // isset id assignments
    private static final int __LIMIT_ISSET_ID = 0;
    private static final int __OFFSET_ISSET_ID = 1;
    private byte __isset_bitfield = 0;
    public static final Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
    static {
      Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new EnumMap<_Fields, org.apache.thrift.meta_data.FieldMetaData>(_Fields.class);
      tmpMap.put(_Fields.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)));
      tmpMap.put(_Fields.USER_NAME, new org.apache.thrift.meta_data.FieldMetaData("userName", org.apache.thrift.TFieldRequirementType.REQUIRED, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING)));
      tmpMap.put(_Fields.EXPERIMENT_STATE, new org.apache.thrift.meta_data.FieldMetaData("experimentState", org.apache.thrift.TFieldRequirementType.REQUIRED, 
          new org.apache.thrift.meta_data.EnumMetaData(org.apache.thrift.protocol.TType.ENUM, org.apache.airavata.model.status.ExperimentState.class)));
      tmpMap.put(_Fields.LIMIT, new org.apache.thrift.meta_data.FieldMetaData("limit", org.apache.thrift.TFieldRequirementType.REQUIRED, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.I32)));
      tmpMap.put(_Fields.OFFSET, new org.apache.thrift.meta_data.FieldMetaData("offset", org.apache.thrift.TFieldRequirementType.REQUIRED, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.I32)));
      metaDataMap = Collections.unmodifiableMap(tmpMap);
      org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(searchExperimentsByStatus_args.class, metaDataMap);
    }

    public searchExperimentsByStatus_args() {
    }

    public searchExperimentsByStatus_args(
      org.apache.airavata.model.security.AuthzToken authzToken,
      String gatewayId,
      String userName,
      org.apache.airavata.model.status.ExperimentState experimentState,
      int limit,
      int offset)
    {
      this();
      this.authzToken = authzToken;
      this.gatewayId = gatewayId;
      this.userName = userName;
      this.experimentState = experimentState;
      this.limit = limit;
      setLimitIsSet(true);
      this.offset = offset;
      setOffsetIsSet(true);
    }

    /**
     * Performs a deep copy on <i>other</i>.
     */
    public searchExperimentsByStatus_args(searchExperimentsByStatus_args other) {
      __isset_bitfield = other.__isset_bitfield;
      if (other.isSetAuthzToken()) {
        this.authzToken = new org.apache.airavata.model.security.AuthzToken(other.authzToken);
      }
      if (other.isSetGatewayId()) {
        this.gatewayId = other.gatewayId;
      }
      if (other.isSetUserName()) {
        this.userName = other.userName;
      }
      if (other.isSetExperimentState()) {
        this.experimentState = other.experimentState;
      }
      this.limit = other.limit;
      this.offset = other.offset;
    }

    public searchExperimentsByStatus_args deepCopy() {
      return new searchExperimentsByStatus_args(this);
    }

    @Override
    public void clear() {
      this.authzToken = null;
      this.gatewayId = null;
      this.userName = null;
      this.experimentState = null;
      setLimitIsSet(false);
      this.limit = 0;
      setOffsetIsSet(false);
      this.offset = 0;
    }

    public org.apache.airavata.model.security.AuthzToken getAuthzToken() {
      return this.authzToken;
    }

    public searchExperimentsByStatus_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 String getGatewayId() {
      return this.gatewayId;
    }

    public searchExperimentsByStatus_args setGatewayId(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 String getUserName() {
      return this.userName;
    }

    public searchExperimentsByStatus_args setUserName(String userName) {
      this.userName = userName;
      return this;
    }

    public void unsetUserName() {
      this.userName = null;
    }

    /** Returns true if field userName is set (has been assigned a value) and false otherwise */
    public boolean isSetUserName() {
      return this.userName != null;
    }

    public void setUserNameIsSet(boolean value) {
      if (!value) {
        this.userName = null;
      }
    }

    /**
     * 
     * @see org.apache.airavata.model.status.ExperimentState
     */
    public org.apache.airavata.model.status.ExperimentState getExperimentState() {
      return this.experimentState;
    }

    /**
     * 
     * @see org.apache.airavata.model.status.ExperimentState
     */
    public searchExperimentsByStatus_args setExperimentState(org.apache.airavata.model.status.ExperimentState experimentState) {
      this.experimentState = experimentState;
      return this;
    }

    public void unsetExperimentState() {
      this.experimentState = null;
    }

    /** Returns true if field experimentState is set (has been assigned a value) and false otherwise */
    public boolean isSetExperimentState() {
      return this.experimentState != null;
    }

    public void setExperimentStateIsSet(boolean value) {
      if (!value) {
        this.experimentState = null;
      }
    }

    public int getLimit() {
      return this.limit;
    }

    public searchExperimentsByStatus_args setLimit(int limit) {
      this.limit = limit;
      setLimitIsSet(true);
      return this;
    }

    public void unsetLimit() {
      __isset_bitfield = EncodingUtils.clearBit(__isset_bitfield, __LIMIT_ISSET_ID);
    }

    /** Returns true if field limit is set (has been assigned a value) and false otherwise */
    public boolean isSetLimit() {
      return EncodingUtils.testBit(__isset_bitfield, __LIMIT_ISSET_ID);
    }

    public void setLimitIsSet(boolean value) {
      __isset_bitfield = EncodingUtils.setBit(__isset_bitfield, __LIMIT_ISSET_ID, value);
    }

    public int getOffset() {
      return this.offset;
    }

    public searchExperimentsByStatus_args setOffset(int offset) {
      this.offset = offset;
      setOffsetIsSet(true);
      return this;
    }

    public void unsetOffset() {
      __isset_bitfield = EncodingUtils.clearBit(__isset_bitfield, __OFFSET_ISSET_ID);
    }

    /** Returns true if field offset is set (has been assigned a value) and false otherwise */
    public boolean isSetOffset() {
      return EncodingUtils.testBit(__isset_bitfield, __OFFSET_ISSET_ID);
    }

    public void setOffsetIsSet(boolean value) {
      __isset_bitfield = EncodingUtils.setBit(__isset_bitfield, __OFFSET_ISSET_ID, value);
    }

    public void setFieldValue(_Fields field, 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((String)value);
        }
        break;

      case USER_NAME:
        if (value == null) {
          unsetUserName();
        } else {
          setUserName((String)value);
        }
        break;

      case EXPERIMENT_STATE:
        if (value == null) {
          unsetExperimentState();
        } else {
          setExperimentState((org.apache.airavata.model.status.ExperimentState)value);
        }
        break;

      case LIMIT:
        if (value == null) {
          unsetLimit();
        } else {
          setLimit((Integer)value);
        }
        break;

      case OFFSET:
        if (value == null) {
          unsetOffset();
        } else {
          setOffset((Integer)value);
        }
        break;

      }
    }

    public Object getFieldValue(_Fields field) {
      switch (field) {
      case AUTHZ_TOKEN:
        return getAuthzToken();

      case GATEWAY_ID:
        return getGatewayId();

      case USER_NAME:
        return getUserName();

      case EXPERIMENT_STATE:
        return getExperimentState();

      case LIMIT:
        return Integer.valueOf(getLimit());

      case OFFSET:
        return Integer.valueOf(getOffset());

      }
      throw new IllegalStateException();
    }

    /** Returns true if field corresponding to fieldID is set (has been assigned a value) and false otherwise */
    public boolean isSet(_Fields field) {
      if (field == null) {
        throw new IllegalArgumentException();
      }

      switch (field) {
      case AUTHZ_TOKEN:
        return isSetAuthzToken();
      case GATEWAY_ID:
        return isSetGatewayId();
      case USER_NAME:
        return isSetUserName();
      case EXPERIMENT_STATE:
        return isSetExperimentState();
      case LIMIT:
        return isSetLimit();
      case OFFSET:
        return isSetOffset();
      }
      throw new IllegalStateException();
    }

    @Override
    public boolean equals(Object that) {
      if (that == null)
        return false;
      if (that instanceof searchExperimentsByStatus_args)
        return this.equals((searchExperimentsByStatus_args)that);
      return false;
    }

    public boolean equals(searchExperimentsByStatus_args that) {
      if (that == null)
        return false;

      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;
      }

      boolean this_present_userName = true && this.isSetUserName();
      boolean that_present_userName = true && that.isSetUserName();
      if (this_present_userName || that_present_userName) {
        if (!(this_present_userName && that_present_userName))
          return false;
        if (!this.userName.equals(that.userName))
          return false;
      }

      boolean this_present_experimentState = true && this.isSetExperimentState();
      boolean that_present_experimentState = true && that.isSetExperimentState();
      if (this_present_experimentState || that_present_experimentState) {
        if (!(this_present_experimentState && that_present_experimentState))
          return false;
        if (!this.experimentState.equals(that.experimentState))
          return false;
      }

      boolean this_present_limit = true;
      boolean that_present_limit = true;
      if (this_present_limit || that_present_limit) {
        if (!(this_present_limit && that_present_limit))
          return false;
        if (this.limit != that.limit)
          return false;
      }

      boolean this_present_offset = true;
      boolean that_present_offset = true;
      if (this_present_offset || that_present_offset) {
        if (!(this_present_offset && that_present_offset))
          return false;
        if (this.offset != that.offset)
          return false;
      }

      return true;
    }

    @Override
    public int hashCode() {
      List<Object> list = new ArrayList<Object>();

      boolean present_authzToken = true && (isSetAuthzToken());
      list.add(present_authzToken);
      if (present_authzToken)
        list.add(authzToken);

      boolean present_gatewayId = true && (isSetGatewayId());
      list.add(present_gatewayId);
      if (present_gatewayId)
        list.add(gatewayId);

      boolean present_userName = true && (isSetUserName());
      list.add(present_userName);
      if (present_userName)
        list.add(userName);

      boolean present_experimentState = true && (isSetExperimentState());
      list.add(present_experimentState);
      if (present_experimentState)
        list.add(experimentState.getValue());

      boolean present_limit = true;
      list.add(present_limit);
      if (present_limit)
        list.add(limit);

      boolean present_offset = true;
      list.add(present_offset);
      if (present_offset)
        list.add(offset);

      return list.hashCode();
    }

    @Override
    public int compareTo(searchExperimentsByStatus_args other) {
      if (!getClass().equals(other.getClass())) {
        return getClass().getName().compareTo(other.getClass().getName());
      }

      int lastComparison = 0;

      lastComparison = 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 = 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;
        }
      }
      lastComparison = Boolean.valueOf(isSetUserName()).compareTo(other.isSetUserName());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetUserName()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.userName, other.userName);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = Boolean.valueOf(isSetExperimentState()).compareTo(other.isSetExperimentState());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetExperimentState()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.experimentState, other.experimentState);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = Boolean.valueOf(isSetLimit()).compareTo(other.isSetLimit());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetLimit()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.limit, other.limit);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = Boolean.valueOf(isSetOffset()).compareTo(other.isSetOffset());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetOffset()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.offset, other.offset);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      return 0;
    }

    public _Fields fieldForId(int fieldId) {
      return _Fields.findByThriftId(fieldId);
    }

    public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
      schemes.get(iprot.getScheme()).getScheme().read(iprot, this);
    }

    public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException {
      schemes.get(oprot.getScheme()).getScheme().write(oprot, this);
    }

    @Override
    public String toString() {
      StringBuilder sb = new StringBuilder("searchExperimentsByStatus_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;
      if (!first) sb.append(", ");
      sb.append("userName:");
      if (this.userName == null) {
        sb.append("null");
      } else {
        sb.append(this.userName);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("experimentState:");
      if (this.experimentState == null) {
        sb.append("null");
      } else {
        sb.append(this.experimentState);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("limit:");
      sb.append(this.limit);
      first = false;
      if (!first) sb.append(", ");
      sb.append("offset:");
      sb.append(this.offset);
      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());
      }
      if (userName == null) {
        throw new org.apache.thrift.protocol.TProtocolException("Required field 'userName' was not present! Struct: " + toString());
      }
      if (experimentState == null) {
        throw new org.apache.thrift.protocol.TProtocolException("Required field 'experimentState' was not present! Struct: " + toString());
      }
      // alas, we cannot check 'limit' because it's a primitive and you chose the non-beans generator.
      // alas, we cannot check 'offset' because it's a primitive and you chose the non-beans generator.
      // 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, 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 searchExperimentsByStatus_argsStandardSchemeFactory implements SchemeFactory {
      public searchExperimentsByStatus_argsStandardScheme getScheme() {
        return new searchExperimentsByStatus_argsStandardScheme();
      }
    }

    private static class searchExperimentsByStatus_argsStandardScheme extends StandardScheme<searchExperimentsByStatus_args> {

      public void read(org.apache.thrift.protocol.TProtocol iprot, searchExperimentsByStatus_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;
            case 3: // USER_NAME
              if (schemeField.type == org.apache.thrift.protocol.TType.STRING) {
                struct.userName = iprot.readString();
                struct.setUserNameIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 4: // EXPERIMENT_STATE
              if (schemeField.type == org.apache.thrift.protocol.TType.I32) {
                struct.experimentState = org.apache.airavata.model.status.ExperimentState.findByValue(iprot.readI32());
                struct.setExperimentStateIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 5: // LIMIT
              if (schemeField.type == org.apache.thrift.protocol.TType.I32) {
                struct.limit = iprot.readI32();
                struct.setLimitIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 6: // OFFSET
              if (schemeField.type == org.apache.thrift.protocol.TType.I32) {
                struct.offset = iprot.readI32();
                struct.setOffsetIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            default:
              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
          }
          iprot.readFieldEnd();
        }
        iprot.readStructEnd();

        // check for required fields of primitive type, which can't be checked in the validate method
        if (!struct.isSetLimit()) {
          throw new org.apache.thrift.protocol.TProtocolException("Required field 'limit' was not found in serialized data! Struct: " + toString());
        }
        if (!struct.isSetOffset()) {
          throw new org.apache.thrift.protocol.TProtocolException("Required field 'offset' was not found in serialized data! Struct: " + toString());
        }
        struct.validate();
      }

      public void write(org.apache.thrift.protocol.TProtocol oprot, searchExperimentsByStatus_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();
        }
        if (struct.userName != null) {
          oprot.writeFieldBegin(USER_NAME_FIELD_DESC);
          oprot.writeString(struct.userName);
          oprot.writeFieldEnd();
        }
        if (struct.experimentState != null) {
          oprot.writeFieldBegin(EXPERIMENT_STATE_FIELD_DESC);
          oprot.writeI32(struct.experimentState.getValue());
          oprot.writeFieldEnd();
        }
        oprot.writeFieldBegin(LIMIT_FIELD_DESC);
        oprot.writeI32(struct.limit);
        oprot.writeFieldEnd();
        oprot.writeFieldBegin(OFFSET_FIELD_DESC);
        oprot.writeI32(struct.offset);
        oprot.writeFieldEnd();
        oprot.writeFieldStop();
        oprot.writeStructEnd();
      }

    }

    private static class searchExperimentsByStatus_argsTupleSchemeFactory implements SchemeFactory {
      public searchExperimentsByStatus_argsTupleScheme getScheme() {
        return new searchExperimentsByStatus_argsTupleScheme();
      }
    }

    private static class searchExperimentsByStatus_argsTupleScheme extends TupleScheme<searchExperimentsByStatus_args> {

      @Override
      public void write(org.apache.thrift.protocol.TProtocol prot, searchExperimentsByStatus_args struct) throws org.apache.thrift.TException {
        TTupleProtocol oprot = (TTupleProtocol) prot;
        struct.authzToken.write(oprot);
        oprot.writeString(struct.gatewayId);
        oprot.writeString(struct.userName);
        oprot.writeI32(struct.experimentState.getValue());
        oprot.writeI32(struct.limit);
        oprot.writeI32(struct.offset);
      }

      @Override
      public void read(org.apache.thrift.protocol.TProtocol prot, searchExperimentsByStatus_args struct) throws org.apache.thrift.TException {
        TTupleProtocol iprot = (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);
        struct.userName = iprot.readString();
        struct.setUserNameIsSet(true);
        struct.experimentState = org.apache.airavata.model.status.ExperimentState.findByValue(iprot.readI32());
        struct.setExperimentStateIsSet(true);
        struct.limit = iprot.readI32();
        struct.setLimitIsSet(true);
        struct.offset = iprot.readI32();
        struct.setOffsetIsSet(true);
      }
    }

  }

  public static class searchExperimentsByStatus_result implements org.apache.thrift.TBase<searchExperimentsByStatus_result, searchExperimentsByStatus_result._Fields>, java.io.Serializable, Cloneable, Comparable<searchExperimentsByStatus_result>   {
    private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("searchExperimentsByStatus_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 IRE_FIELD_DESC = new org.apache.thrift.protocol.TField("ire", org.apache.thrift.protocol.TType.STRUCT, (short)1);
    private static final org.apache.thrift.protocol.TField ACE_FIELD_DESC = new org.apache.thrift.protocol.TField("ace", org.apache.thrift.protocol.TType.STRUCT, (short)2);
    private static final org.apache.thrift.protocol.TField ASE_FIELD_DESC = new org.apache.thrift.protocol.TField("ase", org.apache.thrift.protocol.TType.STRUCT, (short)3);
    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)4);

    private static final Map<Class<? extends IScheme>, SchemeFactory> schemes = new HashMap<Class<? extends IScheme>, SchemeFactory>();
    static {
      schemes.put(StandardScheme.class, new searchExperimentsByStatus_resultStandardSchemeFactory());
      schemes.put(TupleScheme.class, new searchExperimentsByStatus_resultTupleSchemeFactory());
    }

    public List<org.apache.airavata.model.experiment.ExperimentSummaryModel> success; // required
    public org.apache.airavata.model.error.InvalidRequestException ire; // required
    public org.apache.airavata.model.error.AiravataClientException ace; // required
    public org.apache.airavata.model.error.AiravataSystemException ase; // 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"),
      IRE((short)1, "ire"),
      ACE((short)2, "ace"),
      ASE((short)3, "ase"),
      AE((short)4, "ae");

      private static final Map<String, _Fields> byName = new HashMap<String, _Fields>();

      static {
        for (_Fields field : EnumSet.allOf(_Fields.class)) {
          byName.put(field.getFieldName(), field);
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, or null if its not found.
       */
      public static _Fields findByThriftId(int fieldId) {
        switch(fieldId) {
          case 0: // SUCCESS
            return SUCCESS;
          case 1: // IRE
            return IRE;
          case 2: // ACE
            return ACE;
          case 3: // ASE
            return ASE;
          case 4: // 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 IllegalArgumentException("Field " + fieldId + " doesn't exist!");
        return fields;
      }

      /**
       * Find the _Fields constant that matches name, or null if its not found.
       */
      public static _Fields findByName(String name) {
        return byName.get(name);
      }

      private final short _thriftId;
      private final String _fieldName;

      _Fields(short thriftId, String fieldName) {
        _thriftId = thriftId;
        _fieldName = fieldName;
      }

      public short getThriftFieldId() {
        return _thriftId;
      }

      public String getFieldName() {
        return _fieldName;
      }
    }

    // isset id assignments
    public static final Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
    static {
      Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new EnumMap<_Fields, org.apache.thrift.meta_data.FieldMetaData>(_Fields.class);
      tmpMap.put(_Fields.SUCCESS, new org.apache.thrift.meta_data.FieldMetaData("success", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.ListMetaData(org.apache.thrift.protocol.TType.LIST, 
              new org.apache.thrift.meta_data.StructMetaData(org.apache.thrift.protocol.TType.STRUCT, org.apache.airavata.model.experiment.ExperimentSummaryModel.class))));
      tmpMap.put(_Fields.IRE, new org.apache.thrift.meta_data.FieldMetaData("ire", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRUCT)));
      tmpMap.put(_Fields.ACE, new org.apache.thrift.meta_data.FieldMetaData("ace", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRUCT)));
      tmpMap.put(_Fields.ASE, new org.apache.thrift.meta_data.FieldMetaData("ase", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRUCT)));
      tmpMap.put(_Fields.AE, new org.apache.thrift.meta_data.FieldMetaData("ae", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRUCT)));
      metaDataMap = Collections.unmodifiableMap(tmpMap);
      org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(searchExperimentsByStatus_result.class, metaDataMap);
    }

    public searchExperimentsByStatus_result() {
    }

    public searchExperimentsByStatus_result(
      List<org.apache.airavata.model.experiment.ExperimentSummaryModel> success,
      org.apache.airavata.model.error.InvalidRequestException ire,
      org.apache.airavata.model.error.AiravataClientException ace,
      org.apache.airavata.model.error.AiravataSystemException ase,
      org.apache.airavata.model.error.AuthorizationException ae)
    {
      this();
      this.success = success;
      this.ire = ire;
      this.ace = ace;
      this.ase = ase;
      this.ae = ae;
    }

    /**
     * Performs a deep copy on <i>other</i>.
     */
    public searchExperimentsByStatus_result(searchExperimentsByStatus_result other) {
      if (other.isSetSuccess()) {
        List<org.apache.airavata.model.experiment.ExperimentSummaryModel> __this__success = new ArrayList<org.apache.airavata.model.experiment.ExperimentSummaryModel>(other.success.size());
        for (org.apache.airavata.model.experiment.ExperimentSummaryModel other_element : other.success) {
          __this__success.add(new org.apache.airavata.model.experiment.ExperimentSummaryModel(other_element));
        }
        this.success = __this__success;
      }
      if (other.isSetIre()) {
        this.ire = new org.apache.airavata.model.error.InvalidRequestException(other.ire);
      }
      if (other.isSetAce()) {
        this.ace = new org.apache.airavata.model.error.AiravataClientException(other.ace);
      }
      if (other.isSetAse()) {
        this.ase = new org.apache.airavata.model.error.AiravataSystemException(other.ase);
      }
      if (other.isSetAe()) {
        this.ae = new org.apache.airavata.model.error.AuthorizationException(other.ae);
      }
    }

    public searchExperimentsByStatus_result deepCopy() {
      return new searchExperimentsByStatus_result(this);
    }

    @Override
    public void clear() {
      this.success = null;
      this.ire = null;
      this.ace = null;
      this.ase = null;
      this.ae = null;
    }

    public int getSuccessSize() {
      return (this.success == null) ? 0 : this.success.size();
    }

    public java.util.Iterator<org.apache.airavata.model.experiment.ExperimentSummaryModel> getSuccessIterator() {
      return (this.success == null) ? null : this.success.iterator();
    }

    public void addToSuccess(org.apache.airavata.model.experiment.ExperimentSummaryModel elem) {
      if (this.success == null) {
        this.success = new ArrayList<org.apache.airavata.model.experiment.ExperimentSummaryModel>();
      }
      this.success.add(elem);
    }

    public List<org.apache.airavata.model.experiment.ExperimentSummaryModel> getSuccess() {
      return this.success;
    }

    public searchExperimentsByStatus_result setSuccess(List<org.apache.airavata.model.experiment.ExperimentSummaryModel> 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.model.error.InvalidRequestException getIre() {
      return this.ire;
    }

    public searchExperimentsByStatus_result setIre(org.apache.airavata.model.error.InvalidRequestException ire) {
      this.ire = ire;
      return this;
    }

    public void unsetIre() {
      this.ire = null;
    }

    /** Returns true if field ire is set (has been assigned a value) and false otherwise */
    public boolean isSetIre() {
      return this.ire != null;
    }

    public void setIreIsSet(boolean value) {
      if (!value) {
        this.ire = null;
      }
    }

    public org.apache.airavata.model.error.AiravataClientException getAce() {
      return this.ace;
    }

    public searchExperimentsByStatus_result setAce(org.apache.airavata.model.error.AiravataClientException ace) {
      this.ace = ace;
      return this;
    }

    public void unsetAce() {
      this.ace = null;
    }

    /** Returns true if field ace is set (has been assigned a value) and false otherwise */
    public boolean isSetAce() {
      return this.ace != null;
    }

    public void setAceIsSet(boolean value) {
      if (!value) {
        this.ace = null;
      }
    }

    public org.apache.airavata.model.error.AiravataSystemException getAse() {
      return this.ase;
    }

    public searchExperimentsByStatus_result setAse(org.apache.airavata.model.error.AiravataSystemException ase) {
      this.ase = ase;
      return this;
    }

    public void unsetAse() {
      this.ase = null;
    }

    /** Returns true if field ase is set (has been assigned a value) and false otherwise */
    public boolean isSetAse() {
      return this.ase != null;
    }

    public void setAseIsSet(boolean value) {
      if (!value) {
        this.ase = null;
      }
    }

    public org.apache.airavata.model.error.AuthorizationException getAe() {
      return this.ae;
    }

    public searchExperimentsByStatus_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, Object value) {
      switch (field) {
      case SUCCESS:
        if (value == null) {
          unsetSuccess();
        } else {
          setSuccess((List<org.apache.airavata.model.experiment.ExperimentSummaryModel>)value);
        }
        break;

      case IRE:
        if (value == null) {
          unsetIre();
        } else {
          setIre((org.apache.airavata.model.error.InvalidRequestException)value);
        }
        break;

      case ACE:
        if (value == null) {
          unsetAce();
        } else {
          setAce((org.apache.airavata.model.error.AiravataClientException)value);
        }
        break;

      case ASE:
        if (value == null) {
          unsetAse();
        } else {
          setAse((org.apache.airavata.model.error.AiravataSystemException)value);
        }
        break;

      case AE:
        if (value == null) {
          unsetAe();
        } else {
          setAe((org.apache.airavata.model.error.AuthorizationException)value);
        }
        break;

      }
    }

    public Object getFieldValue(_Fields field) {
      switch (field) {
      case SUCCESS:
        return getSuccess();

      case IRE:
        return getIre();

      case ACE:
        return getAce();

      case ASE:
        return getAse();

      case AE:
        return getAe();

      }
      throw new IllegalStateException();
    }

    /** Returns true if field corresponding to fieldID is set (has been assigned a value) and false otherwise */
    public boolean isSet(_Fields field) {
      if (field == null) {
        throw new IllegalArgumentException();
      }

      switch (field) {
      case SUCCESS:
        return isSetSuccess();
      case IRE:
        return isSetIre();
      case ACE:
        return isSetAce();
      case ASE:
        return isSetAse();
      case AE:
        return isSetAe();
      }
      throw new IllegalStateException();
    }

    @Override
    public boolean equals(Object that) {
      if (that == null)
        return false;
      if (that instanceof searchExperimentsByStatus_result)
        return this.equals((searchExperimentsByStatus_result)that);
      return false;
    }

    public boolean equals(searchExperimentsByStatus_result that) {
      if (that == null)
        return false;

      boolean this_present_success = true && this.isSetSuccess();
      boolean that_present_success = true && that.isSetSuccess();
      if (this_present_success || that_present_success) {
        if (!(this_present_success && that_present_success))
          return false;
        if (!this.success.equals(that.success))
          return false;
      }

      boolean this_present_ire = true && this.isSetIre();
      boolean that_present_ire = true && that.isSetIre();
      if (this_present_ire || that_present_ire) {
        if (!(this_present_ire && that_present_ire))
          return false;
        if (!this.ire.equals(that.ire))
          return false;
      }

      boolean this_present_ace = true && this.isSetAce();
      boolean that_present_ace = true && that.isSetAce();
      if (this_present_ace || that_present_ace) {
        if (!(this_present_ace && that_present_ace))
          return false;
        if (!this.ace.equals(that.ace))
          return false;
      }

      boolean this_present_ase = true && this.isSetAse();
      boolean that_present_ase = true && that.isSetAse();
      if (this_present_ase || that_present_ase) {
        if (!(this_present_ase && that_present_ase))
          return false;
        if (!this.ase.equals(that.ase))
          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() {
      List<Object> list = new ArrayList<Object>();

      boolean present_success = true && (isSetSuccess());
      list.add(present_success);
      if (present_success)
        list.add(success);

      boolean present_ire = true && (isSetIre());
      list.add(present_ire);
      if (present_ire)
        list.add(ire);

      boolean present_ace = true && (isSetAce());
      list.add(present_ace);
      if (present_ace)
        list.add(ace);

      boolean present_ase = true && (isSetAse());
      list.add(present_ase);
      if (present_ase)
        list.add(ase);

      boolean present_ae = true && (isSetAe());
      list.add(present_ae);
      if (present_ae)
        list.add(ae);

      return list.hashCode();
    }

    @Override
    public int compareTo(searchExperimentsByStatus_result other) {
      if (!getClass().equals(other.getClass())) {
        return getClass().getName().compareTo(other.getClass().getName());
      }

      int lastComparison = 0;

      lastComparison = Boolean.valueOf(isSetSuccess()).compareTo(other.isSetSuccess());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetSuccess()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.success, other.success);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = Boolean.valueOf(isSetIre()).compareTo(other.isSetIre());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetIre()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.ire, other.ire);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = Boolean.valueOf(isSetAce()).compareTo(other.isSetAce());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetAce()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.ace, other.ace);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = Boolean.valueOf(isSetAse()).compareTo(other.isSetAse());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetAse()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.ase, other.ase);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = 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 {
      schemes.get(iprot.getScheme()).getScheme().read(iprot, this);
    }

    public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException {
      schemes.get(oprot.getScheme()).getScheme().write(oprot, this);
      }

    @Override
    public String toString() {
      StringBuilder sb = new StringBuilder("searchExperimentsByStatus_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("ire:");
      if (this.ire == null) {
        sb.append("null");
      } else {
        sb.append(this.ire);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("ace:");
      if (this.ace == null) {
        sb.append("null");
      } else {
        sb.append(this.ace);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("ase:");
      if (this.ase == null) {
        sb.append("null");
      } else {
        sb.append(this.ase);
      }
      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, 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 searchExperimentsByStatus_resultStandardSchemeFactory implements SchemeFactory {
      public searchExperimentsByStatus_resultStandardScheme getScheme() {
        return new searchExperimentsByStatus_resultStandardScheme();
      }
    }

    private static class searchExperimentsByStatus_resultStandardScheme extends StandardScheme<searchExperimentsByStatus_result> {

      public void read(org.apache.thrift.protocol.TProtocol iprot, searchExperimentsByStatus_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 _list66 = iprot.readListBegin();
                  struct.success = new ArrayList<org.apache.airavata.model.experiment.ExperimentSummaryModel>(_list66.size);
                  org.apache.airavata.model.experiment.ExperimentSummaryModel _elem67;
                  for (int _i68 = 0; _i68 < _list66.size; ++_i68)
                  {
                    _elem67 = new org.apache.airavata.model.experiment.ExperimentSummaryModel();
                    _elem67.read(iprot);
                    struct.success.add(_elem67);
                  }
                  iprot.readListEnd();
                }
                struct.setSuccessIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 1: // IRE
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.ire = new org.apache.airavata.model.error.InvalidRequestException();
                struct.ire.read(iprot);
                struct.setIreIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 2: // ACE
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.ace = new org.apache.airavata.model.error.AiravataClientException();
                struct.ace.read(iprot);
                struct.setAceIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 3: // ASE
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.ase = new org.apache.airavata.model.error.AiravataSystemException();
                struct.ase.read(iprot);
                struct.setAseIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 4: // 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, searchExperimentsByStatus_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.experiment.ExperimentSummaryModel _iter69 : struct.success)
            {
              _iter69.write(oprot);
            }
            oprot.writeListEnd();
          }
          oprot.writeFieldEnd();
        }
        if (struct.ire != null) {
          oprot.writeFieldBegin(IRE_FIELD_DESC);
          struct.ire.write(oprot);
          oprot.writeFieldEnd();
        }
        if (struct.ace != null) {
          oprot.writeFieldBegin(ACE_FIELD_DESC);
          struct.ace.write(oprot);
          oprot.writeFieldEnd();
        }
        if (struct.ase != null) {
          oprot.writeFieldBegin(ASE_FIELD_DESC);
          struct.ase.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 searchExperimentsByStatus_resultTupleSchemeFactory implements SchemeFactory {
      public searchExperimentsByStatus_resultTupleScheme getScheme() {
        return new searchExperimentsByStatus_resultTupleScheme();
      }
    }

    private static class searchExperimentsByStatus_resultTupleScheme extends TupleScheme<searchExperimentsByStatus_result> {

      @Override
      public void write(org.apache.thrift.protocol.TProtocol prot, searchExperimentsByStatus_result struct) throws org.apache.thrift.TException {
        TTupleProtocol oprot = (TTupleProtocol) prot;
        BitSet optionals = new BitSet();
        if (struct.isSetSuccess()) {
          optionals.set(0);
        }
        if (struct.isSetIre()) {
          optionals.set(1);
        }
        if (struct.isSetAce()) {
          optionals.set(2);
        }
        if (struct.isSetAse()) {
          optionals.set(3);
        }
        if (struct.isSetAe()) {
          optionals.set(4);
        }
        oprot.writeBitSet(optionals, 5);
        if (struct.isSetSuccess()) {
          {
            oprot.writeI32(struct.success.size());
            for (org.apache.airavata.model.experiment.ExperimentSummaryModel _iter70 : struct.success)
            {
              _iter70.write(oprot);
            }
          }
        }
        if (struct.isSetIre()) {
          struct.ire.write(oprot);
        }
        if (struct.isSetAce()) {
          struct.ace.write(oprot);
        }
        if (struct.isSetAse()) {
          struct.ase.write(oprot);
        }
        if (struct.isSetAe()) {
          struct.ae.write(oprot);
        }
      }

      @Override
      public void read(org.apache.thrift.protocol.TProtocol prot, searchExperimentsByStatus_result struct) throws org.apache.thrift.TException {
        TTupleProtocol iprot = (TTupleProtocol) prot;
        BitSet incoming = iprot.readBitSet(5);
        if (incoming.get(0)) {
          {
            org.apache.thrift.protocol.TList _list71 = new org.apache.thrift.protocol.TList(org.apache.thrift.protocol.TType.STRUCT, iprot.readI32());
            struct.success = new ArrayList<org.apache.airavata.model.experiment.ExperimentSummaryModel>(_list71.size);
            org.apache.airavata.model.experiment.ExperimentSummaryModel _elem72;
            for (int _i73 = 0; _i73 < _list71.size; ++_i73)
            {
              _elem72 = new org.apache.airavata.model.experiment.ExperimentSummaryModel();
              _elem72.read(iprot);
              struct.success.add(_elem72);
            }
          }
          struct.setSuccessIsSet(true);
        }
        if (incoming.get(1)) {
          struct.ire = new org.apache.airavata.model.error.InvalidRequestException();
          struct.ire.read(iprot);
          struct.setIreIsSet(true);
        }
        if (incoming.get(2)) {
          struct.ace = new org.apache.airavata.model.error.AiravataClientException();
          struct.ace.read(iprot);
          struct.setAceIsSet(true);
        }
        if (incoming.get(3)) {
          struct.ase = new org.apache.airavata.model.error.AiravataSystemException();
          struct.ase.read(iprot);
          struct.setAseIsSet(true);
        }
        if (incoming.get(4)) {
          struct.ae = new org.apache.airavata.model.error.AuthorizationException();
          struct.ae.read(iprot);
          struct.setAeIsSet(true);
        }
      }
    }

  }

  public static class searchExperimentsByCreationTime_args implements org.apache.thrift.TBase<searchExperimentsByCreationTime_args, searchExperimentsByCreationTime_args._Fields>, java.io.Serializable, Cloneable, Comparable<searchExperimentsByCreationTime_args>   {
    private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("searchExperimentsByCreationTime_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.protocol.TField USER_NAME_FIELD_DESC = new org.apache.thrift.protocol.TField("userName", org.apache.thrift.protocol.TType.STRING, (short)3);
    private static final org.apache.thrift.protocol.TField FROM_TIME_FIELD_DESC = new org.apache.thrift.protocol.TField("fromTime", org.apache.thrift.protocol.TType.I64, (short)4);
    private static final org.apache.thrift.protocol.TField TO_TIME_FIELD_DESC = new org.apache.thrift.protocol.TField("toTime", org.apache.thrift.protocol.TType.I64, (short)5);
    private static final org.apache.thrift.protocol.TField LIMIT_FIELD_DESC = new org.apache.thrift.protocol.TField("limit", org.apache.thrift.protocol.TType.I32, (short)6);
    private static final org.apache.thrift.protocol.TField OFFSET_FIELD_DESC = new org.apache.thrift.protocol.TField("offset", org.apache.thrift.protocol.TType.I32, (short)7);

    private static final Map<Class<? extends IScheme>, SchemeFactory> schemes = new HashMap<Class<? extends IScheme>, SchemeFactory>();
    static {
      schemes.put(StandardScheme.class, new searchExperimentsByCreationTime_argsStandardSchemeFactory());
      schemes.put(TupleScheme.class, new searchExperimentsByCreationTime_argsTupleSchemeFactory());
    }

    public org.apache.airavata.model.security.AuthzToken authzToken; // required
    public String gatewayId; // required
    public String userName; // required
    public long fromTime; // required
    public long toTime; // required
    public int limit; // required
    public int offset; // required

    /** 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"),
      USER_NAME((short)3, "userName"),
      FROM_TIME((short)4, "fromTime"),
      TO_TIME((short)5, "toTime"),
      LIMIT((short)6, "limit"),
      OFFSET((short)7, "offset");

      private static final Map<String, _Fields> byName = new HashMap<String, _Fields>();

      static {
        for (_Fields field : EnumSet.allOf(_Fields.class)) {
          byName.put(field.getFieldName(), field);
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, or null if its not found.
       */
      public static _Fields findByThriftId(int fieldId) {
        switch(fieldId) {
          case 1: // AUTHZ_TOKEN
            return AUTHZ_TOKEN;
          case 2: // GATEWAY_ID
            return GATEWAY_ID;
          case 3: // USER_NAME
            return USER_NAME;
          case 4: // FROM_TIME
            return FROM_TIME;
          case 5: // TO_TIME
            return TO_TIME;
          case 6: // LIMIT
            return LIMIT;
          case 7: // OFFSET
            return OFFSET;
          default:
            return null;
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, throwing an exception
       * if it is not found.
       */
      public static _Fields findByThriftIdOrThrow(int fieldId) {
        _Fields fields = findByThriftId(fieldId);
        if (fields == null) throw new IllegalArgumentException("Field " + fieldId + " doesn't exist!");
        return fields;
      }

      /**
       * Find the _Fields constant that matches name, or null if its not found.
       */
      public static _Fields findByName(String name) {
        return byName.get(name);
      }

      private final short _thriftId;
      private final String _fieldName;

      _Fields(short thriftId, String fieldName) {
        _thriftId = thriftId;
        _fieldName = fieldName;
      }

      public short getThriftFieldId() {
        return _thriftId;
      }

      public String getFieldName() {
        return _fieldName;
      }
    }

    // isset id assignments
    private static final int __FROMTIME_ISSET_ID = 0;
    private static final int __TOTIME_ISSET_ID = 1;
    private static final int __LIMIT_ISSET_ID = 2;
    private static final int __OFFSET_ISSET_ID = 3;
    private byte __isset_bitfield = 0;
    public static final Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
    static {
      Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new EnumMap<_Fields, org.apache.thrift.meta_data.FieldMetaData>(_Fields.class);
      tmpMap.put(_Fields.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)));
      tmpMap.put(_Fields.USER_NAME, new org.apache.thrift.meta_data.FieldMetaData("userName", org.apache.thrift.TFieldRequirementType.REQUIRED, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING)));
      tmpMap.put(_Fields.FROM_TIME, new org.apache.thrift.meta_data.FieldMetaData("fromTime", org.apache.thrift.TFieldRequirementType.REQUIRED, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.I64)));
      tmpMap.put(_Fields.TO_TIME, new org.apache.thrift.meta_data.FieldMetaData("toTime", org.apache.thrift.TFieldRequirementType.REQUIRED, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.I64)));
      tmpMap.put(_Fields.LIMIT, new org.apache.thrift.meta_data.FieldMetaData("limit", org.apache.thrift.TFieldRequirementType.REQUIRED, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.I32)));
      tmpMap.put(_Fields.OFFSET, new org.apache.thrift.meta_data.FieldMetaData("offset", org.apache.thrift.TFieldRequirementType.REQUIRED, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.I32)));
      metaDataMap = Collections.unmodifiableMap(tmpMap);
      org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(searchExperimentsByCreationTime_args.class, metaDataMap);
    }

    public searchExperimentsByCreationTime_args() {
    }

    public searchExperimentsByCreationTime_args(
      org.apache.airavata.model.security.AuthzToken authzToken,
      String gatewayId,
      String userName,
      long fromTime,
      long toTime,
      int limit,
      int offset)
    {
      this();
      this.authzToken = authzToken;
      this.gatewayId = gatewayId;
      this.userName = userName;
      this.fromTime = fromTime;
      setFromTimeIsSet(true);
      this.toTime = toTime;
      setToTimeIsSet(true);
      this.limit = limit;
      setLimitIsSet(true);
      this.offset = offset;
      setOffsetIsSet(true);
    }

    /**
     * Performs a deep copy on <i>other</i>.
     */
    public searchExperimentsByCreationTime_args(searchExperimentsByCreationTime_args other) {
      __isset_bitfield = other.__isset_bitfield;
      if (other.isSetAuthzToken()) {
        this.authzToken = new org.apache.airavata.model.security.AuthzToken(other.authzToken);
      }
      if (other.isSetGatewayId()) {
        this.gatewayId = other.gatewayId;
      }
      if (other.isSetUserName()) {
        this.userName = other.userName;
      }
      this.fromTime = other.fromTime;
      this.toTime = other.toTime;
      this.limit = other.limit;
      this.offset = other.offset;
    }

    public searchExperimentsByCreationTime_args deepCopy() {
      return new searchExperimentsByCreationTime_args(this);
    }

    @Override
    public void clear() {
      this.authzToken = null;
      this.gatewayId = null;
      this.userName = null;
      setFromTimeIsSet(false);
      this.fromTime = 0;
      setToTimeIsSet(false);
      this.toTime = 0;
      setLimitIsSet(false);
      this.limit = 0;
      setOffsetIsSet(false);
      this.offset = 0;
    }

    public org.apache.airavata.model.security.AuthzToken getAuthzToken() {
      return this.authzToken;
    }

    public searchExperimentsByCreationTime_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 String getGatewayId() {
      return this.gatewayId;
    }

    public searchExperimentsByCreationTime_args setGatewayId(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 String getUserName() {
      return this.userName;
    }

    public searchExperimentsByCreationTime_args setUserName(String userName) {
      this.userName = userName;
      return this;
    }

    public void unsetUserName() {
      this.userName = null;
    }

    /** Returns true if field userName is set (has been assigned a value) and false otherwise */
    public boolean isSetUserName() {
      return this.userName != null;
    }

    public void setUserNameIsSet(boolean value) {
      if (!value) {
        this.userName = null;
      }
    }

    public long getFromTime() {
      return this.fromTime;
    }

    public searchExperimentsByCreationTime_args setFromTime(long fromTime) {
      this.fromTime = fromTime;
      setFromTimeIsSet(true);
      return this;
    }

    public void unsetFromTime() {
      __isset_bitfield = EncodingUtils.clearBit(__isset_bitfield, __FROMTIME_ISSET_ID);
    }

    /** Returns true if field fromTime is set (has been assigned a value) and false otherwise */
    public boolean isSetFromTime() {
      return EncodingUtils.testBit(__isset_bitfield, __FROMTIME_ISSET_ID);
    }

    public void setFromTimeIsSet(boolean value) {
      __isset_bitfield = EncodingUtils.setBit(__isset_bitfield, __FROMTIME_ISSET_ID, value);
    }

    public long getToTime() {
      return this.toTime;
    }

    public searchExperimentsByCreationTime_args setToTime(long toTime) {
      this.toTime = toTime;
      setToTimeIsSet(true);
      return this;
    }

    public void unsetToTime() {
      __isset_bitfield = EncodingUtils.clearBit(__isset_bitfield, __TOTIME_ISSET_ID);
    }

    /** Returns true if field toTime is set (has been assigned a value) and false otherwise */
    public boolean isSetToTime() {
      return EncodingUtils.testBit(__isset_bitfield, __TOTIME_ISSET_ID);
    }

    public void setToTimeIsSet(boolean value) {
      __isset_bitfield = EncodingUtils.setBit(__isset_bitfield, __TOTIME_ISSET_ID, value);
    }

    public int getLimit() {
      return this.limit;
    }

    public searchExperimentsByCreationTime_args setLimit(int limit) {
      this.limit = limit;
      setLimitIsSet(true);
      return this;
    }

    public void unsetLimit() {
      __isset_bitfield = EncodingUtils.clearBit(__isset_bitfield, __LIMIT_ISSET_ID);
    }

    /** Returns true if field limit is set (has been assigned a value) and false otherwise */
    public boolean isSetLimit() {
      return EncodingUtils.testBit(__isset_bitfield, __LIMIT_ISSET_ID);
    }

    public void setLimitIsSet(boolean value) {
      __isset_bitfield = EncodingUtils.setBit(__isset_bitfield, __LIMIT_ISSET_ID, value);
    }

    public int getOffset() {
      return this.offset;
    }

    public searchExperimentsByCreationTime_args setOffset(int offset) {
      this.offset = offset;
      setOffsetIsSet(true);
      return this;
    }

    public void unsetOffset() {
      __isset_bitfield = EncodingUtils.clearBit(__isset_bitfield, __OFFSET_ISSET_ID);
    }

    /** Returns true if field offset is set (has been assigned a value) and false otherwise */
    public boolean isSetOffset() {
      return EncodingUtils.testBit(__isset_bitfield, __OFFSET_ISSET_ID);
    }

    public void setOffsetIsSet(boolean value) {
      __isset_bitfield = EncodingUtils.setBit(__isset_bitfield, __OFFSET_ISSET_ID, value);
    }

    public void setFieldValue(_Fields field, 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((String)value);
        }
        break;

      case USER_NAME:
        if (value == null) {
          unsetUserName();
        } else {
          setUserName((String)value);
        }
        break;

      case FROM_TIME:
        if (value == null) {
          unsetFromTime();
        } else {
          setFromTime((Long)value);
        }
        break;

      case TO_TIME:
        if (value == null) {
          unsetToTime();
        } else {
          setToTime((Long)value);
        }
        break;

      case LIMIT:
        if (value == null) {
          unsetLimit();
        } else {
          setLimit((Integer)value);
        }
        break;

      case OFFSET:
        if (value == null) {
          unsetOffset();
        } else {
          setOffset((Integer)value);
        }
        break;

      }
    }

    public Object getFieldValue(_Fields field) {
      switch (field) {
      case AUTHZ_TOKEN:
        return getAuthzToken();

      case GATEWAY_ID:
        return getGatewayId();

      case USER_NAME:
        return getUserName();

      case FROM_TIME:
        return Long.valueOf(getFromTime());

      case TO_TIME:
        return Long.valueOf(getToTime());

      case LIMIT:
        return Integer.valueOf(getLimit());

      case OFFSET:
        return Integer.valueOf(getOffset());

      }
      throw new IllegalStateException();
    }

    /** Returns true if field corresponding to fieldID is set (has been assigned a value) and false otherwise */
    public boolean isSet(_Fields field) {
      if (field == null) {
        throw new IllegalArgumentException();
      }

      switch (field) {
      case AUTHZ_TOKEN:
        return isSetAuthzToken();
      case GATEWAY_ID:
        return isSetGatewayId();
      case USER_NAME:
        return isSetUserName();
      case FROM_TIME:
        return isSetFromTime();
      case TO_TIME:
        return isSetToTime();
      case LIMIT:
        return isSetLimit();
      case OFFSET:
        return isSetOffset();
      }
      throw new IllegalStateException();
    }

    @Override
    public boolean equals(Object that) {
      if (that == null)
        return false;
      if (that instanceof searchExperimentsByCreationTime_args)
        return this.equals((searchExperimentsByCreationTime_args)that);
      return false;
    }

    public boolean equals(searchExperimentsByCreationTime_args that) {
      if (that == null)
        return false;

      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;
      }

      boolean this_present_userName = true && this.isSetUserName();
      boolean that_present_userName = true && that.isSetUserName();
      if (this_present_userName || that_present_userName) {
        if (!(this_present_userName && that_present_userName))
          return false;
        if (!this.userName.equals(that.userName))
          return false;
      }

      boolean this_present_fromTime = true;
      boolean that_present_fromTime = true;
      if (this_present_fromTime || that_present_fromTime) {
        if (!(this_present_fromTime && that_present_fromTime))
          return false;
        if (this.fromTime != that.fromTime)
          return false;
      }

      boolean this_present_toTime = true;
      boolean that_present_toTime = true;
      if (this_present_toTime || that_present_toTime) {
        if (!(this_present_toTime && that_present_toTime))
          return false;
        if (this.toTime != that.toTime)
          return false;
      }

      boolean this_present_limit = true;
      boolean that_present_limit = true;
      if (this_present_limit || that_present_limit) {
        if (!(this_present_limit && that_present_limit))
          return false;
        if (this.limit != that.limit)
          return false;
      }

      boolean this_present_offset = true;
      boolean that_present_offset = true;
      if (this_present_offset || that_present_offset) {
        if (!(this_present_offset && that_present_offset))
          return false;
        if (this.offset != that.offset)
          return false;
      }

      return true;
    }

    @Override
    public int hashCode() {
      List<Object> list = new ArrayList<Object>();

      boolean present_authzToken = true && (isSetAuthzToken());
      list.add(present_authzToken);
      if (present_authzToken)
        list.add(authzToken);

      boolean present_gatewayId = true && (isSetGatewayId());
      list.add(present_gatewayId);
      if (present_gatewayId)
        list.add(gatewayId);

      boolean present_userName = true && (isSetUserName());
      list.add(present_userName);
      if (present_userName)
        list.add(userName);

      boolean present_fromTime = true;
      list.add(present_fromTime);
      if (present_fromTime)
        list.add(fromTime);

      boolean present_toTime = true;
      list.add(present_toTime);
      if (present_toTime)
        list.add(toTime);

      boolean present_limit = true;
      list.add(present_limit);
      if (present_limit)
        list.add(limit);

      boolean present_offset = true;
      list.add(present_offset);
      if (present_offset)
        list.add(offset);

      return list.hashCode();
    }

    @Override
    public int compareTo(searchExperimentsByCreationTime_args other) {
      if (!getClass().equals(other.getClass())) {
        return getClass().getName().compareTo(other.getClass().getName());
      }

      int lastComparison = 0;

      lastComparison = 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 = 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;
        }
      }
      lastComparison = Boolean.valueOf(isSetUserName()).compareTo(other.isSetUserName());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetUserName()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.userName, other.userName);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = Boolean.valueOf(isSetFromTime()).compareTo(other.isSetFromTime());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetFromTime()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.fromTime, other.fromTime);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = Boolean.valueOf(isSetToTime()).compareTo(other.isSetToTime());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetToTime()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.toTime, other.toTime);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = Boolean.valueOf(isSetLimit()).compareTo(other.isSetLimit());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetLimit()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.limit, other.limit);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = Boolean.valueOf(isSetOffset()).compareTo(other.isSetOffset());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetOffset()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.offset, other.offset);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      return 0;
    }

    public _Fields fieldForId(int fieldId) {
      return _Fields.findByThriftId(fieldId);
    }

    public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
      schemes.get(iprot.getScheme()).getScheme().read(iprot, this);
    }

    public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException {
      schemes.get(oprot.getScheme()).getScheme().write(oprot, this);
    }

    @Override
    public String toString() {
      StringBuilder sb = new StringBuilder("searchExperimentsByCreationTime_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;
      if (!first) sb.append(", ");
      sb.append("userName:");
      if (this.userName == null) {
        sb.append("null");
      } else {
        sb.append(this.userName);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("fromTime:");
      sb.append(this.fromTime);
      first = false;
      if (!first) sb.append(", ");
      sb.append("toTime:");
      sb.append(this.toTime);
      first = false;
      if (!first) sb.append(", ");
      sb.append("limit:");
      sb.append(this.limit);
      first = false;
      if (!first) sb.append(", ");
      sb.append("offset:");
      sb.append(this.offset);
      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());
      }
      if (userName == null) {
        throw new org.apache.thrift.protocol.TProtocolException("Required field 'userName' was not present! Struct: " + toString());
      }
      // alas, we cannot check 'fromTime' because it's a primitive and you chose the non-beans generator.
      // alas, we cannot check 'toTime' because it's a primitive and you chose the non-beans generator.
      // alas, we cannot check 'limit' because it's a primitive and you chose the non-beans generator.
      // alas, we cannot check 'offset' because it's a primitive and you chose the non-beans generator.
      // 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, 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 searchExperimentsByCreationTime_argsStandardSchemeFactory implements SchemeFactory {
      public searchExperimentsByCreationTime_argsStandardScheme getScheme() {
        return new searchExperimentsByCreationTime_argsStandardScheme();
      }
    }

    private static class searchExperimentsByCreationTime_argsStandardScheme extends StandardScheme<searchExperimentsByCreationTime_args> {

      public void read(org.apache.thrift.protocol.TProtocol iprot, searchExperimentsByCreationTime_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;
            case 3: // USER_NAME
              if (schemeField.type == org.apache.thrift.protocol.TType.STRING) {
                struct.userName = iprot.readString();
                struct.setUserNameIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 4: // FROM_TIME
              if (schemeField.type == org.apache.thrift.protocol.TType.I64) {
                struct.fromTime = iprot.readI64();
                struct.setFromTimeIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 5: // TO_TIME
              if (schemeField.type == org.apache.thrift.protocol.TType.I64) {
                struct.toTime = iprot.readI64();
                struct.setToTimeIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 6: // LIMIT
              if (schemeField.type == org.apache.thrift.protocol.TType.I32) {
                struct.limit = iprot.readI32();
                struct.setLimitIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 7: // OFFSET
              if (schemeField.type == org.apache.thrift.protocol.TType.I32) {
                struct.offset = iprot.readI32();
                struct.setOffsetIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            default:
              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
          }
          iprot.readFieldEnd();
        }
        iprot.readStructEnd();

        // check for required fields of primitive type, which can't be checked in the validate method
        if (!struct.isSetFromTime()) {
          throw new org.apache.thrift.protocol.TProtocolException("Required field 'fromTime' was not found in serialized data! Struct: " + toString());
        }
        if (!struct.isSetToTime()) {
          throw new org.apache.thrift.protocol.TProtocolException("Required field 'toTime' was not found in serialized data! Struct: " + toString());
        }
        if (!struct.isSetLimit()) {
          throw new org.apache.thrift.protocol.TProtocolException("Required field 'limit' was not found in serialized data! Struct: " + toString());
        }
        if (!struct.isSetOffset()) {
          throw new org.apache.thrift.protocol.TProtocolException("Required field 'offset' was not found in serialized data! Struct: " + toString());
        }
        struct.validate();
      }

      public void write(org.apache.thrift.protocol.TProtocol oprot, searchExperimentsByCreationTime_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();
        }
        if (struct.userName != null) {
          oprot.writeFieldBegin(USER_NAME_FIELD_DESC);
          oprot.writeString(struct.userName);
          oprot.writeFieldEnd();
        }
        oprot.writeFieldBegin(FROM_TIME_FIELD_DESC);
        oprot.writeI64(struct.fromTime);
        oprot.writeFieldEnd();
        oprot.writeFieldBegin(TO_TIME_FIELD_DESC);
        oprot.writeI64(struct.toTime);
        oprot.writeFieldEnd();
        oprot.writeFieldBegin(LIMIT_FIELD_DESC);
        oprot.writeI32(struct.limit);
        oprot.writeFieldEnd();
        oprot.writeFieldBegin(OFFSET_FIELD_DESC);
        oprot.writeI32(struct.offset);
        oprot.writeFieldEnd();
        oprot.writeFieldStop();
        oprot.writeStructEnd();
      }

    }

    private static class searchExperimentsByCreationTime_argsTupleSchemeFactory implements SchemeFactory {
      public searchExperimentsByCreationTime_argsTupleScheme getScheme() {
        return new searchExperimentsByCreationTime_argsTupleScheme();
      }
    }

    private static class searchExperimentsByCreationTime_argsTupleScheme extends TupleScheme<searchExperimentsByCreationTime_args> {

      @Override
      public void write(org.apache.thrift.protocol.TProtocol prot, searchExperimentsByCreationTime_args struct) throws org.apache.thrift.TException {
        TTupleProtocol oprot = (TTupleProtocol) prot;
        struct.authzToken.write(oprot);
        oprot.writeString(struct.gatewayId);
        oprot.writeString(struct.userName);
        oprot.writeI64(struct.fromTime);
        oprot.writeI64(struct.toTime);
        oprot.writeI32(struct.limit);
        oprot.writeI32(struct.offset);
      }

      @Override
      public void read(org.apache.thrift.protocol.TProtocol prot, searchExperimentsByCreationTime_args struct) throws org.apache.thrift.TException {
        TTupleProtocol iprot = (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);
        struct.userName = iprot.readString();
        struct.setUserNameIsSet(true);
        struct.fromTime = iprot.readI64();
        struct.setFromTimeIsSet(true);
        struct.toTime = iprot.readI64();
        struct.setToTimeIsSet(true);
        struct.limit = iprot.readI32();
        struct.setLimitIsSet(true);
        struct.offset = iprot.readI32();
        struct.setOffsetIsSet(true);
      }
    }

  }

  public static class searchExperimentsByCreationTime_result implements org.apache.thrift.TBase<searchExperimentsByCreationTime_result, searchExperimentsByCreationTime_result._Fields>, java.io.Serializable, Cloneable, Comparable<searchExperimentsByCreationTime_result>   {
    private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("searchExperimentsByCreationTime_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 IRE_FIELD_DESC = new org.apache.thrift.protocol.TField("ire", org.apache.thrift.protocol.TType.STRUCT, (short)1);
    private static final org.apache.thrift.protocol.TField ACE_FIELD_DESC = new org.apache.thrift.protocol.TField("ace", org.apache.thrift.protocol.TType.STRUCT, (short)2);
    private static final org.apache.thrift.protocol.TField ASE_FIELD_DESC = new org.apache.thrift.protocol.TField("ase", org.apache.thrift.protocol.TType.STRUCT, (short)3);
    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)4);

    private static final Map<Class<? extends IScheme>, SchemeFactory> schemes = new HashMap<Class<? extends IScheme>, SchemeFactory>();
    static {
      schemes.put(StandardScheme.class, new searchExperimentsByCreationTime_resultStandardSchemeFactory());
      schemes.put(TupleScheme.class, new searchExperimentsByCreationTime_resultTupleSchemeFactory());
    }

    public List<org.apache.airavata.model.experiment.ExperimentSummaryModel> success; // required
    public org.apache.airavata.model.error.InvalidRequestException ire; // required
    public org.apache.airavata.model.error.AiravataClientException ace; // required
    public org.apache.airavata.model.error.AiravataSystemException ase; // 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"),
      IRE((short)1, "ire"),
      ACE((short)2, "ace"),
      ASE((short)3, "ase"),
      AE((short)4, "ae");

      private static final Map<String, _Fields> byName = new HashMap<String, _Fields>();

      static {
        for (_Fields field : EnumSet.allOf(_Fields.class)) {
          byName.put(field.getFieldName(), field);
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, or null if its not found.
       */
      public static _Fields findByThriftId(int fieldId) {
        switch(fieldId) {
          case 0: // SUCCESS
            return SUCCESS;
          case 1: // IRE
            return IRE;
          case 2: // ACE
            return ACE;
          case 3: // ASE
            return ASE;
          case 4: // 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 IllegalArgumentException("Field " + fieldId + " doesn't exist!");
        return fields;
      }

      /**
       * Find the _Fields constant that matches name, or null if its not found.
       */
      public static _Fields findByName(String name) {
        return byName.get(name);
      }

      private final short _thriftId;
      private final String _fieldName;

      _Fields(short thriftId, String fieldName) {
        _thriftId = thriftId;
        _fieldName = fieldName;
      }

      public short getThriftFieldId() {
        return _thriftId;
      }

      public String getFieldName() {
        return _fieldName;
      }
    }

    // isset id assignments
    public static final Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
    static {
      Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new EnumMap<_Fields, org.apache.thrift.meta_data.FieldMetaData>(_Fields.class);
      tmpMap.put(_Fields.SUCCESS, new org.apache.thrift.meta_data.FieldMetaData("success", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.ListMetaData(org.apache.thrift.protocol.TType.LIST, 
              new org.apache.thrift.meta_data.StructMetaData(org.apache.thrift.protocol.TType.STRUCT, org.apache.airavata.model.experiment.ExperimentSummaryModel.class))));
      tmpMap.put(_Fields.IRE, new org.apache.thrift.meta_data.FieldMetaData("ire", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRUCT)));
      tmpMap.put(_Fields.ACE, new org.apache.thrift.meta_data.FieldMetaData("ace", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRUCT)));
      tmpMap.put(_Fields.ASE, new org.apache.thrift.meta_data.FieldMetaData("ase", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRUCT)));
      tmpMap.put(_Fields.AE, new org.apache.thrift.meta_data.FieldMetaData("ae", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRUCT)));
      metaDataMap = Collections.unmodifiableMap(tmpMap);
      org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(searchExperimentsByCreationTime_result.class, metaDataMap);
    }

    public searchExperimentsByCreationTime_result() {
    }

    public searchExperimentsByCreationTime_result(
      List<org.apache.airavata.model.experiment.ExperimentSummaryModel> success,
      org.apache.airavata.model.error.InvalidRequestException ire,
      org.apache.airavata.model.error.AiravataClientException ace,
      org.apache.airavata.model.error.AiravataSystemException ase,
      org.apache.airavata.model.error.AuthorizationException ae)
    {
      this();
      this.success = success;
      this.ire = ire;
      this.ace = ace;
      this.ase = ase;
      this.ae = ae;
    }

    /**
     * Performs a deep copy on <i>other</i>.
     */
    public searchExperimentsByCreationTime_result(searchExperimentsByCreationTime_result other) {
      if (other.isSetSuccess()) {
        List<org.apache.airavata.model.experiment.ExperimentSummaryModel> __this__success = new ArrayList<org.apache.airavata.model.experiment.ExperimentSummaryModel>(other.success.size());
        for (org.apache.airavata.model.experiment.ExperimentSummaryModel other_element : other.success) {
          __this__success.add(new org.apache.airavata.model.experiment.ExperimentSummaryModel(other_element));
        }
        this.success = __this__success;
      }
      if (other.isSetIre()) {
        this.ire = new org.apache.airavata.model.error.InvalidRequestException(other.ire);
      }
      if (other.isSetAce()) {
        this.ace = new org.apache.airavata.model.error.AiravataClientException(other.ace);
      }
      if (other.isSetAse()) {
        this.ase = new org.apache.airavata.model.error.AiravataSystemException(other.ase);
      }
      if (other.isSetAe()) {
        this.ae = new org.apache.airavata.model.error.AuthorizationException(other.ae);
      }
    }

    public searchExperimentsByCreationTime_result deepCopy() {
      return new searchExperimentsByCreationTime_result(this);
    }

    @Override
    public void clear() {
      this.success = null;
      this.ire = null;
      this.ace = null;
      this.ase = null;
      this.ae = null;
    }

    public int getSuccessSize() {
      return (this.success == null) ? 0 : this.success.size();
    }

    public java.util.Iterator<org.apache.airavata.model.experiment.ExperimentSummaryModel> getSuccessIterator() {
      return (this.success == null) ? null : this.success.iterator();
    }

    public void addToSuccess(org.apache.airavata.model.experiment.ExperimentSummaryModel elem) {
      if (this.success == null) {
        this.success = new ArrayList<org.apache.airavata.model.experiment.ExperimentSummaryModel>();
      }
      this.success.add(elem);
    }

    public List<org.apache.airavata.model.experiment.ExperimentSummaryModel> getSuccess() {
      return this.success;
    }

    public searchExperimentsByCreationTime_result setSuccess(List<org.apache.airavata.model.experiment.ExperimentSummaryModel> 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.model.error.InvalidRequestException getIre() {
      return this.ire;
    }

    public searchExperimentsByCreationTime_result setIre(org.apache.airavata.model.error.InvalidRequestException ire) {
      this.ire = ire;
      return this;
    }

    public void unsetIre() {
      this.ire = null;
    }

    /** Returns true if field ire is set (has been assigned a value) and false otherwise */
    public boolean isSetIre() {
      return this.ire != null;
    }

    public void setIreIsSet(boolean value) {
      if (!value) {
        this.ire = null;
      }
    }

    public org.apache.airavata.model.error.AiravataClientException getAce() {
      return this.ace;
    }

    public searchExperimentsByCreationTime_result setAce(org.apache.airavata.model.error.AiravataClientException ace) {
      this.ace = ace;
      return this;
    }

    public void unsetAce() {
      this.ace = null;
    }

    /** Returns true if field ace is set (has been assigned a value) and false otherwise */
    public boolean isSetAce() {
      return this.ace != null;
    }

    public void setAceIsSet(boolean value) {
      if (!value) {
        this.ace = null;
      }
    }

    public org.apache.airavata.model.error.AiravataSystemException getAse() {
      return this.ase;
    }

    public searchExperimentsByCreationTime_result setAse(org.apache.airavata.model.error.AiravataSystemException ase) {
      this.ase = ase;
      return this;
    }

    public void unsetAse() {
      this.ase = null;
    }

    /** Returns true if field ase is set (has been assigned a value) and false otherwise */
    public boolean isSetAse() {
      return this.ase != null;
    }

    public void setAseIsSet(boolean value) {
      if (!value) {
        this.ase = null;
      }
    }

    public org.apache.airavata.model.error.AuthorizationException getAe() {
      return this.ae;
    }

    public searchExperimentsByCreationTime_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, Object value) {
      switch (field) {
      case SUCCESS:
        if (value == null) {
          unsetSuccess();
        } else {
          setSuccess((List<org.apache.airavata.model.experiment.ExperimentSummaryModel>)value);
        }
        break;

      case IRE:
        if (value == null) {
          unsetIre();
        } else {
          setIre((org.apache.airavata.model.error.InvalidRequestException)value);
        }
        break;

      case ACE:
        if (value == null) {
          unsetAce();
        } else {
          setAce((org.apache.airavata.model.error.AiravataClientException)value);
        }
        break;

      case ASE:
        if (value == null) {
          unsetAse();
        } else {
          setAse((org.apache.airavata.model.error.AiravataSystemException)value);
        }
        break;

      case AE:
        if (value == null) {
          unsetAe();
        } else {
          setAe((org.apache.airavata.model.error.AuthorizationException)value);
        }
        break;

      }
    }

    public Object getFieldValue(_Fields field) {
      switch (field) {
      case SUCCESS:
        return getSuccess();

      case IRE:
        return getIre();

      case ACE:
        return getAce();

      case ASE:
        return getAse();

      case AE:
        return getAe();

      }
      throw new IllegalStateException();
    }

    /** Returns true if field corresponding to fieldID is set (has been assigned a value) and false otherwise */
    public boolean isSet(_Fields field) {
      if (field == null) {
        throw new IllegalArgumentException();
      }

      switch (field) {
      case SUCCESS:
        return isSetSuccess();
      case IRE:
        return isSetIre();
      case ACE:
        return isSetAce();
      case ASE:
        return isSetAse();
      case AE:
        return isSetAe();
      }
      throw new IllegalStateException();
    }

    @Override
    public boolean equals(Object that) {
      if (that == null)
        return false;
      if (that instanceof searchExperimentsByCreationTime_result)
        return this.equals((searchExperimentsByCreationTime_result)that);
      return false;
    }

    public boolean equals(searchExperimentsByCreationTime_result that) {
      if (that == null)
        return false;

      boolean this_present_success = true && this.isSetSuccess();
      boolean that_present_success = true && that.isSetSuccess();
      if (this_present_success || that_present_success) {
        if (!(this_present_success && that_present_success))
          return false;
        if (!this.success.equals(that.success))
          return false;
      }

      boolean this_present_ire = true && this.isSetIre();
      boolean that_present_ire = true && that.isSetIre();
      if (this_present_ire || that_present_ire) {
        if (!(this_present_ire && that_present_ire))
          return false;
        if (!this.ire.equals(that.ire))
          return false;
      }

      boolean this_present_ace = true && this.isSetAce();
      boolean that_present_ace = true && that.isSetAce();
      if (this_present_ace || that_present_ace) {
        if (!(this_present_ace && that_present_ace))
          return false;
        if (!this.ace.equals(that.ace))
          return false;
      }

      boolean this_present_ase = true && this.isSetAse();
      boolean that_present_ase = true && that.isSetAse();
      if (this_present_ase || that_present_ase) {
        if (!(this_present_ase && that_present_ase))
          return false;
        if (!this.ase.equals(that.ase))
          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() {
      List<Object> list = new ArrayList<Object>();

      boolean present_success = true && (isSetSuccess());
      list.add(present_success);
      if (present_success)
        list.add(success);

      boolean present_ire = true && (isSetIre());
      list.add(present_ire);
      if (present_ire)
        list.add(ire);

      boolean present_ace = true && (isSetAce());
      list.add(present_ace);
      if (present_ace)
        list.add(ace);

      boolean present_ase = true && (isSetAse());
      list.add(present_ase);
      if (present_ase)
        list.add(ase);

      boolean present_ae = true && (isSetAe());
      list.add(present_ae);
      if (present_ae)
        list.add(ae);

      return list.hashCode();
    }

    @Override
    public int compareTo(searchExperimentsByCreationTime_result other) {
      if (!getClass().equals(other.getClass())) {
        return getClass().getName().compareTo(other.getClass().getName());
      }

      int lastComparison = 0;

      lastComparison = Boolean.valueOf(isSetSuccess()).compareTo(other.isSetSuccess());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetSuccess()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.success, other.success);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = Boolean.valueOf(isSetIre()).compareTo(other.isSetIre());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetIre()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.ire, other.ire);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = Boolean.valueOf(isSetAce()).compareTo(other.isSetAce());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetAce()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.ace, other.ace);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = Boolean.valueOf(isSetAse()).compareTo(other.isSetAse());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetAse()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.ase, other.ase);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = 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 {
      schemes.get(iprot.getScheme()).getScheme().read(iprot, this);
    }

    public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException {
      schemes.get(oprot.getScheme()).getScheme().write(oprot, this);
      }

    @Override
    public String toString() {
      StringBuilder sb = new StringBuilder("searchExperimentsByCreationTime_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("ire:");
      if (this.ire == null) {
        sb.append("null");
      } else {
        sb.append(this.ire);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("ace:");
      if (this.ace == null) {
        sb.append("null");
      } else {
        sb.append(this.ace);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("ase:");
      if (this.ase == null) {
        sb.append("null");
      } else {
        sb.append(this.ase);
      }
      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, 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 searchExperimentsByCreationTime_resultStandardSchemeFactory implements SchemeFactory {
      public searchExperimentsByCreationTime_resultStandardScheme getScheme() {
        return new searchExperimentsByCreationTime_resultStandardScheme();
      }
    }

    private static class searchExperimentsByCreationTime_resultStandardScheme extends StandardScheme<searchExperimentsByCreationTime_result> {

      public void read(org.apache.thrift.protocol.TProtocol iprot, searchExperimentsByCreationTime_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 _list74 = iprot.readListBegin();
                  struct.success = new ArrayList<org.apache.airavata.model.experiment.ExperimentSummaryModel>(_list74.size);
                  org.apache.airavata.model.experiment.ExperimentSummaryModel _elem75;
                  for (int _i76 = 0; _i76 < _list74.size; ++_i76)
                  {
                    _elem75 = new org.apache.airavata.model.experiment.ExperimentSummaryModel();
                    _elem75.read(iprot);
                    struct.success.add(_elem75);
                  }
                  iprot.readListEnd();
                }
                struct.setSuccessIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 1: // IRE
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.ire = new org.apache.airavata.model.error.InvalidRequestException();
                struct.ire.read(iprot);
                struct.setIreIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 2: // ACE
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.ace = new org.apache.airavata.model.error.AiravataClientException();
                struct.ace.read(iprot);
                struct.setAceIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 3: // ASE
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.ase = new org.apache.airavata.model.error.AiravataSystemException();
                struct.ase.read(iprot);
                struct.setAseIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 4: // 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, searchExperimentsByCreationTime_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.experiment.ExperimentSummaryModel _iter77 : struct.success)
            {
              _iter77.write(oprot);
            }
            oprot.writeListEnd();
          }
          oprot.writeFieldEnd();
        }
        if (struct.ire != null) {
          oprot.writeFieldBegin(IRE_FIELD_DESC);
          struct.ire.write(oprot);
          oprot.writeFieldEnd();
        }
        if (struct.ace != null) {
          oprot.writeFieldBegin(ACE_FIELD_DESC);
          struct.ace.write(oprot);
          oprot.writeFieldEnd();
        }
        if (struct.ase != null) {
          oprot.writeFieldBegin(ASE_FIELD_DESC);
          struct.ase.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 searchExperimentsByCreationTime_resultTupleSchemeFactory implements SchemeFactory {
      public searchExperimentsByCreationTime_resultTupleScheme getScheme() {
        return new searchExperimentsByCreationTime_resultTupleScheme();
      }
    }

    private static class searchExperimentsByCreationTime_resultTupleScheme extends TupleScheme<searchExperimentsByCreationTime_result> {

      @Override
      public void write(org.apache.thrift.protocol.TProtocol prot, searchExperimentsByCreationTime_result struct) throws org.apache.thrift.TException {
        TTupleProtocol oprot = (TTupleProtocol) prot;
        BitSet optionals = new BitSet();
        if (struct.isSetSuccess()) {
          optionals.set(0);
        }
        if (struct.isSetIre()) {
          optionals.set(1);
        }
        if (struct.isSetAce()) {
          optionals.set(2);
        }
        if (struct.isSetAse()) {
          optionals.set(3);
        }
        if (struct.isSetAe()) {
          optionals.set(4);
        }
        oprot.writeBitSet(optionals, 5);
        if (struct.isSetSuccess()) {
          {
            oprot.writeI32(struct.success.size());
            for (org.apache.airavata.model.experiment.ExperimentSummaryModel _iter78 : struct.success)
            {
              _iter78.write(oprot);
            }
          }
        }
        if (struct.isSetIre()) {
          struct.ire.write(oprot);
        }
        if (struct.isSetAce()) {
          struct.ace.write(oprot);
        }
        if (struct.isSetAse()) {
          struct.ase.write(oprot);
        }
        if (struct.isSetAe()) {
          struct.ae.write(oprot);
        }
      }

      @Override
      public void read(org.apache.thrift.protocol.TProtocol prot, searchExperimentsByCreationTime_result struct) throws org.apache.thrift.TException {
        TTupleProtocol iprot = (TTupleProtocol) prot;
        BitSet incoming = iprot.readBitSet(5);
        if (incoming.get(0)) {
          {
            org.apache.thrift.protocol.TList _list79 = new org.apache.thrift.protocol.TList(org.apache.thrift.protocol.TType.STRUCT, iprot.readI32());
            struct.success = new ArrayList<org.apache.airavata.model.experiment.ExperimentSummaryModel>(_list79.size);
            org.apache.airavata.model.experiment.ExperimentSummaryModel _elem80;
            for (int _i81 = 0; _i81 < _list79.size; ++_i81)
            {
              _elem80 = new org.apache.airavata.model.experiment.ExperimentSummaryModel();
              _elem80.read(iprot);
              struct.success.add(_elem80);
            }
          }
          struct.setSuccessIsSet(true);
        }
        if (incoming.get(1)) {
          struct.ire = new org.apache.airavata.model.error.InvalidRequestException();
          struct.ire.read(iprot);
          struct.setIreIsSet(true);
        }
        if (incoming.get(2)) {
          struct.ace = new org.apache.airavata.model.error.AiravataClientException();
          struct.ace.read(iprot);
          struct.setAceIsSet(true);
        }
        if (incoming.get(3)) {
          struct.ase = new org.apache.airavata.model.error.AiravataSystemException();
          struct.ase.read(iprot);
          struct.setAseIsSet(true);
        }
        if (incoming.get(4)) {
          struct.ae = new org.apache.airavata.model.error.AuthorizationException();
          struct.ae.read(iprot);
          struct.setAeIsSet(true);
        }
      }
    }

  }

  public static class searchExperiments_args implements org.apache.thrift.TBase<searchExperiments_args, searchExperiments_args._Fields>, java.io.Serializable, Cloneable, Comparable<searchExperiments_args>   {
    private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("searchExperiments_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.protocol.TField USER_NAME_FIELD_DESC = new org.apache.thrift.protocol.TField("userName", org.apache.thrift.protocol.TType.STRING, (short)3);
    private static final org.apache.thrift.protocol.TField FILTERS_FIELD_DESC = new org.apache.thrift.protocol.TField("filters", org.apache.thrift.protocol.TType.MAP, (short)4);
    private static final org.apache.thrift.protocol.TField LIMIT_FIELD_DESC = new org.apache.thrift.protocol.TField("limit", org.apache.thrift.protocol.TType.I32, (short)5);
    private static final org.apache.thrift.protocol.TField OFFSET_FIELD_DESC = new org.apache.thrift.protocol.TField("offset", org.apache.thrift.protocol.TType.I32, (short)6);

    private static final Map<Class<? extends IScheme>, SchemeFactory> schemes = new HashMap<Class<? extends IScheme>, SchemeFactory>();
    static {
      schemes.put(StandardScheme.class, new searchExperiments_argsStandardSchemeFactory());
      schemes.put(TupleScheme.class, new searchExperiments_argsTupleSchemeFactory());
    }

    public org.apache.airavata.model.security.AuthzToken authzToken; // required
    public String gatewayId; // required
    public String userName; // required
    public Map<org.apache.airavata.model.experiment.ExperimentSearchFields,String> filters; // required
    public int limit; // required
    public int offset; // required

    /** 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"),
      USER_NAME((short)3, "userName"),
      FILTERS((short)4, "filters"),
      LIMIT((short)5, "limit"),
      OFFSET((short)6, "offset");

      private static final Map<String, _Fields> byName = new HashMap<String, _Fields>();

      static {
        for (_Fields field : EnumSet.allOf(_Fields.class)) {
          byName.put(field.getFieldName(), field);
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, or null if its not found.
       */
      public static _Fields findByThriftId(int fieldId) {
        switch(fieldId) {
          case 1: // AUTHZ_TOKEN
            return AUTHZ_TOKEN;
          case 2: // GATEWAY_ID
            return GATEWAY_ID;
          case 3: // USER_NAME
            return USER_NAME;
          case 4: // FILTERS
            return FILTERS;
          case 5: // LIMIT
            return LIMIT;
          case 6: // OFFSET
            return OFFSET;
          default:
            return null;
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, throwing an exception
       * if it is not found.
       */
      public static _Fields findByThriftIdOrThrow(int fieldId) {
        _Fields fields = findByThriftId(fieldId);
        if (fields == null) throw new IllegalArgumentException("Field " + fieldId + " doesn't exist!");
        return fields;
      }

      /**
       * Find the _Fields constant that matches name, or null if its not found.
       */
      public static _Fields findByName(String name) {
        return byName.get(name);
      }

      private final short _thriftId;
      private final String _fieldName;

      _Fields(short thriftId, String fieldName) {
        _thriftId = thriftId;
        _fieldName = fieldName;
      }

      public short getThriftFieldId() {
        return _thriftId;
      }

      public String getFieldName() {
        return _fieldName;
      }
    }

    // isset id assignments
    private static final int __LIMIT_ISSET_ID = 0;
    private static final int __OFFSET_ISSET_ID = 1;
    private byte __isset_bitfield = 0;
    public static final Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
    static {
      Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new EnumMap<_Fields, org.apache.thrift.meta_data.FieldMetaData>(_Fields.class);
      tmpMap.put(_Fields.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)));
      tmpMap.put(_Fields.USER_NAME, new org.apache.thrift.meta_data.FieldMetaData("userName", org.apache.thrift.TFieldRequirementType.REQUIRED, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING)));
      tmpMap.put(_Fields.FILTERS, new org.apache.thrift.meta_data.FieldMetaData("filters", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.MapMetaData(org.apache.thrift.protocol.TType.MAP, 
              new org.apache.thrift.meta_data.EnumMetaData(org.apache.thrift.protocol.TType.ENUM, org.apache.airavata.model.experiment.ExperimentSearchFields.class), 
              new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING))));
      tmpMap.put(_Fields.LIMIT, new org.apache.thrift.meta_data.FieldMetaData("limit", org.apache.thrift.TFieldRequirementType.REQUIRED, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.I32)));
      tmpMap.put(_Fields.OFFSET, new org.apache.thrift.meta_data.FieldMetaData("offset", org.apache.thrift.TFieldRequirementType.REQUIRED, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.I32)));
      metaDataMap = Collections.unmodifiableMap(tmpMap);
      org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(searchExperiments_args.class, metaDataMap);
    }

    public searchExperiments_args() {
    }

    public searchExperiments_args(
      org.apache.airavata.model.security.AuthzToken authzToken,
      String gatewayId,
      String userName,
      Map<org.apache.airavata.model.experiment.ExperimentSearchFields,String> filters,
      int limit,
      int offset)
    {
      this();
      this.authzToken = authzToken;
      this.gatewayId = gatewayId;
      this.userName = userName;
      this.filters = filters;
      this.limit = limit;
      setLimitIsSet(true);
      this.offset = offset;
      setOffsetIsSet(true);
    }

    /**
     * Performs a deep copy on <i>other</i>.
     */
    public searchExperiments_args(searchExperiments_args other) {
      __isset_bitfield = other.__isset_bitfield;
      if (other.isSetAuthzToken()) {
        this.authzToken = new org.apache.airavata.model.security.AuthzToken(other.authzToken);
      }
      if (other.isSetGatewayId()) {
        this.gatewayId = other.gatewayId;
      }
      if (other.isSetUserName()) {
        this.userName = other.userName;
      }
      if (other.isSetFilters()) {
        Map<org.apache.airavata.model.experiment.ExperimentSearchFields,String> __this__filters = new HashMap<org.apache.airavata.model.experiment.ExperimentSearchFields,String>(other.filters.size());
        for (Map.Entry<org.apache.airavata.model.experiment.ExperimentSearchFields, String> other_element : other.filters.entrySet()) {

          org.apache.airavata.model.experiment.ExperimentSearchFields other_element_key = other_element.getKey();
          String other_element_value = other_element.getValue();

          org.apache.airavata.model.experiment.ExperimentSearchFields __this__filters_copy_key = other_element_key;

          String __this__filters_copy_value = other_element_value;

          __this__filters.put(__this__filters_copy_key, __this__filters_copy_value);
        }
        this.filters = __this__filters;
      }
      this.limit = other.limit;
      this.offset = other.offset;
    }

    public searchExperiments_args deepCopy() {
      return new searchExperiments_args(this);
    }

    @Override
    public void clear() {
      this.authzToken = null;
      this.gatewayId = null;
      this.userName = null;
      this.filters = null;
      setLimitIsSet(false);
      this.limit = 0;
      setOffsetIsSet(false);
      this.offset = 0;
    }

    public org.apache.airavata.model.security.AuthzToken getAuthzToken() {
      return this.authzToken;
    }

    public searchExperiments_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 String getGatewayId() {
      return this.gatewayId;
    }

    public searchExperiments_args setGatewayId(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 String getUserName() {
      return this.userName;
    }

    public searchExperiments_args setUserName(String userName) {
      this.userName = userName;
      return this;
    }

    public void unsetUserName() {
      this.userName = null;
    }

    /** Returns true if field userName is set (has been assigned a value) and false otherwise */
    public boolean isSetUserName() {
      return this.userName != null;
    }

    public void setUserNameIsSet(boolean value) {
      if (!value) {
        this.userName = null;
      }
    }

    public int getFiltersSize() {
      return (this.filters == null) ? 0 : this.filters.size();
    }

    public void putToFilters(org.apache.airavata.model.experiment.ExperimentSearchFields key, String val) {
      if (this.filters == null) {
        this.filters = new HashMap<org.apache.airavata.model.experiment.ExperimentSearchFields,String>();
      }
      this.filters.put(key, val);
    }

    public Map<org.apache.airavata.model.experiment.ExperimentSearchFields,String> getFilters() {
      return this.filters;
    }

    public searchExperiments_args setFilters(Map<org.apache.airavata.model.experiment.ExperimentSearchFields,String> filters) {
      this.filters = filters;
      return this;
    }

    public void unsetFilters() {
      this.filters = null;
    }

    /** Returns true if field filters is set (has been assigned a value) and false otherwise */
    public boolean isSetFilters() {
      return this.filters != null;
    }

    public void setFiltersIsSet(boolean value) {
      if (!value) {
        this.filters = null;
      }
    }

    public int getLimit() {
      return this.limit;
    }

    public searchExperiments_args setLimit(int limit) {
      this.limit = limit;
      setLimitIsSet(true);
      return this;
    }

    public void unsetLimit() {
      __isset_bitfield = EncodingUtils.clearBit(__isset_bitfield, __LIMIT_ISSET_ID);
    }

    /** Returns true if field limit is set (has been assigned a value) and false otherwise */
    public boolean isSetLimit() {
      return EncodingUtils.testBit(__isset_bitfield, __LIMIT_ISSET_ID);
    }

    public void setLimitIsSet(boolean value) {
      __isset_bitfield = EncodingUtils.setBit(__isset_bitfield, __LIMIT_ISSET_ID, value);
    }

    public int getOffset() {
      return this.offset;
    }

    public searchExperiments_args setOffset(int offset) {
      this.offset = offset;
      setOffsetIsSet(true);
      return this;
    }

    public void unsetOffset() {
      __isset_bitfield = EncodingUtils.clearBit(__isset_bitfield, __OFFSET_ISSET_ID);
    }

    /** Returns true if field offset is set (has been assigned a value) and false otherwise */
    public boolean isSetOffset() {
      return EncodingUtils.testBit(__isset_bitfield, __OFFSET_ISSET_ID);
    }

    public void setOffsetIsSet(boolean value) {
      __isset_bitfield = EncodingUtils.setBit(__isset_bitfield, __OFFSET_ISSET_ID, value);
    }

    public void setFieldValue(_Fields field, 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((String)value);
        }
        break;

      case USER_NAME:
        if (value == null) {
          unsetUserName();
        } else {
          setUserName((String)value);
        }
        break;

      case FILTERS:
        if (value == null) {
          unsetFilters();
        } else {
          setFilters((Map<org.apache.airavata.model.experiment.ExperimentSearchFields,String>)value);
        }
        break;

      case LIMIT:
        if (value == null) {
          unsetLimit();
        } else {
          setLimit((Integer)value);
        }
        break;

      case OFFSET:
        if (value == null) {
          unsetOffset();
        } else {
          setOffset((Integer)value);
        }
        break;

      }
    }

    public Object getFieldValue(_Fields field) {
      switch (field) {
      case AUTHZ_TOKEN:
        return getAuthzToken();

      case GATEWAY_ID:
        return getGatewayId();

      case USER_NAME:
        return getUserName();

      case FILTERS:
        return getFilters();

      case LIMIT:
        return Integer.valueOf(getLimit());

      case OFFSET:
        return Integer.valueOf(getOffset());

      }
      throw new IllegalStateException();
    }

    /** Returns true if field corresponding to fieldID is set (has been assigned a value) and false otherwise */
    public boolean isSet(_Fields field) {
      if (field == null) {
        throw new IllegalArgumentException();
      }

      switch (field) {
      case AUTHZ_TOKEN:
        return isSetAuthzToken();
      case GATEWAY_ID:
        return isSetGatewayId();
      case USER_NAME:
        return isSetUserName();
      case FILTERS:
        return isSetFilters();
      case LIMIT:
        return isSetLimit();
      case OFFSET:
        return isSetOffset();
      }
      throw new IllegalStateException();
    }

    @Override
    public boolean equals(Object that) {
      if (that == null)
        return false;
      if (that instanceof searchExperiments_args)
        return this.equals((searchExperiments_args)that);
      return false;
    }

    public boolean equals(searchExperiments_args that) {
      if (that == null)
        return false;

      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;
      }

      boolean this_present_userName = true && this.isSetUserName();
      boolean that_present_userName = true && that.isSetUserName();
      if (this_present_userName || that_present_userName) {
        if (!(this_present_userName && that_present_userName))
          return false;
        if (!this.userName.equals(that.userName))
          return false;
      }

      boolean this_present_filters = true && this.isSetFilters();
      boolean that_present_filters = true && that.isSetFilters();
      if (this_present_filters || that_present_filters) {
        if (!(this_present_filters && that_present_filters))
          return false;
        if (!this.filters.equals(that.filters))
          return false;
      }

      boolean this_present_limit = true;
      boolean that_present_limit = true;
      if (this_present_limit || that_present_limit) {
        if (!(this_present_limit && that_present_limit))
          return false;
        if (this.limit != that.limit)
          return false;
      }

      boolean this_present_offset = true;
      boolean that_present_offset = true;
      if (this_present_offset || that_present_offset) {
        if (!(this_present_offset && that_present_offset))
          return false;
        if (this.offset != that.offset)
          return false;
      }

      return true;
    }

    @Override
    public int hashCode() {
      List<Object> list = new ArrayList<Object>();

      boolean present_authzToken = true && (isSetAuthzToken());
      list.add(present_authzToken);
      if (present_authzToken)
        list.add(authzToken);

      boolean present_gatewayId = true && (isSetGatewayId());
      list.add(present_gatewayId);
      if (present_gatewayId)
        list.add(gatewayId);

      boolean present_userName = true && (isSetUserName());
      list.add(present_userName);
      if (present_userName)
        list.add(userName);

      boolean present_filters = true && (isSetFilters());
      list.add(present_filters);
      if (present_filters)
        list.add(filters);

      boolean present_limit = true;
      list.add(present_limit);
      if (present_limit)
        list.add(limit);

      boolean present_offset = true;
      list.add(present_offset);
      if (present_offset)
        list.add(offset);

      return list.hashCode();
    }

    @Override
    public int compareTo(searchExperiments_args other) {
      if (!getClass().equals(other.getClass())) {
        return getClass().getName().compareTo(other.getClass().getName());
      }

      int lastComparison = 0;

      lastComparison = 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 = 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;
        }
      }
      lastComparison = Boolean.valueOf(isSetUserName()).compareTo(other.isSetUserName());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetUserName()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.userName, other.userName);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = Boolean.valueOf(isSetFilters()).compareTo(other.isSetFilters());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetFilters()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.filters, other.filters);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = Boolean.valueOf(isSetLimit()).compareTo(other.isSetLimit());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetLimit()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.limit, other.limit);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = Boolean.valueOf(isSetOffset()).compareTo(other.isSetOffset());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetOffset()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.offset, other.offset);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      return 0;
    }

    public _Fields fieldForId(int fieldId) {
      return _Fields.findByThriftId(fieldId);
    }

    public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
      schemes.get(iprot.getScheme()).getScheme().read(iprot, this);
    }

    public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException {
      schemes.get(oprot.getScheme()).getScheme().write(oprot, this);
    }

    @Override
    public String toString() {
      StringBuilder sb = new StringBuilder("searchExperiments_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;
      if (!first) sb.append(", ");
      sb.append("userName:");
      if (this.userName == null) {
        sb.append("null");
      } else {
        sb.append(this.userName);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("filters:");
      if (this.filters == null) {
        sb.append("null");
      } else {
        sb.append(this.filters);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("limit:");
      sb.append(this.limit);
      first = false;
      if (!first) sb.append(", ");
      sb.append("offset:");
      sb.append(this.offset);
      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());
      }
      if (userName == null) {
        throw new org.apache.thrift.protocol.TProtocolException("Required field 'userName' was not present! Struct: " + toString());
      }
      // alas, we cannot check 'limit' because it's a primitive and you chose the non-beans generator.
      // alas, we cannot check 'offset' because it's a primitive and you chose the non-beans generator.
      // 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, 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 searchExperiments_argsStandardSchemeFactory implements SchemeFactory {
      public searchExperiments_argsStandardScheme getScheme() {
        return new searchExperiments_argsStandardScheme();
      }
    }

    private static class searchExperiments_argsStandardScheme extends StandardScheme<searchExperiments_args> {

      public void read(org.apache.thrift.protocol.TProtocol iprot, searchExperiments_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;
            case 3: // USER_NAME
              if (schemeField.type == org.apache.thrift.protocol.TType.STRING) {
                struct.userName = iprot.readString();
                struct.setUserNameIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 4: // FILTERS
              if (schemeField.type == org.apache.thrift.protocol.TType.MAP) {
                {
                  org.apache.thrift.protocol.TMap _map82 = iprot.readMapBegin();
                  struct.filters = new HashMap<org.apache.airavata.model.experiment.ExperimentSearchFields,String>(2*_map82.size);
                  org.apache.airavata.model.experiment.ExperimentSearchFields _key83;
                  String _val84;
                  for (int _i85 = 0; _i85 < _map82.size; ++_i85)
                  {
                    _key83 = org.apache.airavata.model.experiment.ExperimentSearchFields.findByValue(iprot.readI32());
                    _val84 = iprot.readString();
                    struct.filters.put(_key83, _val84);
                  }
                  iprot.readMapEnd();
                }
                struct.setFiltersIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 5: // LIMIT
              if (schemeField.type == org.apache.thrift.protocol.TType.I32) {
                struct.limit = iprot.readI32();
                struct.setLimitIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 6: // OFFSET
              if (schemeField.type == org.apache.thrift.protocol.TType.I32) {
                struct.offset = iprot.readI32();
                struct.setOffsetIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            default:
              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
          }
          iprot.readFieldEnd();
        }
        iprot.readStructEnd();

        // check for required fields of primitive type, which can't be checked in the validate method
        if (!struct.isSetLimit()) {
          throw new org.apache.thrift.protocol.TProtocolException("Required field 'limit' was not found in serialized data! Struct: " + toString());
        }
        if (!struct.isSetOffset()) {
          throw new org.apache.thrift.protocol.TProtocolException("Required field 'offset' was not found in serialized data! Struct: " + toString());
        }
        struct.validate();
      }

      public void write(org.apache.thrift.protocol.TProtocol oprot, searchExperiments_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();
        }
        if (struct.userName != null) {
          oprot.writeFieldBegin(USER_NAME_FIELD_DESC);
          oprot.writeString(struct.userName);
          oprot.writeFieldEnd();
        }
        if (struct.filters != null) {
          oprot.writeFieldBegin(FILTERS_FIELD_DESC);
          {
            oprot.writeMapBegin(new org.apache.thrift.protocol.TMap(org.apache.thrift.protocol.TType.I32, org.apache.thrift.protocol.TType.STRING, struct.filters.size()));
            for (Map.Entry<org.apache.airavata.model.experiment.ExperimentSearchFields, String> _iter86 : struct.filters.entrySet())
            {
              oprot.writeI32(_iter86.getKey().getValue());
              oprot.writeString(_iter86.getValue());
            }
            oprot.writeMapEnd();
          }
          oprot.writeFieldEnd();
        }
        oprot.writeFieldBegin(LIMIT_FIELD_DESC);
        oprot.writeI32(struct.limit);
        oprot.writeFieldEnd();
        oprot.writeFieldBegin(OFFSET_FIELD_DESC);
        oprot.writeI32(struct.offset);
        oprot.writeFieldEnd();
        oprot.writeFieldStop();
        oprot.writeStructEnd();
      }

    }

    private static class searchExperiments_argsTupleSchemeFactory implements SchemeFactory {
      public searchExperiments_argsTupleScheme getScheme() {
        return new searchExperiments_argsTupleScheme();
      }
    }

    private static class searchExperiments_argsTupleScheme extends TupleScheme<searchExperiments_args> {

      @Override
      public void write(org.apache.thrift.protocol.TProtocol prot, searchExperiments_args struct) throws org.apache.thrift.TException {
        TTupleProtocol oprot = (TTupleProtocol) prot;
        struct.authzToken.write(oprot);
        oprot.writeString(struct.gatewayId);
        oprot.writeString(struct.userName);
        oprot.writeI32(struct.limit);
        oprot.writeI32(struct.offset);
        BitSet optionals = new BitSet();
        if (struct.isSetFilters()) {
          optionals.set(0);
        }
        oprot.writeBitSet(optionals, 1);
        if (struct.isSetFilters()) {
          {
            oprot.writeI32(struct.filters.size());
            for (Map.Entry<org.apache.airavata.model.experiment.ExperimentSearchFields, String> _iter87 : struct.filters.entrySet())
            {
              oprot.writeI32(_iter87.getKey().getValue());
              oprot.writeString(_iter87.getValue());
            }
          }
        }
      }

      @Override
      public void read(org.apache.thrift.protocol.TProtocol prot, searchExperiments_args struct) throws org.apache.thrift.TException {
        TTupleProtocol iprot = (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);
        struct.userName = iprot.readString();
        struct.setUserNameIsSet(true);
        struct.limit = iprot.readI32();
        struct.setLimitIsSet(true);
        struct.offset = iprot.readI32();
        struct.setOffsetIsSet(true);
        BitSet incoming = iprot.readBitSet(1);
        if (incoming.get(0)) {
          {
            org.apache.thrift.protocol.TMap _map88 = new org.apache.thrift.protocol.TMap(org.apache.thrift.protocol.TType.I32, org.apache.thrift.protocol.TType.STRING, iprot.readI32());
            struct.filters = new HashMap<org.apache.airavata.model.experiment.ExperimentSearchFields,String>(2*_map88.size);
            org.apache.airavata.model.experiment.ExperimentSearchFields _key89;
            String _val90;
            for (int _i91 = 0; _i91 < _map88.size; ++_i91)
            {
              _key89 = org.apache.airavata.model.experiment.ExperimentSearchFields.findByValue(iprot.readI32());
              _val90 = iprot.readString();
              struct.filters.put(_key89, _val90);
            }
          }
          struct.setFiltersIsSet(true);
        }
      }
    }

  }

  public static class searchExperiments_result implements org.apache.thrift.TBase<searchExperiments_result, searchExperiments_result._Fields>, java.io.Serializable, Cloneable, Comparable<searchExperiments_result>   {
    private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("searchExperiments_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 IRE_FIELD_DESC = new org.apache.thrift.protocol.TField("ire", org.apache.thrift.protocol.TType.STRUCT, (short)1);
    private static final org.apache.thrift.protocol.TField ACE_FIELD_DESC = new org.apache.thrift.protocol.TField("ace", org.apache.thrift.protocol.TType.STRUCT, (short)2);
    private static final org.apache.thrift.protocol.TField ASE_FIELD_DESC = new org.apache.thrift.protocol.TField("ase", org.apache.thrift.protocol.TType.STRUCT, (short)3);
    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)4);

    private static final Map<Class<? extends IScheme>, SchemeFactory> schemes = new HashMap<Class<? extends IScheme>, SchemeFactory>();
    static {
      schemes.put(StandardScheme.class, new searchExperiments_resultStandardSchemeFactory());
      schemes.put(TupleScheme.class, new searchExperiments_resultTupleSchemeFactory());
    }

    public List<org.apache.airavata.model.experiment.ExperimentSummaryModel> success; // required
    public org.apache.airavata.model.error.InvalidRequestException ire; // required
    public org.apache.airavata.model.error.AiravataClientException ace; // required
    public org.apache.airavata.model.error.AiravataSystemException ase; // 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"),
      IRE((short)1, "ire"),
      ACE((short)2, "ace"),
      ASE((short)3, "ase"),
      AE((short)4, "ae");

      private static final Map<String, _Fields> byName = new HashMap<String, _Fields>();

      static {
        for (_Fields field : EnumSet.allOf(_Fields.class)) {
          byName.put(field.getFieldName(), field);
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, or null if its not found.
       */
      public static _Fields findByThriftId(int fieldId) {
        switch(fieldId) {
          case 0: // SUCCESS
            return SUCCESS;
          case 1: // IRE
            return IRE;
          case 2: // ACE
            return ACE;
          case 3: // ASE
            return ASE;
          case 4: // 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 IllegalArgumentException("Field " + fieldId + " doesn't exist!");
        return fields;
      }

      /**
       * Find the _Fields constant that matches name, or null if its not found.
       */
      public static _Fields findByName(String name) {
        return byName.get(name);
      }

      private final short _thriftId;
      private final String _fieldName;

      _Fields(short thriftId, String fieldName) {
        _thriftId = thriftId;
        _fieldName = fieldName;
      }

      public short getThriftFieldId() {
        return _thriftId;
      }

      public String getFieldName() {
        return _fieldName;
      }
    }

    // isset id assignments
    public static final Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
    static {
      Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new EnumMap<_Fields, org.apache.thrift.meta_data.FieldMetaData>(_Fields.class);
      tmpMap.put(_Fields.SUCCESS, new org.apache.thrift.meta_data.FieldMetaData("success", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.ListMetaData(org.apache.thrift.protocol.TType.LIST, 
              new org.apache.thrift.meta_data.StructMetaData(org.apache.thrift.protocol.TType.STRUCT, org.apache.airavata.model.experiment.ExperimentSummaryModel.class))));
      tmpMap.put(_Fields.IRE, new org.apache.thrift.meta_data.FieldMetaData("ire", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRUCT)));
      tmpMap.put(_Fields.ACE, new org.apache.thrift.meta_data.FieldMetaData("ace", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRUCT)));
      tmpMap.put(_Fields.ASE, new org.apache.thrift.meta_data.FieldMetaData("ase", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRUCT)));
      tmpMap.put(_Fields.AE, new org.apache.thrift.meta_data.FieldMetaData("ae", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRUCT)));
      metaDataMap = Collections.unmodifiableMap(tmpMap);
      org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(searchExperiments_result.class, metaDataMap);
    }

    public searchExperiments_result() {
    }

    public searchExperiments_result(
      List<org.apache.airavata.model.experiment.ExperimentSummaryModel> success,
      org.apache.airavata.model.error.InvalidRequestException ire,
      org.apache.airavata.model.error.AiravataClientException ace,
      org.apache.airavata.model.error.AiravataSystemException ase,
      org.apache.airavata.model.error.AuthorizationException ae)
    {
      this();
      this.success = success;
      this.ire = ire;
      this.ace = ace;
      this.ase = ase;
      this.ae = ae;
    }

    /**
     * Performs a deep copy on <i>other</i>.
     */
    public searchExperiments_result(searchExperiments_result other) {
      if (other.isSetSuccess()) {
        List<org.apache.airavata.model.experiment.ExperimentSummaryModel> __this__success = new ArrayList<org.apache.airavata.model.experiment.ExperimentSummaryModel>(other.success.size());
        for (org.apache.airavata.model.experiment.ExperimentSummaryModel other_element : other.success) {
          __this__success.add(new org.apache.airavata.model.experiment.ExperimentSummaryModel(other_element));
        }
        this.success = __this__success;
      }
      if (other.isSetIre()) {
        this.ire = new org.apache.airavata.model.error.InvalidRequestException(other.ire);
      }
      if (other.isSetAce()) {
        this.ace = new org.apache.airavata.model.error.AiravataClientException(other.ace);
      }
      if (other.isSetAse()) {
        this.ase = new org.apache.airavata.model.error.AiravataSystemException(other.ase);
      }
      if (other.isSetAe()) {
        this.ae = new org.apache.airavata.model.error.AuthorizationException(other.ae);
      }
    }

    public searchExperiments_result deepCopy() {
      return new searchExperiments_result(this);
    }

    @Override
    public void clear() {
      this.success = null;
      this.ire = null;
      this.ace = null;
      this.ase = null;
      this.ae = null;
    }

    public int getSuccessSize() {
      return (this.success == null) ? 0 : this.success.size();
    }

    public java.util.Iterator<org.apache.airavata.model.experiment.ExperimentSummaryModel> getSuccessIterator() {
      return (this.success == null) ? null : this.success.iterator();
    }

    public void addToSuccess(org.apache.airavata.model.experiment.ExperimentSummaryModel elem) {
      if (this.success == null) {
        this.success = new ArrayList<org.apache.airavata.model.experiment.ExperimentSummaryModel>();
      }
      this.success.add(elem);
    }

    public List<org.apache.airavata.model.experiment.ExperimentSummaryModel> getSuccess() {
      return this.success;
    }

    public searchExperiments_result setSuccess(List<org.apache.airavata.model.experiment.ExperimentSummaryModel> 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.model.error.InvalidRequestException getIre() {
      return this.ire;
    }

    public searchExperiments_result setIre(org.apache.airavata.model.error.InvalidRequestException ire) {
      this.ire = ire;
      return this;
    }

    public void unsetIre() {
      this.ire = null;
    }

    /** Returns true if field ire is set (has been assigned a value) and false otherwise */
    public boolean isSetIre() {
      return this.ire != null;
    }

    public void setIreIsSet(boolean value) {
      if (!value) {
        this.ire = null;
      }
    }

    public org.apache.airavata.model.error.AiravataClientException getAce() {
      return this.ace;
    }

    public searchExperiments_result setAce(org.apache.airavata.model.error.AiravataClientException ace) {
      this.ace = ace;
      return this;
    }

    public void unsetAce() {
      this.ace = null;
    }

    /** Returns true if field ace is set (has been assigned a value) and false otherwise */
    public boolean isSetAce() {
      return this.ace != null;
    }

    public void setAceIsSet(boolean value) {
      if (!value) {
        this.ace = null;
      }
    }

    public org.apache.airavata.model.error.AiravataSystemException getAse() {
      return this.ase;
    }

    public searchExperiments_result setAse(org.apache.airavata.model.error.AiravataSystemException ase) {
      this.ase = ase;
      return this;
    }

    public void unsetAse() {
      this.ase = null;
    }

    /** Returns true if field ase is set (has been assigned a value) and false otherwise */
    public boolean isSetAse() {
      return this.ase != null;
    }

    public void setAseIsSet(boolean value) {
      if (!value) {
        this.ase = null;
      }
    }

    public org.apache.airavata.model.error.AuthorizationException getAe() {
      return this.ae;
    }

    public searchExperiments_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, Object value) {
      switch (field) {
      case SUCCESS:
        if (value == null) {
          unsetSuccess();
        } else {
          setSuccess((List<org.apache.airavata.model.experiment.ExperimentSummaryModel>)value);
        }
        break;

      case IRE:
        if (value == null) {
          unsetIre();
        } else {
          setIre((org.apache.airavata.model.error.InvalidRequestException)value);
        }
        break;

      case ACE:
        if (value == null) {
          unsetAce();
        } else {
          setAce((org.apache.airavata.model.error.AiravataClientException)value);
        }
        break;

      case ASE:
        if (value == null) {
          unsetAse();
        } else {
          setAse((org.apache.airavata.model.error.AiravataSystemException)value);
        }
        break;

      case AE:
        if (value == null) {
          unsetAe();
        } else {
          setAe((org.apache.airavata.model.error.AuthorizationException)value);
        }
        break;

      }
    }

    public Object getFieldValue(_Fields field) {
      switch (field) {
      case SUCCESS:
        return getSuccess();

      case IRE:
        return getIre();

      case ACE:
        return getAce();

      case ASE:
        return getAse();

      case AE:
        return getAe();

      }
      throw new IllegalStateException();
    }

    /** Returns true if field corresponding to fieldID is set (has been assigned a value) and false otherwise */
    public boolean isSet(_Fields field) {
      if (field == null) {
        throw new IllegalArgumentException();
      }

      switch (field) {
      case SUCCESS:
        return isSetSuccess();
      case IRE:
        return isSetIre();
      case ACE:
        return isSetAce();
      case ASE:
        return isSetAse();
      case AE:
        return isSetAe();
      }
      throw new IllegalStateException();
    }

    @Override
    public boolean equals(Object that) {
      if (that == null)
        return false;
      if (that instanceof searchExperiments_result)
        return this.equals((searchExperiments_result)that);
      return false;
    }

    public boolean equals(searchExperiments_result that) {
      if (that == null)
        return false;

      boolean this_present_success = true && this.isSetSuccess();
      boolean that_present_success = true && that.isSetSuccess();
      if (this_present_success || that_present_success) {
        if (!(this_present_success && that_present_success))
          return false;
        if (!this.success.equals(that.success))
          return false;
      }

      boolean this_present_ire = true && this.isSetIre();
      boolean that_present_ire = true && that.isSetIre();
      if (this_present_ire || that_present_ire) {
        if (!(this_present_ire && that_present_ire))
          return false;
        if (!this.ire.equals(that.ire))
          return false;
      }

      boolean this_present_ace = true && this.isSetAce();
      boolean that_present_ace = true && that.isSetAce();
      if (this_present_ace || that_present_ace) {
        if (!(this_present_ace && that_present_ace))
          return false;
        if (!this.ace.equals(that.ace))
          return false;
      }

      boolean this_present_ase = true && this.isSetAse();
      boolean that_present_ase = true && that.isSetAse();
      if (this_present_ase || that_present_ase) {
        if (!(this_present_ase && that_present_ase))
          return false;
        if (!this.ase.equals(that.ase))
          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() {
      List<Object> list = new ArrayList<Object>();

      boolean present_success = true && (isSetSuccess());
      list.add(present_success);
      if (present_success)
        list.add(success);

      boolean present_ire = true && (isSetIre());
      list.add(present_ire);
      if (present_ire)
        list.add(ire);

      boolean present_ace = true && (isSetAce());
      list.add(present_ace);
      if (present_ace)
        list.add(ace);

      boolean present_ase = true && (isSetAse());
      list.add(present_ase);
      if (present_ase)
        list.add(ase);

      boolean present_ae = true && (isSetAe());
      list.add(present_ae);
      if (present_ae)
        list.add(ae);

      return list.hashCode();
    }

    @Override
    public int compareTo(searchExperiments_result other) {
      if (!getClass().equals(other.getClass())) {
        return getClass().getName().compareTo(other.getClass().getName());
      }

      int lastComparison = 0;

      lastComparison = Boolean.valueOf(isSetSuccess()).compareTo(other.isSetSuccess());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetSuccess()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.success, other.success);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = Boolean.valueOf(isSetIre()).compareTo(other.isSetIre());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetIre()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.ire, other.ire);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = Boolean.valueOf(isSetAce()).compareTo(other.isSetAce());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetAce()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.ace, other.ace);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = Boolean.valueOf(isSetAse()).compareTo(other.isSetAse());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetAse()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.ase, other.ase);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = 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 {
      schemes.get(iprot.getScheme()).getScheme().read(iprot, this);
    }

    public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException {
      schemes.get(oprot.getScheme()).getScheme().write(oprot, this);
      }

    @Override
    public String toString() {
      StringBuilder sb = new StringBuilder("searchExperiments_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("ire:");
      if (this.ire == null) {
        sb.append("null");
      } else {
        sb.append(this.ire);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("ace:");
      if (this.ace == null) {
        sb.append("null");
      } else {
        sb.append(this.ace);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("ase:");
      if (this.ase == null) {
        sb.append("null");
      } else {
        sb.append(this.ase);
      }
      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, 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 searchExperiments_resultStandardSchemeFactory implements SchemeFactory {
      public searchExperiments_resultStandardScheme getScheme() {
        return new searchExperiments_resultStandardScheme();
      }
    }

    private static class searchExperiments_resultStandardScheme extends StandardScheme<searchExperiments_result> {

      public void read(org.apache.thrift.protocol.TProtocol iprot, searchExperiments_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 _list92 = iprot.readListBegin();
                  struct.success = new ArrayList<org.apache.airavata.model.experiment.ExperimentSummaryModel>(_list92.size);
                  org.apache.airavata.model.experiment.ExperimentSummaryModel _elem93;
                  for (int _i94 = 0; _i94 < _list92.size; ++_i94)
                  {
                    _elem93 = new org.apache.airavata.model.experiment.ExperimentSummaryModel();
                    _elem93.read(iprot);
                    struct.success.add(_elem93);
                  }
                  iprot.readListEnd();
                }
                struct.setSuccessIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 1: // IRE
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.ire = new org.apache.airavata.model.error.InvalidRequestException();
                struct.ire.read(iprot);
                struct.setIreIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 2: // ACE
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.ace = new org.apache.airavata.model.error.AiravataClientException();
                struct.ace.read(iprot);
                struct.setAceIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 3: // ASE
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.ase = new org.apache.airavata.model.error.AiravataSystemException();
                struct.ase.read(iprot);
                struct.setAseIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 4: // 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, searchExperiments_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.experiment.ExperimentSummaryModel _iter95 : struct.success)
            {
              _iter95.write(oprot);
            }
            oprot.writeListEnd();
          }
          oprot.writeFieldEnd();
        }
        if (struct.ire != null) {
          oprot.writeFieldBegin(IRE_FIELD_DESC);
          struct.ire.write(oprot);
          oprot.writeFieldEnd();
        }
        if (struct.ace != null) {
          oprot.writeFieldBegin(ACE_FIELD_DESC);
          struct.ace.write(oprot);
          oprot.writeFieldEnd();
        }
        if (struct.ase != null) {
          oprot.writeFieldBegin(ASE_FIELD_DESC);
          struct.ase.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 searchExperiments_resultTupleSchemeFactory implements SchemeFactory {
      public searchExperiments_resultTupleScheme getScheme() {
        return new searchExperiments_resultTupleScheme();
      }
    }

    private static class searchExperiments_resultTupleScheme extends TupleScheme<searchExperiments_result> {

      @Override
      public void write(org.apache.thrift.protocol.TProtocol prot, searchExperiments_result struct) throws org.apache.thrift.TException {
        TTupleProtocol oprot = (TTupleProtocol) prot;
        BitSet optionals = new BitSet();
        if (struct.isSetSuccess()) {
          optionals.set(0);
        }
        if (struct.isSetIre()) {
          optionals.set(1);
        }
        if (struct.isSetAce()) {
          optionals.set(2);
        }
        if (struct.isSetAse()) {
          optionals.set(3);
        }
        if (struct.isSetAe()) {
          optionals.set(4);
        }
        oprot.writeBitSet(optionals, 5);
        if (struct.isSetSuccess()) {
          {
            oprot.writeI32(struct.success.size());
            for (org.apache.airavata.model.experiment.ExperimentSummaryModel _iter96 : struct.success)
            {
              _iter96.write(oprot);
            }
          }
        }
        if (struct.isSetIre()) {
          struct.ire.write(oprot);
        }
        if (struct.isSetAce()) {
          struct.ace.write(oprot);
        }
        if (struct.isSetAse()) {
          struct.ase.write(oprot);
        }
        if (struct.isSetAe()) {
          struct.ae.write(oprot);
        }
      }

      @Override
      public void read(org.apache.thrift.protocol.TProtocol prot, searchExperiments_result struct) throws org.apache.thrift.TException {
        TTupleProtocol iprot = (TTupleProtocol) prot;
        BitSet incoming = iprot.readBitSet(5);
        if (incoming.get(0)) {
          {
            org.apache.thrift.protocol.TList _list97 = new org.apache.thrift.protocol.TList(org.apache.thrift.protocol.TType.STRUCT, iprot.readI32());
            struct.success = new ArrayList<org.apache.airavata.model.experiment.ExperimentSummaryModel>(_list97.size);
            org.apache.airavata.model.experiment.ExperimentSummaryModel _elem98;
            for (int _i99 = 0; _i99 < _list97.size; ++_i99)
            {
              _elem98 = new org.apache.airavata.model.experiment.ExperimentSummaryModel();
              _elem98.read(iprot);
              struct.success.add(_elem98);
            }
          }
          struct.setSuccessIsSet(true);
        }
        if (incoming.get(1)) {
          struct.ire = new org.apache.airavata.model.error.InvalidRequestException();
          struct.ire.read(iprot);
          struct.setIreIsSet(true);
        }
        if (incoming.get(2)) {
          struct.ace = new org.apache.airavata.model.error.AiravataClientException();
          struct.ace.read(iprot);
          struct.setAceIsSet(true);
        }
        if (incoming.get(3)) {
          struct.ase = new org.apache.airavata.model.error.AiravataSystemException();
          struct.ase.read(iprot);
          struct.setAseIsSet(true);
        }
        if (incoming.get(4)) {
          struct.ae = new org.apache.airavata.model.error.AuthorizationException();
          struct.ae.read(iprot);
          struct.setAeIsSet(true);
        }
      }
    }

  }

  public static class getExperimentStatistics_args implements org.apache.thrift.TBase<getExperimentStatistics_args, getExperimentStatistics_args._Fields>, java.io.Serializable, Cloneable, Comparable<getExperimentStatistics_args>   {
    private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("getExperimentStatistics_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.protocol.TField FROM_TIME_FIELD_DESC = new org.apache.thrift.protocol.TField("fromTime", org.apache.thrift.protocol.TType.I64, (short)3);
    private static final org.apache.thrift.protocol.TField TO_TIME_FIELD_DESC = new org.apache.thrift.protocol.TField("toTime", org.apache.thrift.protocol.TType.I64, (short)4);

    private static final Map<Class<? extends IScheme>, SchemeFactory> schemes = new HashMap<Class<? extends IScheme>, SchemeFactory>();
    static {
      schemes.put(StandardScheme.class, new getExperimentStatistics_argsStandardSchemeFactory());
      schemes.put(TupleScheme.class, new getExperimentStatistics_argsTupleSchemeFactory());
    }

    public org.apache.airavata.model.security.AuthzToken authzToken; // required
    public String gatewayId; // required
    public long fromTime; // required
    public long toTime; // required

    /** 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"),
      FROM_TIME((short)3, "fromTime"),
      TO_TIME((short)4, "toTime");

      private static final Map<String, _Fields> byName = new HashMap<String, _Fields>();

      static {
        for (_Fields field : EnumSet.allOf(_Fields.class)) {
          byName.put(field.getFieldName(), field);
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, or null if its not found.
       */
      public static _Fields findByThriftId(int fieldId) {
        switch(fieldId) {
          case 1: // AUTHZ_TOKEN
            return AUTHZ_TOKEN;
          case 2: // GATEWAY_ID
            return GATEWAY_ID;
          case 3: // FROM_TIME
            return FROM_TIME;
          case 4: // TO_TIME
            return TO_TIME;
          default:
            return null;
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, throwing an exception
       * if it is not found.
       */
      public static _Fields findByThriftIdOrThrow(int fieldId) {
        _Fields fields = findByThriftId(fieldId);
        if (fields == null) throw new IllegalArgumentException("Field " + fieldId + " doesn't exist!");
        return fields;
      }

      /**
       * Find the _Fields constant that matches name, or null if its not found.
       */
      public static _Fields findByName(String name) {
        return byName.get(name);
      }

      private final short _thriftId;
      private final String _fieldName;

      _Fields(short thriftId, String fieldName) {
        _thriftId = thriftId;
        _fieldName = fieldName;
      }

      public short getThriftFieldId() {
        return _thriftId;
      }

      public String getFieldName() {
        return _fieldName;
      }
    }

    // isset id assignments
    private static final int __FROMTIME_ISSET_ID = 0;
    private static final int __TOTIME_ISSET_ID = 1;
    private byte __isset_bitfield = 0;
    public static final Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
    static {
      Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new EnumMap<_Fields, org.apache.thrift.meta_data.FieldMetaData>(_Fields.class);
      tmpMap.put(_Fields.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)));
      tmpMap.put(_Fields.FROM_TIME, new org.apache.thrift.meta_data.FieldMetaData("fromTime", org.apache.thrift.TFieldRequirementType.REQUIRED, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.I64)));
      tmpMap.put(_Fields.TO_TIME, new org.apache.thrift.meta_data.FieldMetaData("toTime", org.apache.thrift.TFieldRequirementType.REQUIRED, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.I64)));
      metaDataMap = Collections.unmodifiableMap(tmpMap);
      org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(getExperimentStatistics_args.class, metaDataMap);
    }

    public getExperimentStatistics_args() {
    }

    public getExperimentStatistics_args(
      org.apache.airavata.model.security.AuthzToken authzToken,
      String gatewayId,
      long fromTime,
      long toTime)
    {
      this();
      this.authzToken = authzToken;
      this.gatewayId = gatewayId;
      this.fromTime = fromTime;
      setFromTimeIsSet(true);
      this.toTime = toTime;
      setToTimeIsSet(true);
    }

    /**
     * Performs a deep copy on <i>other</i>.
     */
    public getExperimentStatistics_args(getExperimentStatistics_args other) {
      __isset_bitfield = other.__isset_bitfield;
      if (other.isSetAuthzToken()) {
        this.authzToken = new org.apache.airavata.model.security.AuthzToken(other.authzToken);
      }
      if (other.isSetGatewayId()) {
        this.gatewayId = other.gatewayId;
      }
      this.fromTime = other.fromTime;
      this.toTime = other.toTime;
    }

    public getExperimentStatistics_args deepCopy() {
      return new getExperimentStatistics_args(this);
    }

    @Override
    public void clear() {
      this.authzToken = null;
      this.gatewayId = null;
      setFromTimeIsSet(false);
      this.fromTime = 0;
      setToTimeIsSet(false);
      this.toTime = 0;
    }

    public org.apache.airavata.model.security.AuthzToken getAuthzToken() {
      return this.authzToken;
    }

    public getExperimentStatistics_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 String getGatewayId() {
      return this.gatewayId;
    }

    public getExperimentStatistics_args setGatewayId(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 long getFromTime() {
      return this.fromTime;
    }

    public getExperimentStatistics_args setFromTime(long fromTime) {
      this.fromTime = fromTime;
      setFromTimeIsSet(true);
      return this;
    }

    public void unsetFromTime() {
      __isset_bitfield = EncodingUtils.clearBit(__isset_bitfield, __FROMTIME_ISSET_ID);
    }

    /** Returns true if field fromTime is set (has been assigned a value) and false otherwise */
    public boolean isSetFromTime() {
      return EncodingUtils.testBit(__isset_bitfield, __FROMTIME_ISSET_ID);
    }

    public void setFromTimeIsSet(boolean value) {
      __isset_bitfield = EncodingUtils.setBit(__isset_bitfield, __FROMTIME_ISSET_ID, value);
    }

    public long getToTime() {
      return this.toTime;
    }

    public getExperimentStatistics_args setToTime(long toTime) {
      this.toTime = toTime;
      setToTimeIsSet(true);
      return this;
    }

    public void unsetToTime() {
      __isset_bitfield = EncodingUtils.clearBit(__isset_bitfield, __TOTIME_ISSET_ID);
    }

    /** Returns true if field toTime is set (has been assigned a value) and false otherwise */
    public boolean isSetToTime() {
      return EncodingUtils.testBit(__isset_bitfield, __TOTIME_ISSET_ID);
    }

    public void setToTimeIsSet(boolean value) {
      __isset_bitfield = EncodingUtils.setBit(__isset_bitfield, __TOTIME_ISSET_ID, value);
    }

    public void setFieldValue(_Fields field, 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((String)value);
        }
        break;

      case FROM_TIME:
        if (value == null) {
          unsetFromTime();
        } else {
          setFromTime((Long)value);
        }
        break;

      case TO_TIME:
        if (value == null) {
          unsetToTime();
        } else {
          setToTime((Long)value);
        }
        break;

      }
    }

    public Object getFieldValue(_Fields field) {
      switch (field) {
      case AUTHZ_TOKEN:
        return getAuthzToken();

      case GATEWAY_ID:
        return getGatewayId();

      case FROM_TIME:
        return Long.valueOf(getFromTime());

      case TO_TIME:
        return Long.valueOf(getToTime());

      }
      throw new IllegalStateException();
    }

    /** Returns true if field corresponding to fieldID is set (has been assigned a value) and false otherwise */
    public boolean isSet(_Fields field) {
      if (field == null) {
        throw new IllegalArgumentException();
      }

      switch (field) {
      case AUTHZ_TOKEN:
        return isSetAuthzToken();
      case GATEWAY_ID:
        return isSetGatewayId();
      case FROM_TIME:
        return isSetFromTime();
      case TO_TIME:
        return isSetToTime();
      }
      throw new IllegalStateException();
    }

    @Override
    public boolean equals(Object that) {
      if (that == null)
        return false;
      if (that instanceof getExperimentStatistics_args)
        return this.equals((getExperimentStatistics_args)that);
      return false;
    }

    public boolean equals(getExperimentStatistics_args that) {
      if (that == null)
        return false;

      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;
      }

      boolean this_present_fromTime = true;
      boolean that_present_fromTime = true;
      if (this_present_fromTime || that_present_fromTime) {
        if (!(this_present_fromTime && that_present_fromTime))
          return false;
        if (this.fromTime != that.fromTime)
          return false;
      }

      boolean this_present_toTime = true;
      boolean that_present_toTime = true;
      if (this_present_toTime || that_present_toTime) {
        if (!(this_present_toTime && that_present_toTime))
          return false;
        if (this.toTime != that.toTime)
          return false;
      }

      return true;
    }

    @Override
    public int hashCode() {
      List<Object> list = new ArrayList<Object>();

      boolean present_authzToken = true && (isSetAuthzToken());
      list.add(present_authzToken);
      if (present_authzToken)
        list.add(authzToken);

      boolean present_gatewayId = true && (isSetGatewayId());
      list.add(present_gatewayId);
      if (present_gatewayId)
        list.add(gatewayId);

      boolean present_fromTime = true;
      list.add(present_fromTime);
      if (present_fromTime)
        list.add(fromTime);

      boolean present_toTime = true;
      list.add(present_toTime);
      if (present_toTime)
        list.add(toTime);

      return list.hashCode();
    }

    @Override
    public int compareTo(getExperimentStatistics_args other) {
      if (!getClass().equals(other.getClass())) {
        return getClass().getName().compareTo(other.getClass().getName());
      }

      int lastComparison = 0;

      lastComparison = 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 = 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;
        }
      }
      lastComparison = Boolean.valueOf(isSetFromTime()).compareTo(other.isSetFromTime());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetFromTime()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.fromTime, other.fromTime);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = Boolean.valueOf(isSetToTime()).compareTo(other.isSetToTime());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetToTime()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.toTime, other.toTime);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      return 0;
    }

    public _Fields fieldForId(int fieldId) {
      return _Fields.findByThriftId(fieldId);
    }

    public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
      schemes.get(iprot.getScheme()).getScheme().read(iprot, this);
    }

    public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException {
      schemes.get(oprot.getScheme()).getScheme().write(oprot, this);
    }

    @Override
    public String toString() {
      StringBuilder sb = new StringBuilder("getExperimentStatistics_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;
      if (!first) sb.append(", ");
      sb.append("fromTime:");
      sb.append(this.fromTime);
      first = false;
      if (!first) sb.append(", ");
      sb.append("toTime:");
      sb.append(this.toTime);
      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());
      }
      // alas, we cannot check 'fromTime' because it's a primitive and you chose the non-beans generator.
      // alas, we cannot check 'toTime' because it's a primitive and you chose the non-beans generator.
      // 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, 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 getExperimentStatistics_argsStandardSchemeFactory implements SchemeFactory {
      public getExperimentStatistics_argsStandardScheme getScheme() {
        return new getExperimentStatistics_argsStandardScheme();
      }
    }

    private static class getExperimentStatistics_argsStandardScheme extends StandardScheme<getExperimentStatistics_args> {

      public void read(org.apache.thrift.protocol.TProtocol iprot, getExperimentStatistics_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;
            case 3: // FROM_TIME
              if (schemeField.type == org.apache.thrift.protocol.TType.I64) {
                struct.fromTime = iprot.readI64();
                struct.setFromTimeIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 4: // TO_TIME
              if (schemeField.type == org.apache.thrift.protocol.TType.I64) {
                struct.toTime = iprot.readI64();
                struct.setToTimeIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            default:
              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
          }
          iprot.readFieldEnd();
        }
        iprot.readStructEnd();

        // check for required fields of primitive type, which can't be checked in the validate method
        if (!struct.isSetFromTime()) {
          throw new org.apache.thrift.protocol.TProtocolException("Required field 'fromTime' was not found in serialized data! Struct: " + toString());
        }
        if (!struct.isSetToTime()) {
          throw new org.apache.thrift.protocol.TProtocolException("Required field 'toTime' was not found in serialized data! Struct: " + toString());
        }
        struct.validate();
      }

      public void write(org.apache.thrift.protocol.TProtocol oprot, getExperimentStatistics_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.writeFieldBegin(FROM_TIME_FIELD_DESC);
        oprot.writeI64(struct.fromTime);
        oprot.writeFieldEnd();
        oprot.writeFieldBegin(TO_TIME_FIELD_DESC);
        oprot.writeI64(struct.toTime);
        oprot.writeFieldEnd();
        oprot.writeFieldStop();
        oprot.writeStructEnd();
      }

    }

    private static class getExperimentStatistics_argsTupleSchemeFactory implements SchemeFactory {
      public getExperimentStatistics_argsTupleScheme getScheme() {
        return new getExperimentStatistics_argsTupleScheme();
      }
    }

    private static class getExperimentStatistics_argsTupleScheme extends TupleScheme<getExperimentStatistics_args> {

      @Override
      public void write(org.apache.thrift.protocol.TProtocol prot, getExperimentStatistics_args struct) throws org.apache.thrift.TException {
        TTupleProtocol oprot = (TTupleProtocol) prot;
        struct.authzToken.write(oprot);
        oprot.writeString(struct.gatewayId);
        oprot.writeI64(struct.fromTime);
        oprot.writeI64(struct.toTime);
      }

      @Override
      public void read(org.apache.thrift.protocol.TProtocol prot, getExperimentStatistics_args struct) throws org.apache.thrift.TException {
        TTupleProtocol iprot = (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);
        struct.fromTime = iprot.readI64();
        struct.setFromTimeIsSet(true);
        struct.toTime = iprot.readI64();
        struct.setToTimeIsSet(true);
      }
    }

  }

  public static class getExperimentStatistics_result implements org.apache.thrift.TBase<getExperimentStatistics_result, getExperimentStatistics_result._Fields>, java.io.Serializable, Cloneable, Comparable<getExperimentStatistics_result>   {
    private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("getExperimentStatistics_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 IRE_FIELD_DESC = new org.apache.thrift.protocol.TField("ire", org.apache.thrift.protocol.TType.STRUCT, (short)1);
    private static final org.apache.thrift.protocol.TField ACE_FIELD_DESC = new org.apache.thrift.protocol.TField("ace", org.apache.thrift.protocol.TType.STRUCT, (short)2);
    private static final org.apache.thrift.protocol.TField ASE_FIELD_DESC = new org.apache.thrift.protocol.TField("ase", org.apache.thrift.protocol.TType.STRUCT, (short)3);
    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)4);

    private static final Map<Class<? extends IScheme>, SchemeFactory> schemes = new HashMap<Class<? extends IScheme>, SchemeFactory>();
    static {
      schemes.put(StandardScheme.class, new getExperimentStatistics_resultStandardSchemeFactory());
      schemes.put(TupleScheme.class, new getExperimentStatistics_resultTupleSchemeFactory());
    }

    public org.apache.airavata.model.experiment.ExperimentStatistics success; // required
    public org.apache.airavata.model.error.InvalidRequestException ire; // required
    public org.apache.airavata.model.error.AiravataClientException ace; // required
    public org.apache.airavata.model.error.AiravataSystemException ase; // 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"),
      IRE((short)1, "ire"),
      ACE((short)2, "ace"),
      ASE((short)3, "ase"),
      AE((short)4, "ae");

      private static final Map<String, _Fields> byName = new HashMap<String, _Fields>();

      static {
        for (_Fields field : EnumSet.allOf(_Fields.class)) {
          byName.put(field.getFieldName(), field);
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, or null if its not found.
       */
      public static _Fields findByThriftId(int fieldId) {
        switch(fieldId) {
          case 0: // SUCCESS
            return SUCCESS;
          case 1: // IRE
            return IRE;
          case 2: // ACE
            return ACE;
          case 3: // ASE
            return ASE;
          case 4: // 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 IllegalArgumentException("Field " + fieldId + " doesn't exist!");
        return fields;
      }

      /**
       * Find the _Fields constant that matches name, or null if its not found.
       */
      public static _Fields findByName(String name) {
        return byName.get(name);
      }

      private final short _thriftId;
      private final String _fieldName;

      _Fields(short thriftId, String fieldName) {
        _thriftId = thriftId;
        _fieldName = fieldName;
      }

      public short getThriftFieldId() {
        return _thriftId;
      }

      public String getFieldName() {
        return _fieldName;
      }
    }

    // isset id assignments
    public static final Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
    static {
      Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new EnumMap<_Fields, org.apache.thrift.meta_data.FieldMetaData>(_Fields.class);
      tmpMap.put(_Fields.SUCCESS, new org.apache.thrift.meta_data.FieldMetaData("success", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.StructMetaData(org.apache.thrift.protocol.TType.STRUCT, org.apache.airavata.model.experiment.ExperimentStatistics.class)));
      tmpMap.put(_Fields.IRE, new org.apache.thrift.meta_data.FieldMetaData("ire", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRUCT)));
      tmpMap.put(_Fields.ACE, new org.apache.thrift.meta_data.FieldMetaData("ace", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRUCT)));
      tmpMap.put(_Fields.ASE, new org.apache.thrift.meta_data.FieldMetaData("ase", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRUCT)));
      tmpMap.put(_Fields.AE, new org.apache.thrift.meta_data.FieldMetaData("ae", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRUCT)));
      metaDataMap = Collections.unmodifiableMap(tmpMap);
      org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(getExperimentStatistics_result.class, metaDataMap);
    }

    public getExperimentStatistics_result() {
    }

    public getExperimentStatistics_result(
      org.apache.airavata.model.experiment.ExperimentStatistics success,
      org.apache.airavata.model.error.InvalidRequestException ire,
      org.apache.airavata.model.error.AiravataClientException ace,
      org.apache.airavata.model.error.AiravataSystemException ase,
      org.apache.airavata.model.error.AuthorizationException ae)
    {
      this();
      this.success = success;
      this.ire = ire;
      this.ace = ace;
      this.ase = ase;
      this.ae = ae;
    }

    /**
     * Performs a deep copy on <i>other</i>.
     */
    public getExperimentStatistics_result(getExperimentStatistics_result other) {
      if (other.isSetSuccess()) {
        this.success = new org.apache.airavata.model.experiment.ExperimentStatistics(other.success);
      }
      if (other.isSetIre()) {
        this.ire = new org.apache.airavata.model.error.InvalidRequestException(other.ire);
      }
      if (other.isSetAce()) {
        this.ace = new org.apache.airavata.model.error.AiravataClientException(other.ace);
      }
      if (other.isSetAse()) {
        this.ase = new org.apache.airavata.model.error.AiravataSystemException(other.ase);
      }
      if (other.isSetAe()) {
        this.ae = new org.apache.airavata.model.error.AuthorizationException(other.ae);
      }
    }

    public getExperimentStatistics_result deepCopy() {
      return new getExperimentStatistics_result(this);
    }

    @Override
    public void clear() {
      this.success = null;
      this.ire = null;
      this.ace = null;
      this.ase = null;
      this.ae = null;
    }

    public org.apache.airavata.model.experiment.ExperimentStatistics getSuccess() {
      return this.success;
    }

    public getExperimentStatistics_result setSuccess(org.apache.airavata.model.experiment.ExperimentStatistics 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.model.error.InvalidRequestException getIre() {
      return this.ire;
    }

    public getExperimentStatistics_result setIre(org.apache.airavata.model.error.InvalidRequestException ire) {
      this.ire = ire;
      return this;
    }

    public void unsetIre() {
      this.ire = null;
    }

    /** Returns true if field ire is set (has been assigned a value) and false otherwise */
    public boolean isSetIre() {
      return this.ire != null;
    }

    public void setIreIsSet(boolean value) {
      if (!value) {
        this.ire = null;
      }
    }

    public org.apache.airavata.model.error.AiravataClientException getAce() {
      return this.ace;
    }

    public getExperimentStatistics_result setAce(org.apache.airavata.model.error.AiravataClientException ace) {
      this.ace = ace;
      return this;
    }

    public void unsetAce() {
      this.ace = null;
    }

    /** Returns true if field ace is set (has been assigned a value) and false otherwise */
    public boolean isSetAce() {
      return this.ace != null;
    }

    public void setAceIsSet(boolean value) {
      if (!value) {
        this.ace = null;
      }
    }

    public org.apache.airavata.model.error.AiravataSystemException getAse() {
      return this.ase;
    }

    public getExperimentStatistics_result setAse(org.apache.airavata.model.error.AiravataSystemException ase) {
      this.ase = ase;
      return this;
    }

    public void unsetAse() {
      this.ase = null;
    }

    /** Returns true if field ase is set (has been assigned a value) and false otherwise */
    public boolean isSetAse() {
      return this.ase != null;
    }

    public void setAseIsSet(boolean value) {
      if (!value) {
        this.ase = null;
      }
    }

    public org.apache.airavata.model.error.AuthorizationException getAe() {
      return this.ae;
    }

    public getExperimentStatistics_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, Object value) {
      switch (field) {
      case SUCCESS:
        if (value == null) {
          unsetSuccess();
        } else {
          setSuccess((org.apache.airavata.model.experiment.ExperimentStatistics)value);
        }
        break;

      case IRE:
        if (value == null) {
          unsetIre();
        } else {
          setIre((org.apache.airavata.model.error.InvalidRequestException)value);
        }
        break;

      case ACE:
        if (value == null) {
          unsetAce();
        } else {
          setAce((org.apache.airavata.model.error.AiravataClientException)value);
        }
        break;

      case ASE:
        if (value == null) {
          unsetAse();
        } else {
          setAse((org.apache.airavata.model.error.AiravataSystemException)value);
        }
        break;

      case AE:
        if (value == null) {
          unsetAe();
        } else {
          setAe((org.apache.airavata.model.error.AuthorizationException)value);
        }
        break;

      }
    }

    public Object getFieldValue(_Fields field) {
      switch (field) {
      case SUCCESS:
        return getSuccess();

      case IRE:
        return getIre();

      case ACE:
        return getAce();

      case ASE:
        return getAse();

      case AE:
        return getAe();

      }
      throw new IllegalStateException();
    }

    /** Returns true if field corresponding to fieldID is set (has been assigned a value) and false otherwise */
    public boolean isSet(_Fields field) {
      if (field == null) {
        throw new IllegalArgumentException();
      }

      switch (field) {
      case SUCCESS:
        return isSetSuccess();
      case IRE:
        return isSetIre();
      case ACE:
        return isSetAce();
      case ASE:
        return isSetAse();
      case AE:
        return isSetAe();
      }
      throw new IllegalStateException();
    }

    @Override
    public boolean equals(Object that) {
      if (that == null)
        return false;
      if (that instanceof getExperimentStatistics_result)
        return this.equals((getExperimentStatistics_result)that);
      return false;
    }

    public boolean equals(getExperimentStatistics_result that) {
      if (that == null)
        return false;

      boolean this_present_success = true && this.isSetSuccess();
      boolean that_present_success = true && that.isSetSuccess();
      if (this_present_success || that_present_success) {
        if (!(this_present_success && that_present_success))
          return false;
        if (!this.success.equals(that.success))
          return false;
      }

      boolean this_present_ire = true && this.isSetIre();
      boolean that_present_ire = true && that.isSetIre();
      if (this_present_ire || that_present_ire) {
        if (!(this_present_ire && that_present_ire))
          return false;
        if (!this.ire.equals(that.ire))
          return false;
      }

      boolean this_present_ace = true && this.isSetAce();
      boolean that_present_ace = true && that.isSetAce();
      if (this_present_ace || that_present_ace) {
        if (!(this_present_ace && that_present_ace))
          return false;
        if (!this.ace.equals(that.ace))
          return false;
      }

      boolean this_present_ase = true && this.isSetAse();
      boolean that_present_ase = true && that.isSetAse();
      if (this_present_ase || that_present_ase) {
        if (!(this_present_ase && that_present_ase))
          return false;
        if (!this.ase.equals(that.ase))
          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() {
      List<Object> list = new ArrayList<Object>();

      boolean present_success = true && (isSetSuccess());
      list.add(present_success);
      if (present_success)
        list.add(success);

      boolean present_ire = true && (isSetIre());
      list.add(present_ire);
      if (present_ire)
        list.add(ire);

      boolean present_ace = true && (isSetAce());
      list.add(present_ace);
      if (present_ace)
        list.add(ace);

      boolean present_ase = true && (isSetAse());
      list.add(present_ase);
      if (present_ase)
        list.add(ase);

      boolean present_ae = true && (isSetAe());
      list.add(present_ae);
      if (present_ae)
        list.add(ae);

      return list.hashCode();
    }

    @Override
    public int compareTo(getExperimentStatistics_result other) {
      if (!getClass().equals(other.getClass())) {
        return getClass().getName().compareTo(other.getClass().getName());
      }

      int lastComparison = 0;

      lastComparison = Boolean.valueOf(isSetSuccess()).compareTo(other.isSetSuccess());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetSuccess()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.success, other.success);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = Boolean.valueOf(isSetIre()).compareTo(other.isSetIre());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetIre()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.ire, other.ire);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = Boolean.valueOf(isSetAce()).compareTo(other.isSetAce());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetAce()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.ace, other.ace);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = Boolean.valueOf(isSetAse()).compareTo(other.isSetAse());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetAse()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.ase, other.ase);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = 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 {
      schemes.get(iprot.getScheme()).getScheme().read(iprot, this);
    }

    public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException {
      schemes.get(oprot.getScheme()).getScheme().write(oprot, this);
      }

    @Override
    public String toString() {
      StringBuilder sb = new StringBuilder("getExperimentStatistics_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("ire:");
      if (this.ire == null) {
        sb.append("null");
      } else {
        sb.append(this.ire);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("ace:");
      if (this.ace == null) {
        sb.append("null");
      } else {
        sb.append(this.ace);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("ase:");
      if (this.ase == null) {
        sb.append("null");
      } else {
        sb.append(this.ase);
      }
      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, 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 getExperimentStatistics_resultStandardSchemeFactory implements SchemeFactory {
      public getExperimentStatistics_resultStandardScheme getScheme() {
        return new getExperimentStatistics_resultStandardScheme();
      }
    }

    private static class getExperimentStatistics_resultStandardScheme extends StandardScheme<getExperimentStatistics_result> {

      public void read(org.apache.thrift.protocol.TProtocol iprot, getExperimentStatistics_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.experiment.ExperimentStatistics();
                struct.success.read(iprot);
                struct.setSuccessIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 1: // IRE
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.ire = new org.apache.airavata.model.error.InvalidRequestException();
                struct.ire.read(iprot);
                struct.setIreIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 2: // ACE
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.ace = new org.apache.airavata.model.error.AiravataClientException();
                struct.ace.read(iprot);
                struct.setAceIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 3: // ASE
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.ase = new org.apache.airavata.model.error.AiravataSystemException();
                struct.ase.read(iprot);
                struct.setAseIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 4: // 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, getExperimentStatistics_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.ire != null) {
          oprot.writeFieldBegin(IRE_FIELD_DESC);
          struct.ire.write(oprot);
          oprot.writeFieldEnd();
        }
        if (struct.ace != null) {
          oprot.writeFieldBegin(ACE_FIELD_DESC);
          struct.ace.write(oprot);
          oprot.writeFieldEnd();
        }
        if (struct.ase != null) {
          oprot.writeFieldBegin(ASE_FIELD_DESC);
          struct.ase.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 getExperimentStatistics_resultTupleSchemeFactory implements SchemeFactory {
      public getExperimentStatistics_resultTupleScheme getScheme() {
        return new getExperimentStatistics_resultTupleScheme();
      }
    }

    private static class getExperimentStatistics_resultTupleScheme extends TupleScheme<getExperimentStatistics_result> {

      @Override
      public void write(org.apache.thrift.protocol.TProtocol prot, getExperimentStatistics_result struct) throws org.apache.thrift.TException {
        TTupleProtocol oprot = (TTupleProtocol) prot;
        BitSet optionals = new BitSet();
        if (struct.isSetSuccess()) {
          optionals.set(0);
        }
        if (struct.isSetIre()) {
          optionals.set(1);
        }
        if (struct.isSetAce()) {
          optionals.set(2);
        }
        if (struct.isSetAse()) {
          optionals.set(3);
        }
        if (struct.isSetAe()) {
          optionals.set(4);
        }
        oprot.writeBitSet(optionals, 5);
        if (struct.isSetSuccess()) {
          struct.success.write(oprot);
        }
        if (struct.isSetIre()) {
          struct.ire.write(oprot);
        }
        if (struct.isSetAce()) {
          struct.ace.write(oprot);
        }
        if (struct.isSetAse()) {
          struct.ase.write(oprot);
        }
        if (struct.isSetAe()) {
          struct.ae.write(oprot);
        }
      }

      @Override
      public void read(org.apache.thrift.protocol.TProtocol prot, getExperimentStatistics_result struct) throws org.apache.thrift.TException {
        TTupleProtocol iprot = (TTupleProtocol) prot;
        BitSet incoming = iprot.readBitSet(5);
        if (incoming.get(0)) {
          struct.success = new org.apache.airavata.model.experiment.ExperimentStatistics();
          struct.success.read(iprot);
          struct.setSuccessIsSet(true);
        }
        if (incoming.get(1)) {
          struct.ire = new org.apache.airavata.model.error.InvalidRequestException();
          struct.ire.read(iprot);
          struct.setIreIsSet(true);
        }
        if (incoming.get(2)) {
          struct.ace = new org.apache.airavata.model.error.AiravataClientException();
          struct.ace.read(iprot);
          struct.setAceIsSet(true);
        }
        if (incoming.get(3)) {
          struct.ase = new org.apache.airavata.model.error.AiravataSystemException();
          struct.ase.read(iprot);
          struct.setAseIsSet(true);
        }
        if (incoming.get(4)) {
          struct.ae = new org.apache.airavata.model.error.AuthorizationException();
          struct.ae.read(iprot);
          struct.setAeIsSet(true);
        }
      }
    }

  }

  public static class getExperimentsInProject_args implements org.apache.thrift.TBase<getExperimentsInProject_args, getExperimentsInProject_args._Fields>, java.io.Serializable, Cloneable, Comparable<getExperimentsInProject_args>   {
    private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("getExperimentsInProject_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 PROJECT_ID_FIELD_DESC = new org.apache.thrift.protocol.TField("projectId", org.apache.thrift.protocol.TType.STRING, (short)2);
    private static final org.apache.thrift.protocol.TField LIMIT_FIELD_DESC = new org.apache.thrift.protocol.TField("limit", org.apache.thrift.protocol.TType.I32, (short)3);
    private static final org.apache.thrift.protocol.TField OFFSET_FIELD_DESC = new org.apache.thrift.protocol.TField("offset", org.apache.thrift.protocol.TType.I32, (short)4);

    private static final Map<Class<? extends IScheme>, SchemeFactory> schemes = new HashMap<Class<? extends IScheme>, SchemeFactory>();
    static {
      schemes.put(StandardScheme.class, new getExperimentsInProject_argsStandardSchemeFactory());
      schemes.put(TupleScheme.class, new getExperimentsInProject_argsTupleSchemeFactory());
    }

    public org.apache.airavata.model.security.AuthzToken authzToken; // required
    public String projectId; // required
    public int limit; // required
    public int offset; // required

    /** 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"),
      PROJECT_ID((short)2, "projectId"),
      LIMIT((short)3, "limit"),
      OFFSET((short)4, "offset");

      private static final Map<String, _Fields> byName = new HashMap<String, _Fields>();

      static {
        for (_Fields field : EnumSet.allOf(_Fields.class)) {
          byName.put(field.getFieldName(), field);
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, or null if its not found.
       */
      public static _Fields findByThriftId(int fieldId) {
        switch(fieldId) {
          case 1: // AUTHZ_TOKEN
            return AUTHZ_TOKEN;
          case 2: // PROJECT_ID
            return PROJECT_ID;
          case 3: // LIMIT
            return LIMIT;
          case 4: // OFFSET
            return OFFSET;
          default:
            return null;
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, throwing an exception
       * if it is not found.
       */
      public static _Fields findByThriftIdOrThrow(int fieldId) {
        _Fields fields = findByThriftId(fieldId);
        if (fields == null) throw new IllegalArgumentException("Field " + fieldId + " doesn't exist!");
        return fields;
      }

      /**
       * Find the _Fields constant that matches name, or null if its not found.
       */
      public static _Fields findByName(String name) {
        return byName.get(name);
      }

      private final short _thriftId;
      private final String _fieldName;

      _Fields(short thriftId, String fieldName) {
        _thriftId = thriftId;
        _fieldName = fieldName;
      }

      public short getThriftFieldId() {
        return _thriftId;
      }

      public String getFieldName() {
        return _fieldName;
      }
    }

    // isset id assignments
    private static final int __LIMIT_ISSET_ID = 0;
    private static final int __OFFSET_ISSET_ID = 1;
    private byte __isset_bitfield = 0;
    public static final Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
    static {
      Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new EnumMap<_Fields, org.apache.thrift.meta_data.FieldMetaData>(_Fields.class);
      tmpMap.put(_Fields.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.PROJECT_ID, new org.apache.thrift.meta_data.FieldMetaData("projectId", org.apache.thrift.TFieldRequirementType.REQUIRED, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING)));
      tmpMap.put(_Fields.LIMIT, new org.apache.thrift.meta_data.FieldMetaData("limit", org.apache.thrift.TFieldRequirementType.REQUIRED, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.I32)));
      tmpMap.put(_Fields.OFFSET, new org.apache.thrift.meta_data.FieldMetaData("offset", org.apache.thrift.TFieldRequirementType.REQUIRED, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.I32)));
      metaDataMap = Collections.unmodifiableMap(tmpMap);
      org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(getExperimentsInProject_args.class, metaDataMap);
    }

    public getExperimentsInProject_args() {
    }

    public getExperimentsInProject_args(
      org.apache.airavata.model.security.AuthzToken authzToken,
      String projectId,
      int limit,
      int offset)
    {
      this();
      this.authzToken = authzToken;
      this.projectId = projectId;
      this.limit = limit;
      setLimitIsSet(true);
      this.offset = offset;
      setOffsetIsSet(true);
    }

    /**
     * Performs a deep copy on <i>other</i>.
     */
    public getExperimentsInProject_args(getExperimentsInProject_args other) {
      __isset_bitfield = other.__isset_bitfield;
      if (other.isSetAuthzToken()) {
        this.authzToken = new org.apache.airavata.model.security.AuthzToken(other.authzToken);
      }
      if (other.isSetProjectId()) {
        this.projectId = other.projectId;
      }
      this.limit = other.limit;
      this.offset = other.offset;
    }

    public getExperimentsInProject_args deepCopy() {
      return new getExperimentsInProject_args(this);
    }

    @Override
    public void clear() {
      this.authzToken = null;
      this.projectId = null;
      setLimitIsSet(false);
      this.limit = 0;
      setOffsetIsSet(false);
      this.offset = 0;
    }

    public org.apache.airavata.model.security.AuthzToken getAuthzToken() {
      return this.authzToken;
    }

    public getExperimentsInProject_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 String getProjectId() {
      return this.projectId;
    }

    public getExperimentsInProject_args setProjectId(String projectId) {
      this.projectId = projectId;
      return this;
    }

    public void unsetProjectId() {
      this.projectId = null;
    }

    /** Returns true if field projectId is set (has been assigned a value) and false otherwise */
    public boolean isSetProjectId() {
      return this.projectId != null;
    }

    public void setProjectIdIsSet(boolean value) {
      if (!value) {
        this.projectId = null;
      }
    }

    public int getLimit() {
      return this.limit;
    }

    public getExperimentsInProject_args setLimit(int limit) {
      this.limit = limit;
      setLimitIsSet(true);
      return this;
    }

    public void unsetLimit() {
      __isset_bitfield = EncodingUtils.clearBit(__isset_bitfield, __LIMIT_ISSET_ID);
    }

    /** Returns true if field limit is set (has been assigned a value) and false otherwise */
    public boolean isSetLimit() {
      return EncodingUtils.testBit(__isset_bitfield, __LIMIT_ISSET_ID);
    }

    public void setLimitIsSet(boolean value) {
      __isset_bitfield = EncodingUtils.setBit(__isset_bitfield, __LIMIT_ISSET_ID, value);
    }

    public int getOffset() {
      return this.offset;
    }

    public getExperimentsInProject_args setOffset(int offset) {
      this.offset = offset;
      setOffsetIsSet(true);
      return this;
    }

    public void unsetOffset() {
      __isset_bitfield = EncodingUtils.clearBit(__isset_bitfield, __OFFSET_ISSET_ID);
    }

    /** Returns true if field offset is set (has been assigned a value) and false otherwise */
    public boolean isSetOffset() {
      return EncodingUtils.testBit(__isset_bitfield, __OFFSET_ISSET_ID);
    }

    public void setOffsetIsSet(boolean value) {
      __isset_bitfield = EncodingUtils.setBit(__isset_bitfield, __OFFSET_ISSET_ID, value);
    }

    public void setFieldValue(_Fields field, Object value) {
      switch (field) {
      case AUTHZ_TOKEN:
        if (value == null) {
          unsetAuthzToken();
        } else {
          setAuthzToken((org.apache.airavata.model.security.AuthzToken)value);
        }
        break;

      case PROJECT_ID:
        if (value == null) {
          unsetProjectId();
        } else {
          setProjectId((String)value);
        }
        break;

      case LIMIT:
        if (value == null) {
          unsetLimit();
        } else {
          setLimit((Integer)value);
        }
        break;

      case OFFSET:
        if (value == null) {
          unsetOffset();
        } else {
          setOffset((Integer)value);
        }
        break;

      }
    }

    public Object getFieldValue(_Fields field) {
      switch (field) {
      case AUTHZ_TOKEN:
        return getAuthzToken();

      case PROJECT_ID:
        return getProjectId();

      case LIMIT:
        return Integer.valueOf(getLimit());

      case OFFSET:
        return Integer.valueOf(getOffset());

      }
      throw new IllegalStateException();
    }

    /** Returns true if field corresponding to fieldID is set (has been assigned a value) and false otherwise */
    public boolean isSet(_Fields field) {
      if (field == null) {
        throw new IllegalArgumentException();
      }

      switch (field) {
      case AUTHZ_TOKEN:
        return isSetAuthzToken();
      case PROJECT_ID:
        return isSetProjectId();
      case LIMIT:
        return isSetLimit();
      case OFFSET:
        return isSetOffset();
      }
      throw new IllegalStateException();
    }

    @Override
    public boolean equals(Object that) {
      if (that == null)
        return false;
      if (that instanceof getExperimentsInProject_args)
        return this.equals((getExperimentsInProject_args)that);
      return false;
    }

    public boolean equals(getExperimentsInProject_args that) {
      if (that == null)
        return false;

      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_projectId = true && this.isSetProjectId();
      boolean that_present_projectId = true && that.isSetProjectId();
      if (this_present_projectId || that_present_projectId) {
        if (!(this_present_projectId && that_present_projectId))
          return false;
        if (!this.projectId.equals(that.projectId))
          return false;
      }

      boolean this_present_limit = true;
      boolean that_present_limit = true;
      if (this_present_limit || that_present_limit) {
        if (!(this_present_limit && that_present_limit))
          return false;
        if (this.limit != that.limit)
          return false;
      }

      boolean this_present_offset = true;
      boolean that_present_offset = true;
      if (this_present_offset || that_present_offset) {
        if (!(this_present_offset && that_present_offset))
          return false;
        if (this.offset != that.offset)
          return false;
      }

      return true;
    }

    @Override
    public int hashCode() {
      List<Object> list = new ArrayList<Object>();

      boolean present_authzToken = true && (isSetAuthzToken());
      list.add(present_authzToken);
      if (present_authzToken)
        list.add(authzToken);

      boolean present_projectId = true && (isSetProjectId());
      list.add(present_projectId);
      if (present_projectId)
        list.add(projectId);

      boolean present_limit = true;
      list.add(present_limit);
      if (present_limit)
        list.add(limit);

      boolean present_offset = true;
      list.add(present_offset);
      if (present_offset)
        list.add(offset);

      return list.hashCode();
    }

    @Override
    public int compareTo(getExperimentsInProject_args other) {
      if (!getClass().equals(other.getClass())) {
        return getClass().getName().compareTo(other.getClass().getName());
      }

      int lastComparison = 0;

      lastComparison = 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 = Boolean.valueOf(isSetProjectId()).compareTo(other.isSetProjectId());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetProjectId()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.projectId, other.projectId);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = Boolean.valueOf(isSetLimit()).compareTo(other.isSetLimit());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetLimit()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.limit, other.limit);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = Boolean.valueOf(isSetOffset()).compareTo(other.isSetOffset());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetOffset()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.offset, other.offset);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      return 0;
    }

    public _Fields fieldForId(int fieldId) {
      return _Fields.findByThriftId(fieldId);
    }

    public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
      schemes.get(iprot.getScheme()).getScheme().read(iprot, this);
    }

    public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException {
      schemes.get(oprot.getScheme()).getScheme().write(oprot, this);
    }

    @Override
    public String toString() {
      StringBuilder sb = new StringBuilder("getExperimentsInProject_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("projectId:");
      if (this.projectId == null) {
        sb.append("null");
      } else {
        sb.append(this.projectId);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("limit:");
      sb.append(this.limit);
      first = false;
      if (!first) sb.append(", ");
      sb.append("offset:");
      sb.append(this.offset);
      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 (projectId == null) {
        throw new org.apache.thrift.protocol.TProtocolException("Required field 'projectId' was not present! Struct: " + toString());
      }
      // alas, we cannot check 'limit' because it's a primitive and you chose the non-beans generator.
      // alas, we cannot check 'offset' because it's a primitive and you chose the non-beans generator.
      // 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, 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 getExperimentsInProject_argsStandardSchemeFactory implements SchemeFactory {
      public getExperimentsInProject_argsStandardScheme getScheme() {
        return new getExperimentsInProject_argsStandardScheme();
      }
    }

    private static class getExperimentsInProject_argsStandardScheme extends StandardScheme<getExperimentsInProject_args> {

      public void read(org.apache.thrift.protocol.TProtocol iprot, getExperimentsInProject_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: // PROJECT_ID
              if (schemeField.type == org.apache.thrift.protocol.TType.STRING) {
                struct.projectId = iprot.readString();
                struct.setProjectIdIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 3: // LIMIT
              if (schemeField.type == org.apache.thrift.protocol.TType.I32) {
                struct.limit = iprot.readI32();
                struct.setLimitIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 4: // OFFSET
              if (schemeField.type == org.apache.thrift.protocol.TType.I32) {
                struct.offset = iprot.readI32();
                struct.setOffsetIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            default:
              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
          }
          iprot.readFieldEnd();
        }
        iprot.readStructEnd();

        // check for required fields of primitive type, which can't be checked in the validate method
        if (!struct.isSetLimit()) {
          throw new org.apache.thrift.protocol.TProtocolException("Required field 'limit' was not found in serialized data! Struct: " + toString());
        }
        if (!struct.isSetOffset()) {
          throw new org.apache.thrift.protocol.TProtocolException("Required field 'offset' was not found in serialized data! Struct: " + toString());
        }
        struct.validate();
      }

      public void write(org.apache.thrift.protocol.TProtocol oprot, getExperimentsInProject_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.projectId != null) {
          oprot.writeFieldBegin(PROJECT_ID_FIELD_DESC);
          oprot.writeString(struct.projectId);
          oprot.writeFieldEnd();
        }
        oprot.writeFieldBegin(LIMIT_FIELD_DESC);
        oprot.writeI32(struct.limit);
        oprot.writeFieldEnd();
        oprot.writeFieldBegin(OFFSET_FIELD_DESC);
        oprot.writeI32(struct.offset);
        oprot.writeFieldEnd();
        oprot.writeFieldStop();
        oprot.writeStructEnd();
      }

    }

    private static class getExperimentsInProject_argsTupleSchemeFactory implements SchemeFactory {
      public getExperimentsInProject_argsTupleScheme getScheme() {
        return new getExperimentsInProject_argsTupleScheme();
      }
    }

    private static class getExperimentsInProject_argsTupleScheme extends TupleScheme<getExperimentsInProject_args> {

      @Override
      public void write(org.apache.thrift.protocol.TProtocol prot, getExperimentsInProject_args struct) throws org.apache.thrift.TException {
        TTupleProtocol oprot = (TTupleProtocol) prot;
        struct.authzToken.write(oprot);
        oprot.writeString(struct.projectId);
        oprot.writeI32(struct.limit);
        oprot.writeI32(struct.offset);
      }

      @Override
      public void read(org.apache.thrift.protocol.TProtocol prot, getExperimentsInProject_args struct) throws org.apache.thrift.TException {
        TTupleProtocol iprot = (TTupleProtocol) prot;
        struct.authzToken = new org.apache.airavata.model.security.AuthzToken();
        struct.authzToken.read(iprot);
        struct.setAuthzTokenIsSet(true);
        struct.projectId = iprot.readString();
        struct.setProjectIdIsSet(true);
        struct.limit = iprot.readI32();
        struct.setLimitIsSet(true);
        struct.offset = iprot.readI32();
        struct.setOffsetIsSet(true);
      }
    }

  }

  public static class getExperimentsInProject_result implements org.apache.thrift.TBase<getExperimentsInProject_result, getExperimentsInProject_result._Fields>, java.io.Serializable, Cloneable, Comparable<getExperimentsInProject_result>   {
    private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("getExperimentsInProject_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 IRE_FIELD_DESC = new org.apache.thrift.protocol.TField("ire", org.apache.thrift.protocol.TType.STRUCT, (short)1);
    private static final org.apache.thrift.protocol.TField ACE_FIELD_DESC = new org.apache.thrift.protocol.TField("ace", org.apache.thrift.protocol.TType.STRUCT, (short)2);
    private static final org.apache.thrift.protocol.TField ASE_FIELD_DESC = new org.apache.thrift.protocol.TField("ase", org.apache.thrift.protocol.TType.STRUCT, (short)3);
    private static final org.apache.thrift.protocol.TField PNFE_FIELD_DESC = new org.apache.thrift.protocol.TField("pnfe", org.apache.thrift.protocol.TType.STRUCT, (short)4);
    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)5);

    private static final Map<Class<? extends IScheme>, SchemeFactory> schemes = new HashMap<Class<? extends IScheme>, SchemeFactory>();
    static {
      schemes.put(StandardScheme.class, new getExperimentsInProject_resultStandardSchemeFactory());
      schemes.put(TupleScheme.class, new getExperimentsInProject_resultTupleSchemeFactory());
    }

    public List<org.apache.airavata.model.experiment.ExperimentModel> success; // required
    public org.apache.airavata.model.error.InvalidRequestException ire; // required
    public org.apache.airavata.model.error.AiravataClientException ace; // required
    public org.apache.airavata.model.error.AiravataSystemException ase; // required
    public org.apache.airavata.model.error.ProjectNotFoundException pnfe; // 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"),
      IRE((short)1, "ire"),
      ACE((short)2, "ace"),
      ASE((short)3, "ase"),
      PNFE((short)4, "pnfe"),
      AE((short)5, "ae");

      private static final Map<String, _Fields> byName = new HashMap<String, _Fields>();

      static {
        for (_Fields field : EnumSet.allOf(_Fields.class)) {
          byName.put(field.getFieldName(), field);
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, or null if its not found.
       */
      public static _Fields findByThriftId(int fieldId) {
        switch(fieldId) {
          case 0: // SUCCESS
            return SUCCESS;
          case 1: // IRE
            return IRE;
          case 2: // ACE
            return ACE;
          case 3: // ASE
            return ASE;
          case 4: // PNFE
            return PNFE;
          case 5: // 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 IllegalArgumentException("Field " + fieldId + " doesn't exist!");
        return fields;
      }

      /**
       * Find the _Fields constant that matches name, or null if its not found.
       */
      public static _Fields findByName(String name) {
        return byName.get(name);
      }

      private final short _thriftId;
      private final String _fieldName;

      _Fields(short thriftId, String fieldName) {
        _thriftId = thriftId;
        _fieldName = fieldName;
      }

      public short getThriftFieldId() {
        return _thriftId;
      }

      public String getFieldName() {
        return _fieldName;
      }
    }

    // isset id assignments
    public static final Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
    static {
      Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new EnumMap<_Fields, org.apache.thrift.meta_data.FieldMetaData>(_Fields.class);
      tmpMap.put(_Fields.SUCCESS, new org.apache.thrift.meta_data.FieldMetaData("success", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.ListMetaData(org.apache.thrift.protocol.TType.LIST, 
              new org.apache.thrift.meta_data.StructMetaData(org.apache.thrift.protocol.TType.STRUCT, org.apache.airavata.model.experiment.ExperimentModel.class))));
      tmpMap.put(_Fields.IRE, new org.apache.thrift.meta_data.FieldMetaData("ire", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRUCT)));
      tmpMap.put(_Fields.ACE, new org.apache.thrift.meta_data.FieldMetaData("ace", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRUCT)));
      tmpMap.put(_Fields.ASE, new org.apache.thrift.meta_data.FieldMetaData("ase", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRUCT)));
      tmpMap.put(_Fields.PNFE, new org.apache.thrift.meta_data.FieldMetaData("pnfe", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRUCT)));
      tmpMap.put(_Fields.AE, new org.apache.thrift.meta_data.FieldMetaData("ae", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRUCT)));
      metaDataMap = Collections.unmodifiableMap(tmpMap);
      org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(getExperimentsInProject_result.class, metaDataMap);
    }

    public getExperimentsInProject_result() {
    }

    public getExperimentsInProject_result(
      List<org.apache.airavata.model.experiment.ExperimentModel> success,
      org.apache.airavata.model.error.InvalidRequestException ire,
      org.apache.airavata.model.error.AiravataClientException ace,
      org.apache.airavata.model.error.AiravataSystemException ase,
      org.apache.airavata.model.error.ProjectNotFoundException pnfe,
      org.apache.airavata.model.error.AuthorizationException ae)
    {
      this();
      this.success = success;
      this.ire = ire;
      this.ace = ace;
      this.ase = ase;
      this.pnfe = pnfe;
      this.ae = ae;
    }

    /**
     * Performs a deep copy on <i>other</i>.
     */
    public getExperimentsInProject_result(getExperimentsInProject_result other) {
      if (other.isSetSuccess()) {
        List<org.apache.airavata.model.experiment.ExperimentModel> __this__success = new ArrayList<org.apache.airavata.model.experiment.ExperimentModel>(other.success.size());
        for (org.apache.airavata.model.experiment.ExperimentModel other_element : other.success) {
          __this__success.add(new org.apache.airavata.model.experiment.ExperimentModel(other_element));
        }
        this.success = __this__success;
      }
      if (other.isSetIre()) {
        this.ire = new org.apache.airavata.model.error.InvalidRequestException(other.ire);
      }
      if (other.isSetAce()) {
        this.ace = new org.apache.airavata.model.error.AiravataClientException(other.ace);
      }
      if (other.isSetAse()) {
        this.ase = new org.apache.airavata.model.error.AiravataSystemException(other.ase);
      }
      if (other.isSetPnfe()) {
        this.pnfe = new org.apache.airavata.model.error.ProjectNotFoundException(other.pnfe);
      }
      if (other.isSetAe()) {
        this.ae = new org.apache.airavata.model.error.AuthorizationException(other.ae);
      }
    }

    public getExperimentsInProject_result deepCopy() {
      return new getExperimentsInProject_result(this);
    }

    @Override
    public void clear() {
      this.success = null;
      this.ire = null;
      this.ace = null;
      this.ase = null;
      this.pnfe = null;
      this.ae = null;
    }

    public int getSuccessSize() {
      return (this.success == null) ? 0 : this.success.size();
    }

    public java.util.Iterator<org.apache.airavata.model.experiment.ExperimentModel> getSuccessIterator() {
      return (this.success == null) ? null : this.success.iterator();
    }

    public void addToSuccess(org.apache.airavata.model.experiment.ExperimentModel elem) {
      if (this.success == null) {
        this.success = new ArrayList<org.apache.airavata.model.experiment.ExperimentModel>();
      }
      this.success.add(elem);
    }

    public List<org.apache.airavata.model.experiment.ExperimentModel> getSuccess() {
      return this.success;
    }

    public getExperimentsInProject_result setSuccess(List<org.apache.airavata.model.experiment.ExperimentModel> 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.model.error.InvalidRequestException getIre() {
      return this.ire;
    }

    public getExperimentsInProject_result setIre(org.apache.airavata.model.error.InvalidRequestException ire) {
      this.ire = ire;
      return this;
    }

    public void unsetIre() {
      this.ire = null;
    }

    /** Returns true if field ire is set (has been assigned a value) and false otherwise */
    public boolean isSetIre() {
      return this.ire != null;
    }

    public void setIreIsSet(boolean value) {
      if (!value) {
        this.ire = null;
      }
    }

    public org.apache.airavata.model.error.AiravataClientException getAce() {
      return this.ace;
    }

    public getExperimentsInProject_result setAce(org.apache.airavata.model.error.AiravataClientException ace) {
      this.ace = ace;
      return this;
    }

    public void unsetAce() {
      this.ace = null;
    }

    /** Returns true if field ace is set (has been assigned a value) and false otherwise */
    public boolean isSetAce() {
      return this.ace != null;
    }

    public void setAceIsSet(boolean value) {
      if (!value) {
        this.ace = null;
      }
    }

    public org.apache.airavata.model.error.AiravataSystemException getAse() {
      return this.ase;
    }

    public getExperimentsInProject_result setAse(org.apache.airavata.model.error.AiravataSystemException ase) {
      this.ase = ase;
      return this;
    }

    public void unsetAse() {
      this.ase = null;
    }

    /** Returns true if field ase is set (has been assigned a value) and false otherwise */
    public boolean isSetAse() {
      return this.ase != null;
    }

    public void setAseIsSet(boolean value) {
      if (!value) {
        this.ase = null;
      }
    }

    public org.apache.airavata.model.error.ProjectNotFoundException getPnfe() {
      return this.pnfe;
    }

    public getExperimentsInProject_result setPnfe(org.apache.airavata.model.error.ProjectNotFoundException pnfe) {
      this.pnfe = pnfe;
      return this;
    }

    public void unsetPnfe() {
      this.pnfe = null;
    }

    /** Returns true if field pnfe is set (has been assigned a value) and false otherwise */
    public boolean isSetPnfe() {
      return this.pnfe != null;
    }

    public void setPnfeIsSet(boolean value) {
      if (!value) {
        this.pnfe = null;
      }
    }

    public org.apache.airavata.model.error.AuthorizationException getAe() {
      return this.ae;
    }

    public getExperimentsInProject_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, Object value) {
      switch (field) {
      case SUCCESS:
        if (value == null) {
          unsetSuccess();
        } else {
          setSuccess((List<org.apache.airavata.model.experiment.ExperimentModel>)value);
        }
        break;

      case IRE:
        if (value == null) {
          unsetIre();
        } else {
          setIre((org.apache.airavata.model.error.InvalidRequestException)value);
        }
        break;

      case ACE:
        if (value == null) {
          unsetAce();
        } else {
          setAce((org.apache.airavata.model.error.AiravataClientException)value);
        }
        break;

      case ASE:
        if (value == null) {
          unsetAse();
        } else {
          setAse((org.apache.airavata.model.error.AiravataSystemException)value);
        }
        break;

      case PNFE:
        if (value == null) {
          unsetPnfe();
        } else {
          setPnfe((org.apache.airavata.model.error.ProjectNotFoundException)value);
        }
        break;

      case AE:
        if (value == null) {
          unsetAe();
        } else {
          setAe((org.apache.airavata.model.error.AuthorizationException)value);
        }
        break;

      }
    }

    public Object getFieldValue(_Fields field) {
      switch (field) {
      case SUCCESS:
        return getSuccess();

      case IRE:
        return getIre();

      case ACE:
        return getAce();

      case ASE:
        return getAse();

      case PNFE:
        return getPnfe();

      case AE:
        return getAe();

      }
      throw new IllegalStateException();
    }

    /** Returns true if field corresponding to fieldID is set (has been assigned a value) and false otherwise */
    public boolean isSet(_Fields field) {
      if (field == null) {
        throw new IllegalArgumentException();
      }

      switch (field) {
      case SUCCESS:
        return isSetSuccess();
      case IRE:
        return isSetIre();
      case ACE:
        return isSetAce();
      case ASE:
        return isSetAse();
      case PNFE:
        return isSetPnfe();
      case AE:
        return isSetAe();
      }
      throw new IllegalStateException();
    }

    @Override
    public boolean equals(Object that) {
      if (that == null)
        return false;
      if (that instanceof getExperimentsInProject_result)
        return this.equals((getExperimentsInProject_result)that);
      return false;
    }

    public boolean equals(getExperimentsInProject_result that) {
      if (that == null)
        return false;

      boolean this_present_success = true && this.isSetSuccess();
      boolean that_present_success = true && that.isSetSuccess();
      if (this_present_success || that_present_success) {
        if (!(this_present_success && that_present_success))
          return false;
        if (!this.success.equals(that.success))
          return false;
      }

      boolean this_present_ire = true && this.isSetIre();
      boolean that_present_ire = true && that.isSetIre();
      if (this_present_ire || that_present_ire) {
        if (!(this_present_ire && that_present_ire))
          return false;
        if (!this.ire.equals(that.ire))
          return false;
      }

      boolean this_present_ace = true && this.isSetAce();
      boolean that_present_ace = true && that.isSetAce();
      if (this_present_ace || that_present_ace) {
        if (!(this_present_ace && that_present_ace))
          return false;
        if (!this.ace.equals(that.ace))
          return false;
      }

      boolean this_present_ase = true && this.isSetAse();
      boolean that_present_ase = true && that.isSetAse();
      if (this_present_ase || that_present_ase) {
        if (!(this_present_ase && that_present_ase))
          return false;
        if (!this.ase.equals(that.ase))
          return false;
      }

      boolean this_present_pnfe = true && this.isSetPnfe();
      boolean that_present_pnfe = true && that.isSetPnfe();
      if (this_present_pnfe || that_present_pnfe) {
        if (!(this_present_pnfe && that_present_pnfe))
          return false;
        if (!this.pnfe.equals(that.pnfe))
          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() {
      List<Object> list = new ArrayList<Object>();

      boolean present_success = true && (isSetSuccess());
      list.add(present_success);
      if (present_success)
        list.add(success);

      boolean present_ire = true && (isSetIre());
      list.add(present_ire);
      if (present_ire)
        list.add(ire);

      boolean present_ace = true && (isSetAce());
      list.add(present_ace);
      if (present_ace)
        list.add(ace);

      boolean present_ase = true && (isSetAse());
      list.add(present_ase);
      if (present_ase)
        list.add(ase);

      boolean present_pnfe = true && (isSetPnfe());
      list.add(present_pnfe);
      if (present_pnfe)
        list.add(pnfe);

      boolean present_ae = true && (isSetAe());
      list.add(present_ae);
      if (present_ae)
        list.add(ae);

      return list.hashCode();
    }

    @Override
    public int compareTo(getExperimentsInProject_result other) {
      if (!getClass().equals(other.getClass())) {
        return getClass().getName().compareTo(other.getClass().getName());
      }

      int lastComparison = 0;

      lastComparison = Boolean.valueOf(isSetSuccess()).compareTo(other.isSetSuccess());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetSuccess()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.success, other.success);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = Boolean.valueOf(isSetIre()).compareTo(other.isSetIre());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetIre()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.ire, other.ire);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = Boolean.valueOf(isSetAce()).compareTo(other.isSetAce());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetAce()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.ace, other.ace);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = Boolean.valueOf(isSetAse()).compareTo(other.isSetAse());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetAse()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.ase, other.ase);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = Boolean.valueOf(isSetPnfe()).compareTo(other.isSetPnfe());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetPnfe()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.pnfe, other.pnfe);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = 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 {
      schemes.get(iprot.getScheme()).getScheme().read(iprot, this);
    }

    public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException {
      schemes.get(oprot.getScheme()).getScheme().write(oprot, this);
      }

    @Override
    public String toString() {
      StringBuilder sb = new StringBuilder("getExperimentsInProject_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("ire:");
      if (this.ire == null) {
        sb.append("null");
      } else {
        sb.append(this.ire);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("ace:");
      if (this.ace == null) {
        sb.append("null");
      } else {
        sb.append(this.ace);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("ase:");
      if (this.ase == null) {
        sb.append("null");
      } else {
        sb.append(this.ase);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("pnfe:");
      if (this.pnfe == null) {
        sb.append("null");
      } else {
        sb.append(this.pnfe);
      }
      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, 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 getExperimentsInProject_resultStandardSchemeFactory implements SchemeFactory {
      public getExperimentsInProject_resultStandardScheme getScheme() {
        return new getExperimentsInProject_resultStandardScheme();
      }
    }

    private static class getExperimentsInProject_resultStandardScheme extends StandardScheme<getExperimentsInProject_result> {

      public void read(org.apache.thrift.protocol.TProtocol iprot, getExperimentsInProject_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 _list100 = iprot.readListBegin();
                  struct.success = new ArrayList<org.apache.airavata.model.experiment.ExperimentModel>(_list100.size);
                  org.apache.airavata.model.experiment.ExperimentModel _elem101;
                  for (int _i102 = 0; _i102 < _list100.size; ++_i102)
                  {
                    _elem101 = new org.apache.airavata.model.experiment.ExperimentModel();
                    _elem101.read(iprot);
                    struct.success.add(_elem101);
                  }
                  iprot.readListEnd();
                }
                struct.setSuccessIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 1: // IRE
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.ire = new org.apache.airavata.model.error.InvalidRequestException();
                struct.ire.read(iprot);
                struct.setIreIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 2: // ACE
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.ace = new org.apache.airavata.model.error.AiravataClientException();
                struct.ace.read(iprot);
                struct.setAceIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 3: // ASE
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.ase = new org.apache.airavata.model.error.AiravataSystemException();
                struct.ase.read(iprot);
                struct.setAseIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 4: // PNFE
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.pnfe = new org.apache.airavata.model.error.ProjectNotFoundException();
                struct.pnfe.read(iprot);
                struct.setPnfeIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 5: // 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, getExperimentsInProject_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.experiment.ExperimentModel _iter103 : struct.success)
            {
              _iter103.write(oprot);
            }
            oprot.writeListEnd();
          }
          oprot.writeFieldEnd();
        }
        if (struct.ire != null) {
          oprot.writeFieldBegin(IRE_FIELD_DESC);
          struct.ire.write(oprot);
          oprot.writeFieldEnd();
        }
        if (struct.ace != null) {
          oprot.writeFieldBegin(ACE_FIELD_DESC);
          struct.ace.write(oprot);
          oprot.writeFieldEnd();
        }
        if (struct.ase != null) {
          oprot.writeFieldBegin(ASE_FIELD_DESC);
          struct.ase.write(oprot);
          oprot.writeFieldEnd();
        }
        if (struct.pnfe != null) {
          oprot.writeFieldBegin(PNFE_FIELD_DESC);
          struct.pnfe.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 getExperimentsInProject_resultTupleSchemeFactory implements SchemeFactory {
      public getExperimentsInProject_resultTupleScheme getScheme() {
        return new getExperimentsInProject_resultTupleScheme();
      }
    }

    private static class getExperimentsInProject_resultTupleScheme extends TupleScheme<getExperimentsInProject_result> {

      @Override
      public void write(org.apache.thrift.protocol.TProtocol prot, getExperimentsInProject_result struct) throws org.apache.thrift.TException {
        TTupleProtocol oprot = (TTupleProtocol) prot;
        BitSet optionals = new BitSet();
        if (struct.isSetSuccess()) {
          optionals.set(0);
        }
        if (struct.isSetIre()) {
          optionals.set(1);
        }
        if (struct.isSetAce()) {
          optionals.set(2);
        }
        if (struct.isSetAse()) {
          optionals.set(3);
        }
        if (struct.isSetPnfe()) {
          optionals.set(4);
        }
        if (struct.isSetAe()) {
          optionals.set(5);
        }
        oprot.writeBitSet(optionals, 6);
        if (struct.isSetSuccess()) {
          {
            oprot.writeI32(struct.success.size());
            for (org.apache.airavata.model.experiment.ExperimentModel _iter104 : struct.success)
            {
              _iter104.write(oprot);
            }
          }
        }
        if (struct.isSetIre()) {
          struct.ire.write(oprot);
        }
        if (struct.isSetAce()) {
          struct.ace.write(oprot);
        }
        if (struct.isSetAse()) {
          struct.ase.write(oprot);
        }
        if (struct.isSetPnfe()) {
          struct.pnfe.write(oprot);
        }
        if (struct.isSetAe()) {
          struct.ae.write(oprot);
        }
      }

      @Override
      public void read(org.apache.thrift.protocol.TProtocol prot, getExperimentsInProject_result struct) throws org.apache.thrift.TException {
        TTupleProtocol iprot = (TTupleProtocol) prot;
        BitSet incoming = iprot.readBitSet(6);
        if (incoming.get(0)) {
          {
            org.apache.thrift.protocol.TList _list105 = new org.apache.thrift.protocol.TList(org.apache.thrift.protocol.TType.STRUCT, iprot.readI32());
            struct.success = new ArrayList<org.apache.airavata.model.experiment.ExperimentModel>(_list105.size);
            org.apache.airavata.model.experiment.ExperimentModel _elem106;
            for (int _i107 = 0; _i107 < _list105.size; ++_i107)
            {
              _elem106 = new org.apache.airavata.model.experiment.ExperimentModel();
              _elem106.read(iprot);
              struct.success.add(_elem106);
            }
          }
          struct.setSuccessIsSet(true);
        }
        if (incoming.get(1)) {
          struct.ire = new org.apache.airavata.model.error.InvalidRequestException();
          struct.ire.read(iprot);
          struct.setIreIsSet(true);
        }
        if (incoming.get(2)) {
          struct.ace = new org.apache.airavata.model.error.AiravataClientException();
          struct.ace.read(iprot);
          struct.setAceIsSet(true);
        }
        if (incoming.get(3)) {
          struct.ase = new org.apache.airavata.model.error.AiravataSystemException();
          struct.ase.read(iprot);
          struct.setAseIsSet(true);
        }
        if (incoming.get(4)) {
          struct.pnfe = new org.apache.airavata.model.error.ProjectNotFoundException();
          struct.pnfe.read(iprot);
          struct.setPnfeIsSet(true);
        }
        if (incoming.get(5)) {
          struct.ae = new org.apache.airavata.model.error.AuthorizationException();
          struct.ae.read(iprot);
          struct.setAeIsSet(true);
        }
      }
    }

  }

  public static class getUserExperiments_args implements org.apache.thrift.TBase<getUserExperiments_args, getUserExperiments_args._Fields>, java.io.Serializable, Cloneable, Comparable<getUserExperiments_args>   {
    private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("getUserExperiments_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.protocol.TField USER_NAME_FIELD_DESC = new org.apache.thrift.protocol.TField("userName", org.apache.thrift.protocol.TType.STRING, (short)3);
    private static final org.apache.thrift.protocol.TField LIMIT_FIELD_DESC = new org.apache.thrift.protocol.TField("limit", org.apache.thrift.protocol.TType.I32, (short)4);
    private static final org.apache.thrift.protocol.TField OFFSET_FIELD_DESC = new org.apache.thrift.protocol.TField("offset", org.apache.thrift.protocol.TType.I32, (short)5);

    private static final Map<Class<? extends IScheme>, SchemeFactory> schemes = new HashMap<Class<? extends IScheme>, SchemeFactory>();
    static {
      schemes.put(StandardScheme.class, new getUserExperiments_argsStandardSchemeFactory());
      schemes.put(TupleScheme.class, new getUserExperiments_argsTupleSchemeFactory());
    }

    public org.apache.airavata.model.security.AuthzToken authzToken; // required
    public String gatewayId; // required
    public String userName; // required
    public int limit; // required
    public int offset; // required

    /** 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"),
      USER_NAME((short)3, "userName"),
      LIMIT((short)4, "limit"),
      OFFSET((short)5, "offset");

      private static final Map<String, _Fields> byName = new HashMap<String, _Fields>();

      static {
        for (_Fields field : EnumSet.allOf(_Fields.class)) {
          byName.put(field.getFieldName(), field);
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, or null if its not found.
       */
      public static _Fields findByThriftId(int fieldId) {
        switch(fieldId) {
          case 1: // AUTHZ_TOKEN
            return AUTHZ_TOKEN;
          case 2: // GATEWAY_ID
            return GATEWAY_ID;
          case 3: // USER_NAME
            return USER_NAME;
          case 4: // LIMIT
            return LIMIT;
          case 5: // OFFSET
            return OFFSET;
          default:
            return null;
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, throwing an exception
       * if it is not found.
       */
      public static _Fields findByThriftIdOrThrow(int fieldId) {
        _Fields fields = findByThriftId(fieldId);
        if (fields == null) throw new IllegalArgumentException("Field " + fieldId + " doesn't exist!");
        return fields;
      }

      /**
       * Find the _Fields constant that matches name, or null if its not found.
       */
      public static _Fields findByName(String name) {
        return byName.get(name);
      }

      private final short _thriftId;
      private final String _fieldName;

      _Fields(short thriftId, String fieldName) {
        _thriftId = thriftId;
        _fieldName = fieldName;
      }

      public short getThriftFieldId() {
        return _thriftId;
      }

      public String getFieldName() {
        return _fieldName;
      }
    }

    // isset id assignments
    private static final int __LIMIT_ISSET_ID = 0;
    private static final int __OFFSET_ISSET_ID = 1;
    private byte __isset_bitfield = 0;
    public static final Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
    static {
      Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new EnumMap<_Fields, org.apache.thrift.meta_data.FieldMetaData>(_Fields.class);
      tmpMap.put(_Fields.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)));
      tmpMap.put(_Fields.USER_NAME, new org.apache.thrift.meta_data.FieldMetaData("userName", org.apache.thrift.TFieldRequirementType.REQUIRED, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING)));
      tmpMap.put(_Fields.LIMIT, new org.apache.thrift.meta_data.FieldMetaData("limit", org.apache.thrift.TFieldRequirementType.REQUIRED, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.I32)));
      tmpMap.put(_Fields.OFFSET, new org.apache.thrift.meta_data.FieldMetaData("offset", org.apache.thrift.TFieldRequirementType.REQUIRED, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.I32)));
      metaDataMap = Collections.unmodifiableMap(tmpMap);
      org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(getUserExperiments_args.class, metaDataMap);
    }

    public getUserExperiments_args() {
    }

    public getUserExperiments_args(
      org.apache.airavata.model.security.AuthzToken authzToken,
      String gatewayId,
      String userName,
      int limit,
      int offset)
    {
      this();
      this.authzToken = authzToken;
      this.gatewayId = gatewayId;
      this.userName = userName;
      this.limit = limit;
      setLimitIsSet(true);
      this.offset = offset;
      setOffsetIsSet(true);
    }

    /**
     * Performs a deep copy on <i>other</i>.
     */
    public getUserExperiments_args(getUserExperiments_args other) {
      __isset_bitfield = other.__isset_bitfield;
      if (other.isSetAuthzToken()) {
        this.authzToken = new org.apache.airavata.model.security.AuthzToken(other.authzToken);
      }
      if (other.isSetGatewayId()) {
        this.gatewayId = other.gatewayId;
      }
      if (other.isSetUserName()) {
        this.userName = other.userName;
      }
      this.limit = other.limit;
      this.offset = other.offset;
    }

    public getUserExperiments_args deepCopy() {
      return new getUserExperiments_args(this);
    }

    @Override
    public void clear() {
      this.authzToken = null;
      this.gatewayId = null;
      this.userName = null;
      setLimitIsSet(false);
      this.limit = 0;
      setOffsetIsSet(false);
      this.offset = 0;
    }

    public org.apache.airavata.model.security.AuthzToken getAuthzToken() {
      return this.authzToken;
    }

    public getUserExperiments_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 String getGatewayId() {
      return this.gatewayId;
    }

    public getUserExperiments_args setGatewayId(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 String getUserName() {
      return this.userName;
    }

    public getUserExperiments_args setUserName(String userName) {
      this.userName = userName;
      return this;
    }

    public void unsetUserName() {
      this.userName = null;
    }

    /** Returns true if field userName is set (has been assigned a value) and false otherwise */
    public boolean isSetUserName() {
      return this.userName != null;
    }

    public void setUserNameIsSet(boolean value) {
      if (!value) {
        this.userName = null;
      }
    }

    public int getLimit() {
      return this.limit;
    }

    public getUserExperiments_args setLimit(int limit) {
      this.limit = limit;
      setLimitIsSet(true);
      return this;
    }

    public void unsetLimit() {
      __isset_bitfield = EncodingUtils.clearBit(__isset_bitfield, __LIMIT_ISSET_ID);
    }

    /** Returns true if field limit is set (has been assigned a value) and false otherwise */
    public boolean isSetLimit() {
      return EncodingUtils.testBit(__isset_bitfield, __LIMIT_ISSET_ID);
    }

    public void setLimitIsSet(boolean value) {
      __isset_bitfield = EncodingUtils.setBit(__isset_bitfield, __LIMIT_ISSET_ID, value);
    }

    public int getOffset() {
      return this.offset;
    }

    public getUserExperiments_args setOffset(int offset) {
      this.offset = offset;
      setOffsetIsSet(true);
      return this;
    }

    public void unsetOffset() {
      __isset_bitfield = EncodingUtils.clearBit(__isset_bitfield, __OFFSET_ISSET_ID);
    }

    /** Returns true if field offset is set (has been assigned a value) and false otherwise */
    public boolean isSetOffset() {
      return EncodingUtils.testBit(__isset_bitfield, __OFFSET_ISSET_ID);
    }

    public void setOffsetIsSet(boolean value) {
      __isset_bitfield = EncodingUtils.setBit(__isset_bitfield, __OFFSET_ISSET_ID, value);
    }

    public void setFieldValue(_Fields field, 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((String)value);
        }
        break;

      case USER_NAME:
        if (value == null) {
          unsetUserName();
        } else {
          setUserName((String)value);
        }
        break;

      case LIMIT:
        if (value == null) {
          unsetLimit();
        } else {
          setLimit((Integer)value);
        }
        break;

      case OFFSET:
        if (value == null) {
          unsetOffset();
        } else {
          setOffset((Integer)value);
        }
        break;

      }
    }

    public Object getFieldValue(_Fields field) {
      switch (field) {
      case AUTHZ_TOKEN:
        return getAuthzToken();

      case GATEWAY_ID:
        return getGatewayId();

      case USER_NAME:
        return getUserName();

      case LIMIT:
        return Integer.valueOf(getLimit());

      case OFFSET:
        return Integer.valueOf(getOffset());

      }
      throw new IllegalStateException();
    }

    /** Returns true if field corresponding to fieldID is set (has been assigned a value) and false otherwise */
    public boolean isSet(_Fields field) {
      if (field == null) {
        throw new IllegalArgumentException();
      }

      switch (field) {
      case AUTHZ_TOKEN:
        return isSetAuthzToken();
      case GATEWAY_ID:
        return isSetGatewayId();
      case USER_NAME:
        return isSetUserName();
      case LIMIT:
        return isSetLimit();
      case OFFSET:
        return isSetOffset();
      }
      throw new IllegalStateException();
    }

    @Override
    public boolean equals(Object that) {
      if (that == null)
        return false;
      if (that instanceof getUserExperiments_args)
        return this.equals((getUserExperiments_args)that);
      return false;
    }

    public boolean equals(getUserExperiments_args that) {
      if (that == null)
        return false;

      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;
      }

      boolean this_present_userName = true && this.isSetUserName();
      boolean that_present_userName = true && that.isSetUserName();
      if (this_present_userName || that_present_userName) {
        if (!(this_present_userName && that_present_userName))
          return false;
        if (!this.userName.equals(that.userName))
          return false;
      }

      boolean this_present_limit = true;
      boolean that_present_limit = true;
      if (this_present_limit || that_present_limit) {
        if (!(this_present_limit && that_present_limit))
          return false;
        if (this.limit != that.limit)
          return false;
      }

      boolean this_present_offset = true;
      boolean that_present_offset = true;
      if (this_present_offset || that_present_offset) {
        if (!(this_present_offset && that_present_offset))
          return false;
        if (this.offset != that.offset)
          return false;
      }

      return true;
    }

    @Override
    public int hashCode() {
      List<Object> list = new ArrayList<Object>();

      boolean present_authzToken = true && (isSetAuthzToken());
      list.add(present_authzToken);
      if (present_authzToken)
        list.add(authzToken);

      boolean present_gatewayId = true && (isSetGatewayId());
      list.add(present_gatewayId);
      if (present_gatewayId)
        list.add(gatewayId);

      boolean present_userName = true && (isSetUserName());
      list.add(present_userName);
      if (present_userName)
        list.add(userName);

      boolean present_limit = true;
      list.add(present_limit);
      if (present_limit)
        list.add(limit);

      boolean present_offset = true;
      list.add(present_offset);
      if (present_offset)
        list.add(offset);

      return list.hashCode();
    }

    @Override
    public int compareTo(getUserExperiments_args other) {
      if (!getClass().equals(other.getClass())) {
        return getClass().getName().compareTo(other.getClass().getName());
      }

      int lastComparison = 0;

      lastComparison = 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 = 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;
        }
      }
      lastComparison = Boolean.valueOf(isSetUserName()).compareTo(other.isSetUserName());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetUserName()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.userName, other.userName);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = Boolean.valueOf(isSetLimit()).compareTo(other.isSetLimit());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetLimit()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.limit, other.limit);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = Boolean.valueOf(isSetOffset()).compareTo(other.isSetOffset());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetOffset()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.offset, other.offset);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      return 0;
    }

    public _Fields fieldForId(int fieldId) {
      return _Fields.findByThriftId(fieldId);
    }

    public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
      schemes.get(iprot.getScheme()).getScheme().read(iprot, this);
    }

    public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException {
      schemes.get(oprot.getScheme()).getScheme().write(oprot, this);
    }

    @Override
    public String toString() {
      StringBuilder sb = new StringBuilder("getUserExperiments_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;
      if (!first) sb.append(", ");
      sb.append("userName:");
      if (this.userName == null) {
        sb.append("null");
      } else {
        sb.append(this.userName);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("limit:");
      sb.append(this.limit);
      first = false;
      if (!first) sb.append(", ");
      sb.append("offset:");
      sb.append(this.offset);
      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());
      }
      if (userName == null) {
        throw new org.apache.thrift.protocol.TProtocolException("Required field 'userName' was not present! Struct: " + toString());
      }
      // alas, we cannot check 'limit' because it's a primitive and you chose the non-beans generator.
      // alas, we cannot check 'offset' because it's a primitive and you chose the non-beans generator.
      // 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, 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 getUserExperiments_argsStandardSchemeFactory implements SchemeFactory {
      public getUserExperiments_argsStandardScheme getScheme() {
        return new getUserExperiments_argsStandardScheme();
      }
    }

    private static class getUserExperiments_argsStandardScheme extends StandardScheme<getUserExperiments_args> {

      public void read(org.apache.thrift.protocol.TProtocol iprot, getUserExperiments_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;
            case 3: // USER_NAME
              if (schemeField.type == org.apache.thrift.protocol.TType.STRING) {
                struct.userName = iprot.readString();
                struct.setUserNameIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 4: // LIMIT
              if (schemeField.type == org.apache.thrift.protocol.TType.I32) {
                struct.limit = iprot.readI32();
                struct.setLimitIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 5: // OFFSET
              if (schemeField.type == org.apache.thrift.protocol.TType.I32) {
                struct.offset = iprot.readI32();
                struct.setOffsetIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            default:
              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
          }
          iprot.readFieldEnd();
        }
        iprot.readStructEnd();

        // check for required fields of primitive type, which can't be checked in the validate method
        if (!struct.isSetLimit()) {
          throw new org.apache.thrift.protocol.TProtocolException("Required field 'limit' was not found in serialized data! Struct: " + toString());
        }
        if (!struct.isSetOffset()) {
          throw new org.apache.thrift.protocol.TProtocolException("Required field 'offset' was not found in serialized data! Struct: " + toString());
        }
        struct.validate();
      }

      public void write(org.apache.thrift.protocol.TProtocol oprot, getUserExperiments_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();
        }
        if (struct.userName != null) {
          oprot.writeFieldBegin(USER_NAME_FIELD_DESC);
          oprot.writeString(struct.userName);
          oprot.writeFieldEnd();
        }
        oprot.writeFieldBegin(LIMIT_FIELD_DESC);
        oprot.writeI32(struct.limit);
        oprot.writeFieldEnd();
        oprot.writeFieldBegin(OFFSET_FIELD_DESC);
        oprot.writeI32(struct.offset);
        oprot.writeFieldEnd();
        oprot.writeFieldStop();
        oprot.writeStructEnd();
      }

    }

    private static class getUserExperiments_argsTupleSchemeFactory implements SchemeFactory {
      public getUserExperiments_argsTupleScheme getScheme() {
        return new getUserExperiments_argsTupleScheme();
      }
    }

    private static class getUserExperiments_argsTupleScheme extends TupleScheme<getUserExperiments_args> {

      @Override
      public void write(org.apache.thrift.protocol.TProtocol prot, getUserExperiments_args struct) throws org.apache.thrift.TException {
        TTupleProtocol oprot = (TTupleProtocol) prot;
        struct.authzToken.write(oprot);
        oprot.writeString(struct.gatewayId);
        oprot.writeString(struct.userName);
        oprot.writeI32(struct.limit);
        oprot.writeI32(struct.offset);
      }

      @Override
      public void read(org.apache.thrift.protocol.TProtocol prot, getUserExperiments_args struct) throws org.apache.thrift.TException {
        TTupleProtocol iprot = (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);
        struct.userName = iprot.readString();
        struct.setUserNameIsSet(true);
        struct.limit = iprot.readI32();
        struct.setLimitIsSet(true);
        struct.offset = iprot.readI32();
        struct.setOffsetIsSet(true);
      }
    }

  }

  public static class getUserExperiments_result implements org.apache.thrift.TBase<getUserExperiments_result, getUserExperiments_result._Fields>, java.io.Serializable, Cloneable, Comparable<getUserExperiments_result>   {
    private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("getUserExperiments_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 IRE_FIELD_DESC = new org.apache.thrift.protocol.TField("ire", org.apache.thrift.protocol.TType.STRUCT, (short)1);
    private static final org.apache.thrift.protocol.TField ACE_FIELD_DESC = new org.apache.thrift.protocol.TField("ace", org.apache.thrift.protocol.TType.STRUCT, (short)2);
    private static final org.apache.thrift.protocol.TField ASE_FIELD_DESC = new org.apache.thrift.protocol.TField("ase", org.apache.thrift.protocol.TType.STRUCT, (short)3);
    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)4);

    private static final Map<Class<? extends IScheme>, SchemeFactory> schemes = new HashMap<Class<? extends IScheme>, SchemeFactory>();
    static {
      schemes.put(StandardScheme.class, new getUserExperiments_resultStandardSchemeFactory());
      schemes.put(TupleScheme.class, new getUserExperiments_resultTupleSchemeFactory());
    }

    public List<org.apache.airavata.model.experiment.ExperimentModel> success; // required
    public org.apache.airavata.model.error.InvalidRequestException ire; // required
    public org.apache.airavata.model.error.AiravataClientException ace; // required
    public org.apache.airavata.model.error.AiravataSystemException ase; // 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"),
      IRE((short)1, "ire"),
      ACE((short)2, "ace"),
      ASE((short)3, "ase"),
      AE((short)4, "ae");

      private static final Map<String, _Fields> byName = new HashMap<String, _Fields>();

      static {
        for (_Fields field : EnumSet.allOf(_Fields.class)) {
          byName.put(field.getFieldName(), field);
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, or null if its not found.
       */
      public static _Fields findByThriftId(int fieldId) {
        switch(fieldId) {
          case 0: // SUCCESS
            return SUCCESS;
          case 1: // IRE
            return IRE;
          case 2: // ACE
            return ACE;
          case 3: // ASE
            return ASE;
          case 4: // 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 IllegalArgumentException("Field " + fieldId + " doesn't exist!");
        return fields;
      }

      /**
       * Find the _Fields constant that matches name, or null if its not found.
       */
      public static _Fields findByName(String name) {
        return byName.get(name);
      }

      private final short _thriftId;
      private final String _fieldName;

      _Fields(short thriftId, String fieldName) {
        _thriftId = thriftId;
        _fieldName = fieldName;
      }

      public short getThriftFieldId() {
        return _thriftId;
      }

      public String getFieldName() {
        return _fieldName;
      }
    }

    // isset id assignments
    public static final Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
    static {
      Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new EnumMap<_Fields, org.apache.thrift.meta_data.FieldMetaData>(_Fields.class);
      tmpMap.put(_Fields.SUCCESS, new org.apache.thrift.meta_data.FieldMetaData("success", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.ListMetaData(org.apache.thrift.protocol.TType.LIST, 
              new org.apache.thrift.meta_data.StructMetaData(org.apache.thrift.protocol.TType.STRUCT, org.apache.airavata.model.experiment.ExperimentModel.class))));
      tmpMap.put(_Fields.IRE, new org.apache.thrift.meta_data.FieldMetaData("ire", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRUCT)));
      tmpMap.put(_Fields.ACE, new org.apache.thrift.meta_data.FieldMetaData("ace", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRUCT)));
      tmpMap.put(_Fields.ASE, new org.apache.thrift.meta_data.FieldMetaData("ase", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRUCT)));
      tmpMap.put(_Fields.AE, new org.apache.thrift.meta_data.FieldMetaData("ae", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRUCT)));
      metaDataMap = Collections.unmodifiableMap(tmpMap);
      org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(getUserExperiments_result.class, metaDataMap);
    }

    public getUserExperiments_result() {
    }

    public getUserExperiments_result(
      List<org.apache.airavata.model.experiment.ExperimentModel> success,
      org.apache.airavata.model.error.InvalidRequestException ire,
      org.apache.airavata.model.error.AiravataClientException ace,
      org.apache.airavata.model.error.AiravataSystemException ase,
      org.apache.airavata.model.error.AuthorizationException ae)
    {
      this();
      this.success = success;
      this.ire = ire;
      this.ace = ace;
      this.ase = ase;
      this.ae = ae;
    }

    /**
     * Performs a deep copy on <i>other</i>.
     */
    public getUserExperiments_result(getUserExperiments_result other) {
      if (other.isSetSuccess()) {
        List<org.apache.airavata.model.experiment.ExperimentModel> __this__success = new ArrayList<org.apache.airavata.model.experiment.ExperimentModel>(other.success.size());
        for (org.apache.airavata.model.experiment.ExperimentModel other_element : other.success) {
          __this__success.add(new org.apache.airavata.model.experiment.ExperimentModel(other_element));
        }
        this.success = __this__success;
      }
      if (other.isSetIre()) {
        this.ire = new org.apache.airavata.model.error.InvalidRequestException(other.ire);
      }
      if (other.isSetAce()) {
        this.ace = new org.apache.airavata.model.error.AiravataClientException(other.ace);
      }
      if (other.isSetAse()) {
        this.ase = new org.apache.airavata.model.error.AiravataSystemException(other.ase);
      }
      if (other.isSetAe()) {
        this.ae = new org.apache.airavata.model.error.AuthorizationException(other.ae);
      }
    }

    public getUserExperiments_result deepCopy() {
      return new getUserExperiments_result(this);
    }

    @Override
    public void clear() {
      this.success = null;
      this.ire = null;
      this.ace = null;
      this.ase = null;
      this.ae = null;
    }

    public int getSuccessSize() {
      return (this.success == null) ? 0 : this.success.size();
    }

    public java.util.Iterator<org.apache.airavata.model.experiment.ExperimentModel> getSuccessIterator() {
      return (this.success == null) ? null : this.success.iterator();
    }

    public void addToSuccess(org.apache.airavata.model.experiment.ExperimentModel elem) {
      if (this.success == null) {
        this.success = new ArrayList<org.apache.airavata.model.experiment.ExperimentModel>();
      }
      this.success.add(elem);
    }

    public List<org.apache.airavata.model.experiment.ExperimentModel> getSuccess() {
      return this.success;
    }

    public getUserExperiments_result setSuccess(List<org.apache.airavata.model.experiment.ExperimentModel> 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.model.error.InvalidRequestException getIre() {
      return this.ire;
    }

    public getUserExperiments_result setIre(org.apache.airavata.model.error.InvalidRequestException ire) {
      this.ire = ire;
      return this;
    }

    public void unsetIre() {
      this.ire = null;
    }

    /** Returns true if field ire is set (has been assigned a value) and false otherwise */
    public boolean isSetIre() {
      return this.ire != null;
    }

    public void setIreIsSet(boolean value) {
      if (!value) {
        this.ire = null;
      }
    }

    public org.apache.airavata.model.error.AiravataClientException getAce() {
      return this.ace;
    }

    public getUserExperiments_result setAce(org.apache.airavata.model.error.AiravataClientException ace) {
      this.ace = ace;
      return this;
    }

    public void unsetAce() {
      this.ace = null;
    }

    /** Returns true if field ace is set (has been assigned a value) and false otherwise */
    public boolean isSetAce() {
      return this.ace != null;
    }

    public void setAceIsSet(boolean value) {
      if (!value) {
        this.ace = null;
      }
    }

    public org.apache.airavata.model.error.AiravataSystemException getAse() {
      return this.ase;
    }

    public getUserExperiments_result setAse(org.apache.airavata.model.error.AiravataSystemException ase) {
      this.ase = ase;
      return this;
    }

    public void unsetAse() {
      this.ase = null;
    }

    /** Returns true if field ase is set (has been assigned a value) and false otherwise */
    public boolean isSetAse() {
      return this.ase != null;
    }

    public void setAseIsSet(boolean value) {
      if (!value) {
        this.ase = null;
      }
    }

    public org.apache.airavata.model.error.AuthorizationException getAe() {
      return this.ae;
    }

    public getUserExperiments_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, Object value) {
      switch (field) {
      case SUCCESS:
        if (value == null) {
          unsetSuccess();
        } else {
          setSuccess((List<org.apache.airavata.model.experiment.ExperimentModel>)value);
        }
        break;

      case IRE:
        if (value == null) {
          unsetIre();
        } else {
          setIre((org.apache.airavata.model.error.InvalidRequestException)value);
        }
        break;

      case ACE:
        if (value == null) {
          unsetAce();
        } else {
          setAce((org.apache.airavata.model.error.AiravataClientException)value);
        }
        break;

      case ASE:
        if (value == null) {
          unsetAse();
        } else {
          setAse((org.apache.airavata.model.error.AiravataSystemException)value);
        }
        break;

      case AE:
        if (value == null) {
          unsetAe();
        } else {
          setAe((org.apache.airavata.model.error.AuthorizationException)value);
        }
        break;

      }
    }

    public Object getFieldValue(_Fields field) {
      switch (field) {
      case SUCCESS:
        return getSuccess();

      case IRE:
        return getIre();

      case ACE:
        return getAce();

      case ASE:
        return getAse();

      case AE:
        return getAe();

      }
      throw new IllegalStateException();
    }

    /** Returns true if field corresponding to fieldID is set (has been assigned a value) and false otherwise */
    public boolean isSet(_Fields field) {
      if (field == null) {
        throw new IllegalArgumentException();
      }

      switch (field) {
      case SUCCESS:
        return isSetSuccess();
      case IRE:
        return isSetIre();
      case ACE:
        return isSetAce();
      case ASE:
        return isSetAse();
      case AE:
        return isSetAe();
      }
      throw new IllegalStateException();
    }

    @Override
    public boolean equals(Object that) {
      if (that == null)
        return false;
      if (that instanceof getUserExperiments_result)
        return this.equals((getUserExperiments_result)that);
      return false;
    }

    public boolean equals(getUserExperiments_result that) {
      if (that == null)
        return false;

      boolean this_present_success = true && this.isSetSuccess();
      boolean that_present_success = true && that.isSetSuccess();
      if (this_present_success || that_present_success) {
        if (!(this_present_success && that_present_success))
          return false;
        if (!this.success.equals(that.success))
          return false;
      }

      boolean this_present_ire = true && this.isSetIre();
      boolean that_present_ire = true && that.isSetIre();
      if (this_present_ire || that_present_ire) {
        if (!(this_present_ire && that_present_ire))
          return false;
        if (!this.ire.equals(that.ire))
          return false;
      }

      boolean this_present_ace = true && this.isSetAce();
      boolean that_present_ace = true && that.isSetAce();
      if (this_present_ace || that_present_ace) {
        if (!(this_present_ace && that_present_ace))
          return false;
        if (!this.ace.equals(that.ace))
          return false;
      }

      boolean this_present_ase = true && this.isSetAse();
      boolean that_present_ase = true && that.isSetAse();
      if (this_present_ase || that_present_ase) {
        if (!(this_present_ase && that_present_ase))
          return false;
        if (!this.ase.equals(that.ase))
          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() {
      List<Object> list = new ArrayList<Object>();

      boolean present_success = true && (isSetSuccess());
      list.add(present_success);
      if (present_success)
        list.add(success);

      boolean present_ire = true && (isSetIre());
      list.add(present_ire);
      if (present_ire)
        list.add(ire);

      boolean present_ace = true && (isSetAce());
      list.add(present_ace);
      if (present_ace)
        list.add(ace);

      boolean present_ase = true && (isSetAse());
      list.add(present_ase);
      if (present_ase)
        list.add(ase);

      boolean present_ae = true && (isSetAe());
      list.add(present_ae);
      if (present_ae)
        list.add(ae);

      return list.hashCode();
    }

    @Override
    public int compareTo(getUserExperiments_result other) {
      if (!getClass().equals(other.getClass())) {
        return getClass().getName().compareTo(other.getClass().getName());
      }

      int lastComparison = 0;

      lastComparison = Boolean.valueOf(isSetSuccess()).compareTo(other.isSetSuccess());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetSuccess()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.success, other.success);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = Boolean.valueOf(isSetIre()).compareTo(other.isSetIre());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetIre()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.ire, other.ire);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = Boolean.valueOf(isSetAce()).compareTo(other.isSetAce());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetAce()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.ace, other.ace);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = Boolean.valueOf(isSetAse()).compareTo(other.isSetAse());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetAse()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.ase, other.ase);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = 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 {
      schemes.get(iprot.getScheme()).getScheme().read(iprot, this);
    }

    public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException {
      schemes.get(oprot.getScheme()).getScheme().write(oprot, this);
      }

    @Override
    public String toString() {
      StringBuilder sb = new StringBuilder("getUserExperiments_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("ire:");
      if (this.ire == null) {
        sb.append("null");
      } else {
        sb.append(this.ire);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("ace:");
      if (this.ace == null) {
        sb.append("null");
      } else {
        sb.append(this.ace);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("ase:");
      if (this.ase == null) {
        sb.append("null");
      } else {
        sb.append(this.ase);
      }
      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, 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 getUserExperiments_resultStandardSchemeFactory implements SchemeFactory {
      public getUserExperiments_resultStandardScheme getScheme() {
        return new getUserExperiments_resultStandardScheme();
      }
    }

    private static class getUserExperiments_resultStandardScheme extends StandardScheme<getUserExperiments_result> {

      public void read(org.apache.thrift.protocol.TProtocol iprot, getUserExperiments_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 _list108 = iprot.readListBegin();
                  struct.success = new ArrayList<org.apache.airavata.model.experiment.ExperimentModel>(_list108.size);
                  org.apache.airavata.model.experiment.ExperimentModel _elem109;
                  for (int _i110 = 0; _i110 < _list108.size; ++_i110)
                  {
                    _elem109 = new org.apache.airavata.model.experiment.ExperimentModel();
                    _elem109.read(iprot);
                    struct.success.add(_elem109);
                  }
                  iprot.readListEnd();
                }
                struct.setSuccessIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 1: // IRE
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.ire = new org.apache.airavata.model.error.InvalidRequestException();
                struct.ire.read(iprot);
                struct.setIreIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 2: // ACE
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.ace = new org.apache.airavata.model.error.AiravataClientException();
                struct.ace.read(iprot);
                struct.setAceIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 3: // ASE
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.ase = new org.apache.airavata.model.error.AiravataSystemException();
                struct.ase.read(iprot);
                struct.setAseIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 4: // 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, getUserExperiments_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.experiment.ExperimentModel _iter111 : struct.success)
            {
              _iter111.write(oprot);
            }
            oprot.writeListEnd();
          }
          oprot.writeFieldEnd();
        }
        if (struct.ire != null) {
          oprot.writeFieldBegin(IRE_FIELD_DESC);
          struct.ire.write(oprot);
          oprot.writeFieldEnd();
        }
        if (struct.ace != null) {
          oprot.writeFieldBegin(ACE_FIELD_DESC);
          struct.ace.write(oprot);
          oprot.writeFieldEnd();
        }
        if (struct.ase != null) {
          oprot.writeFieldBegin(ASE_FIELD_DESC);
          struct.ase.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 getUserExperiments_resultTupleSchemeFactory implements SchemeFactory {
      public getUserExperiments_resultTupleScheme getScheme() {
        return new getUserExperiments_resultTupleScheme();
      }
    }

    private static class getUserExperiments_resultTupleScheme extends TupleScheme<getUserExperiments_result> {

      @Override
      public void write(org.apache.thrift.protocol.TProtocol prot, getUserExperiments_result struct) throws org.apache.thrift.TException {
        TTupleProtocol oprot = (TTupleProtocol) prot;
        BitSet optionals = new BitSet();
        if (struct.isSetSuccess()) {
          optionals.set(0);
        }
        if (struct.isSetIre()) {
          optionals.set(1);
        }
        if (struct.isSetAce()) {
          optionals.set(2);
        }
        if (struct.isSetAse()) {
          optionals.set(3);
        }
        if (struct.isSetAe()) {
          optionals.set(4);
        }
        oprot.writeBitSet(optionals, 5);
        if (struct.isSetSuccess()) {
          {
            oprot.writeI32(struct.success.size());
            for (org.apache.airavata.model.experiment.ExperimentModel _iter112 : struct.success)
            {
              _iter112.write(oprot);
            }
          }
        }
        if (struct.isSetIre()) {
          struct.ire.write(oprot);
        }
        if (struct.isSetAce()) {
          struct.ace.write(oprot);
        }
        if (struct.isSetAse()) {
          struct.ase.write(oprot);
        }
        if (struct.isSetAe()) {
          struct.ae.write(oprot);
        }
      }

      @Override
      public void read(org.apache.thrift.protocol.TProtocol prot, getUserExperiments_result struct) throws org.apache.thrift.TException {
        TTupleProtocol iprot = (TTupleProtocol) prot;
        BitSet incoming = iprot.readBitSet(5);
        if (incoming.get(0)) {
          {
            org.apache.thrift.protocol.TList _list113 = new org.apache.thrift.protocol.TList(org.apache.thrift.protocol.TType.STRUCT, iprot.readI32());
            struct.success = new ArrayList<org.apache.airavata.model.experiment.ExperimentModel>(_list113.size);
            org.apache.airavata.model.experiment.ExperimentModel _elem114;
            for (int _i115 = 0; _i115 < _list113.size; ++_i115)
            {
              _elem114 = new org.apache.airavata.model.experiment.ExperimentModel();
              _elem114.read(iprot);
              struct.success.add(_elem114);
            }
          }
          struct.setSuccessIsSet(true);
        }
        if (incoming.get(1)) {
          struct.ire = new org.apache.airavata.model.error.InvalidRequestException();
          struct.ire.read(iprot);
          struct.setIreIsSet(true);
        }
        if (incoming.get(2)) {
          struct.ace = new org.apache.airavata.model.error.AiravataClientException();
          struct.ace.read(iprot);
          struct.setAceIsSet(true);
        }
        if (incoming.get(3)) {
          struct.ase = new org.apache.airavata.model.error.AiravataSystemException();
          struct.ase.read(iprot);
          struct.setAseIsSet(true);
        }
        if (incoming.get(4)) {
          struct.ae = new org.apache.airavata.model.error.AuthorizationException();
          struct.ae.read(iprot);
          struct.setAeIsSet(true);
        }
      }
    }

  }

  public static class createExperiment_args implements org.apache.thrift.TBase<createExperiment_args, createExperiment_args._Fields>, java.io.Serializable, Cloneable, Comparable<createExperiment_args>   {
    private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("createExperiment_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.protocol.TField EXPERIMENT_FIELD_DESC = new org.apache.thrift.protocol.TField("experiment", org.apache.thrift.protocol.TType.STRUCT, (short)3);

    private static final Map<Class<? extends IScheme>, SchemeFactory> schemes = new HashMap<Class<? extends IScheme>, SchemeFactory>();
    static {
      schemes.put(StandardScheme.class, new createExperiment_argsStandardSchemeFactory());
      schemes.put(TupleScheme.class, new createExperiment_argsTupleSchemeFactory());
    }

    public org.apache.airavata.model.security.AuthzToken authzToken; // required
    public String gatewayId; // required
    public org.apache.airavata.model.experiment.ExperimentModel experiment; // required

    /** 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"),
      EXPERIMENT((short)3, "experiment");

      private static final Map<String, _Fields> byName = new HashMap<String, _Fields>();

      static {
        for (_Fields field : EnumSet.allOf(_Fields.class)) {
          byName.put(field.getFieldName(), field);
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, or null if its not found.
       */
      public static _Fields findByThriftId(int fieldId) {
        switch(fieldId) {
          case 1: // AUTHZ_TOKEN
            return AUTHZ_TOKEN;
          case 2: // GATEWAY_ID
            return GATEWAY_ID;
          case 3: // EXPERIMENT
            return EXPERIMENT;
          default:
            return null;
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, throwing an exception
       * if it is not found.
       */
      public static _Fields findByThriftIdOrThrow(int fieldId) {
        _Fields fields = findByThriftId(fieldId);
        if (fields == null) throw new IllegalArgumentException("Field " + fieldId + " doesn't exist!");
        return fields;
      }

      /**
       * Find the _Fields constant that matches name, or null if its not found.
       */
      public static _Fields findByName(String name) {
        return byName.get(name);
      }

      private final short _thriftId;
      private final String _fieldName;

      _Fields(short thriftId, String fieldName) {
        _thriftId = thriftId;
        _fieldName = fieldName;
      }

      public short getThriftFieldId() {
        return _thriftId;
      }

      public String getFieldName() {
        return _fieldName;
      }
    }

    // isset id assignments
    public static final Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
    static {
      Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new EnumMap<_Fields, org.apache.thrift.meta_data.FieldMetaData>(_Fields.class);
      tmpMap.put(_Fields.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)));
      tmpMap.put(_Fields.EXPERIMENT, new org.apache.thrift.meta_data.FieldMetaData("experiment", org.apache.thrift.TFieldRequirementType.REQUIRED, 
          new org.apache.thrift.meta_data.StructMetaData(org.apache.thrift.protocol.TType.STRUCT, org.apache.airavata.model.experiment.ExperimentModel.class)));
      metaDataMap = Collections.unmodifiableMap(tmpMap);
      org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(createExperiment_args.class, metaDataMap);
    }

    public createExperiment_args() {
    }

    public createExperiment_args(
      org.apache.airavata.model.security.AuthzToken authzToken,
      String gatewayId,
      org.apache.airavata.model.experiment.ExperimentModel experiment)
    {
      this();
      this.authzToken = authzToken;
      this.gatewayId = gatewayId;
      this.experiment = experiment;
    }

    /**
     * Performs a deep copy on <i>other</i>.
     */
    public createExperiment_args(createExperiment_args other) {
      if (other.isSetAuthzToken()) {
        this.authzToken = new org.apache.airavata.model.security.AuthzToken(other.authzToken);
      }
      if (other.isSetGatewayId()) {
        this.gatewayId = other.gatewayId;
      }
      if (other.isSetExperiment()) {
        this.experiment = new org.apache.airavata.model.experiment.ExperimentModel(other.experiment);
      }
    }

    public createExperiment_args deepCopy() {
      return new createExperiment_args(this);
    }

    @Override
    public void clear() {
      this.authzToken = null;
      this.gatewayId = null;
      this.experiment = null;
    }

    public org.apache.airavata.model.security.AuthzToken getAuthzToken() {
      return this.authzToken;
    }

    public createExperiment_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 String getGatewayId() {
      return this.gatewayId;
    }

    public createExperiment_args setGatewayId(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 org.apache.airavata.model.experiment.ExperimentModel getExperiment() {
      return this.experiment;
    }

    public createExperiment_args setExperiment(org.apache.airavata.model.experiment.ExperimentModel experiment) {
      this.experiment = experiment;
      return this;
    }

    public void unsetExperiment() {
      this.experiment = null;
    }

    /** Returns true if field experiment is set (has been assigned a value) and false otherwise */
    public boolean isSetExperiment() {
      return this.experiment != null;
    }

    public void setExperimentIsSet(boolean value) {
      if (!value) {
        this.experiment = null;
      }
    }

    public void setFieldValue(_Fields field, 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((String)value);
        }
        break;

      case EXPERIMENT:
        if (value == null) {
          unsetExperiment();
        } else {
          setExperiment((org.apache.airavata.model.experiment.ExperimentModel)value);
        }
        break;

      }
    }

    public Object getFieldValue(_Fields field) {
      switch (field) {
      case AUTHZ_TOKEN:
        return getAuthzToken();

      case GATEWAY_ID:
        return getGatewayId();

      case EXPERIMENT:
        return getExperiment();

      }
      throw new IllegalStateException();
    }

    /** Returns true if field corresponding to fieldID is set (has been assigned a value) and false otherwise */
    public boolean isSet(_Fields field) {
      if (field == null) {
        throw new IllegalArgumentException();
      }

      switch (field) {
      case AUTHZ_TOKEN:
        return isSetAuthzToken();
      case GATEWAY_ID:
        return isSetGatewayId();
      case EXPERIMENT:
        return isSetExperiment();
      }
      throw new IllegalStateException();
    }

    @Override
    public boolean equals(Object that) {
      if (that == null)
        return false;
      if (that instanceof createExperiment_args)
        return this.equals((createExperiment_args)that);
      return false;
    }

    public boolean equals(createExperiment_args that) {
      if (that == null)
        return false;

      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;
      }

      boolean this_present_experiment = true && this.isSetExperiment();
      boolean that_present_experiment = true && that.isSetExperiment();
      if (this_present_experiment || that_present_experiment) {
        if (!(this_present_experiment && that_present_experiment))
          return false;
        if (!this.experiment.equals(that.experiment))
          return false;
      }

      return true;
    }

    @Override
    public int hashCode() {
      List<Object> list = new ArrayList<Object>();

      boolean present_authzToken = true && (isSetAuthzToken());
      list.add(present_authzToken);
      if (present_authzToken)
        list.add(authzToken);

      boolean present_gatewayId = true && (isSetGatewayId());
      list.add(present_gatewayId);
      if (present_gatewayId)
        list.add(gatewayId);

      boolean present_experiment = true && (isSetExperiment());
      list.add(present_experiment);
      if (present_experiment)
        list.add(experiment);

      return list.hashCode();
    }

    @Override
    public int compareTo(createExperiment_args other) {
      if (!getClass().equals(other.getClass())) {
        return getClass().getName().compareTo(other.getClass().getName());
      }

      int lastComparison = 0;

      lastComparison = 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 = 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;
        }
      }
      lastComparison = Boolean.valueOf(isSetExperiment()).compareTo(other.isSetExperiment());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetExperiment()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.experiment, other.experiment);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      return 0;
    }

    public _Fields fieldForId(int fieldId) {
      return _Fields.findByThriftId(fieldId);
    }

    public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
      schemes.get(iprot.getScheme()).getScheme().read(iprot, this);
    }

    public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException {
      schemes.get(oprot.getScheme()).getScheme().write(oprot, this);
    }

    @Override
    public String toString() {
      StringBuilder sb = new StringBuilder("createExperiment_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;
      if (!first) sb.append(", ");
      sb.append("experiment:");
      if (this.experiment == null) {
        sb.append("null");
      } else {
        sb.append(this.experiment);
      }
      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());
      }
      if (experiment == null) {
        throw new org.apache.thrift.protocol.TProtocolException("Required field 'experiment' was not present! Struct: " + toString());
      }
      // check for sub-struct validity
      if (authzToken != null) {
        authzToken.validate();
      }
      if (experiment != null) {
        experiment.validate();
      }
    }

    private void writeObject(java.io.ObjectOutputStream out) throws java.io.IOException {
      try {
        write(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(out)));
      } catch (org.apache.thrift.TException te) {
        throw new java.io.IOException(te);
      }
    }

    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, ClassNotFoundException {
      try {
        read(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(in)));
      } catch (org.apache.thrift.TException te) {
        throw new java.io.IOException(te);
      }
    }

    private static class createExperiment_argsStandardSchemeFactory implements SchemeFactory {
      public createExperiment_argsStandardScheme getScheme() {
        return new createExperiment_argsStandardScheme();
      }
    }

    private static class createExperiment_argsStandardScheme extends StandardScheme<createExperiment_args> {

      public void read(org.apache.thrift.protocol.TProtocol iprot, createExperiment_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;
            case 3: // EXPERIMENT
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.experiment = new org.apache.airavata.model.experiment.ExperimentModel();
                struct.experiment.read(iprot);
                struct.setExperimentIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            default:
              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
          }
          iprot.readFieldEnd();
        }
        iprot.readStructEnd();

        // check for required fields of primitive type, which can't be checked in the validate method
        struct.validate();
      }

      public void write(org.apache.thrift.protocol.TProtocol oprot, createExperiment_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();
        }
        if (struct.experiment != null) {
          oprot.writeFieldBegin(EXPERIMENT_FIELD_DESC);
          struct.experiment.write(oprot);
          oprot.writeFieldEnd();
        }
        oprot.writeFieldStop();
        oprot.writeStructEnd();
      }

    }

    private static class createExperiment_argsTupleSchemeFactory implements SchemeFactory {
      public createExperiment_argsTupleScheme getScheme() {
        return new createExperiment_argsTupleScheme();
      }
    }

    private static class createExperiment_argsTupleScheme extends TupleScheme<createExperiment_args> {

      @Override
      public void write(org.apache.thrift.protocol.TProtocol prot, createExperiment_args struct) throws org.apache.thrift.TException {
        TTupleProtocol oprot = (TTupleProtocol) prot;
        struct.authzToken.write(oprot);
        oprot.writeString(struct.gatewayId);
        struct.experiment.write(oprot);
      }

      @Override
      public void read(org.apache.thrift.protocol.TProtocol prot, createExperiment_args struct) throws org.apache.thrift.TException {
        TTupleProtocol iprot = (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);
        struct.experiment = new org.apache.airavata.model.experiment.ExperimentModel();
        struct.experiment.read(iprot);
        struct.setExperimentIsSet(true);
      }
    }

  }

  public static class createExperiment_result implements org.apache.thrift.TBase<createExperiment_result, createExperiment_result._Fields>, java.io.Serializable, Cloneable, Comparable<createExperiment_result>   {
    private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("createExperiment_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 IRE_FIELD_DESC = new org.apache.thrift.protocol.TField("ire", org.apache.thrift.protocol.TType.STRUCT, (short)1);
    private static final org.apache.thrift.protocol.TField ACE_FIELD_DESC = new org.apache.thrift.protocol.TField("ace", org.apache.thrift.protocol.TType.STRUCT, (short)2);
    private static final org.apache.thrift.protocol.TField ASE_FIELD_DESC = new org.apache.thrift.protocol.TField("ase", org.apache.thrift.protocol.TType.STRUCT, (short)3);
    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)4);

    private static final Map<Class<? extends IScheme>, SchemeFactory> schemes = new HashMap<Class<? extends IScheme>, SchemeFactory>();
    static {
      schemes.put(StandardScheme.class, new createExperiment_resultStandardSchemeFactory());
      schemes.put(TupleScheme.class, new createExperiment_resultTupleSchemeFactory());
    }

    public String success; // required
    public org.apache.airavata.model.error.InvalidRequestException ire; // required
    public org.apache.airavata.model.error.AiravataClientException ace; // required
    public org.apache.airavata.model.error.AiravataSystemException ase; // 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"),
      IRE((short)1, "ire"),
      ACE((short)2, "ace"),
      ASE((short)3, "ase"),
      AE((short)4, "ae");

      private static final Map<String, _Fields> byName = new HashMap<String, _Fields>();

      static {
        for (_Fields field : EnumSet.allOf(_Fields.class)) {
          byName.put(field.getFieldName(), field);
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, or null if its not found.
       */
      public static _Fields findByThriftId(int fieldId) {
        switch(fieldId) {
          case 0: // SUCCESS
            return SUCCESS;
          case 1: // IRE
            return IRE;
          case 2: // ACE
            return ACE;
          case 3: // ASE
            return ASE;
          case 4: // 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 IllegalArgumentException("Field " + fieldId + " doesn't exist!");
        return fields;
      }

      /**
       * Find the _Fields constant that matches name, or null if its not found.
       */
      public static _Fields findByName(String name) {
        return byName.get(name);
      }

      private final short _thriftId;
      private final String _fieldName;

      _Fields(short thriftId, String fieldName) {
        _thriftId = thriftId;
        _fieldName = fieldName;
      }

      public short getThriftFieldId() {
        return _thriftId;
      }

      public String getFieldName() {
        return _fieldName;
      }
    }

    // isset id assignments
    public static final Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
    static {
      Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new EnumMap<_Fields, org.apache.thrift.meta_data.FieldMetaData>(_Fields.class);
      tmpMap.put(_Fields.SUCCESS, new org.apache.thrift.meta_data.FieldMetaData("success", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING)));
      tmpMap.put(_Fields.IRE, new org.apache.thrift.meta_data.FieldMetaData("ire", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRUCT)));
      tmpMap.put(_Fields.ACE, new org.apache.thrift.meta_data.FieldMetaData("ace", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRUCT)));
      tmpMap.put(_Fields.ASE, new org.apache.thrift.meta_data.FieldMetaData("ase", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRUCT)));
      tmpMap.put(_Fields.AE, new org.apache.thrift.meta_data.FieldMetaData("ae", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRUCT)));
      metaDataMap = Collections.unmodifiableMap(tmpMap);
      org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(createExperiment_result.class, metaDataMap);
    }

    public createExperiment_result() {
    }

    public createExperiment_result(
      String success,
      org.apache.airavata.model.error.InvalidRequestException ire,
      org.apache.airavata.model.error.AiravataClientException ace,
      org.apache.airavata.model.error.AiravataSystemException ase,
      org.apache.airavata.model.error.AuthorizationException ae)
    {
      this();
      this.success = success;
      this.ire = ire;
      this.ace = ace;
      this.ase = ase;
      this.ae = ae;
    }

    /**
     * Performs a deep copy on <i>other</i>.
     */
    public createExperiment_result(createExperiment_result other) {
      if (other.isSetSuccess()) {
        this.success = other.success;
      }
      if (other.isSetIre()) {
        this.ire = new org.apache.airavata.model.error.InvalidRequestException(other.ire);
      }
      if (other.isSetAce()) {
        this.ace = new org.apache.airavata.model.error.AiravataClientException(other.ace);
      }
      if (other.isSetAse()) {
        this.ase = new org.apache.airavata.model.error.AiravataSystemException(other.ase);
      }
      if (other.isSetAe()) {
        this.ae = new org.apache.airavata.model.error.AuthorizationException(other.ae);
      }
    }

    public createExperiment_result deepCopy() {
      return new createExperiment_result(this);
    }

    @Override
    public void clear() {
      this.success = null;
      this.ire = null;
      this.ace = null;
      this.ase = null;
      this.ae = null;
    }

    public String getSuccess() {
      return this.success;
    }

    public createExperiment_result setSuccess(String success) {
      this.success = success;
      return this;
    }

    public void unsetSuccess() {
      this.success = null;
    }

    /** Returns true if field success is set (has been assigned a value) and false otherwise */
    public boolean isSetSuccess() {
      return this.success != null;
    }

    public void setSuccessIsSet(boolean value) {
      if (!value) {
        this.success = null;
      }
    }

    public org.apache.airavata.model.error.InvalidRequestException getIre() {
      return this.ire;
    }

    public createExperiment_result setIre(org.apache.airavata.model.error.InvalidRequestException ire) {
      this.ire = ire;
      return this;
    }

    public void unsetIre() {
      this.ire = null;
    }

    /** Returns true if field ire is set (has been assigned a value) and false otherwise */
    public boolean isSetIre() {
      return this.ire != null;
    }

    public void setIreIsSet(boolean value) {
      if (!value) {
        this.ire = null;
      }
    }

    public org.apache.airavata.model.error.AiravataClientException getAce() {
      return this.ace;
    }

    public createExperiment_result setAce(org.apache.airavata.model.error.AiravataClientException ace) {
      this.ace = ace;
      return this;
    }

    public void unsetAce() {
      this.ace = null;
    }

    /** Returns true if field ace is set (has been assigned a value) and false otherwise */
    public boolean isSetAce() {
      return this.ace != null;
    }

    public void setAceIsSet(boolean value) {
      if (!value) {
        this.ace = null;
      }
    }

    public org.apache.airavata.model.error.AiravataSystemException getAse() {
      return this.ase;
    }

    public createExperiment_result setAse(org.apache.airavata.model.error.AiravataSystemException ase) {
      this.ase = ase;
      return this;
    }

    public void unsetAse() {
      this.ase = null;
    }

    /** Returns true if field ase is set (has been assigned a value) and false otherwise */
    public boolean isSetAse() {
      return this.ase != null;
    }

    public void setAseIsSet(boolean value) {
      if (!value) {
        this.ase = null;
      }
    }

    public org.apache.airavata.model.error.AuthorizationException getAe() {
      return this.ae;
    }

    public createExperiment_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, Object value) {
      switch (field) {
      case SUCCESS:
        if (value == null) {
          unsetSuccess();
        } else {
          setSuccess((String)value);
        }
        break;

      case IRE:
        if (value == null) {
          unsetIre();
        } else {
          setIre((org.apache.airavata.model.error.InvalidRequestException)value);
        }
        break;

      case ACE:
        if (value == null) {
          unsetAce();
        } else {
          setAce((org.apache.airavata.model.error.AiravataClientException)value);
        }
        break;

      case ASE:
        if (value == null) {
          unsetAse();
        } else {
          setAse((org.apache.airavata.model.error.AiravataSystemException)value);
        }
        break;

      case AE:
        if (value == null) {
          unsetAe();
        } else {
          setAe((org.apache.airavata.model.error.AuthorizationException)value);
        }
        break;

      }
    }

    public Object getFieldValue(_Fields field) {
      switch (field) {
      case SUCCESS:
        return getSuccess();

      case IRE:
        return getIre();

      case ACE:
        return getAce();

      case ASE:
        return getAse();

      case AE:
        return getAe();

      }
      throw new IllegalStateException();
    }

    /** Returns true if field corresponding to fieldID is set (has been assigned a value) and false otherwise */
    public boolean isSet(_Fields field) {
      if (field == null) {
        throw new IllegalArgumentException();
      }

      switch (field) {
      case SUCCESS:
        return isSetSuccess();
      case IRE:
        return isSetIre();
      case ACE:
        return isSetAce();
      case ASE:
        return isSetAse();
      case AE:
        return isSetAe();
      }
      throw new IllegalStateException();
    }

    @Override
    public boolean equals(Object that) {
      if (that == null)
        return false;
      if (that instanceof createExperiment_result)
        return this.equals((createExperiment_result)that);
      return false;
    }

    public boolean equals(createExperiment_result that) {
      if (that == null)
        return false;

      boolean this_present_success = true && this.isSetSuccess();
      boolean that_present_success = true && that.isSetSuccess();
      if (this_present_success || that_present_success) {
        if (!(this_present_success && that_present_success))
          return false;
        if (!this.success.equals(that.success))
          return false;
      }

      boolean this_present_ire = true && this.isSetIre();
      boolean that_present_ire = true && that.isSetIre();
      if (this_present_ire || that_present_ire) {
        if (!(this_present_ire && that_present_ire))
          return false;
        if (!this.ire.equals(that.ire))
          return false;
      }

      boolean this_present_ace = true && this.isSetAce();
      boolean that_present_ace = true && that.isSetAce();
      if (this_present_ace || that_present_ace) {
        if (!(this_present_ace && that_present_ace))
          return false;
        if (!this.ace.equals(that.ace))
          return false;
      }

      boolean this_present_ase = true && this.isSetAse();
      boolean that_present_ase = true && that.isSetAse();
      if (this_present_ase || that_present_ase) {
        if (!(this_present_ase && that_present_ase))
          return false;
        if (!this.ase.equals(that.ase))
          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() {
      List<Object> list = new ArrayList<Object>();

      boolean present_success = true && (isSetSuccess());
      list.add(present_success);
      if (present_success)
        list.add(success);

      boolean present_ire = true && (isSetIre());
      list.add(present_ire);
      if (present_ire)
        list.add(ire);

      boolean present_ace = true && (isSetAce());
      list.add(present_ace);
      if (present_ace)
        list.add(ace);

      boolean present_ase = true && (isSetAse());
      list.add(present_ase);
      if (present_ase)
        list.add(ase);

      boolean present_ae = true && (isSetAe());
      list.add(present_ae);
      if (present_ae)
        list.add(ae);

      return list.hashCode();
    }

    @Override
    public int compareTo(createExperiment_result other) {
      if (!getClass().equals(other.getClass())) {
        return getClass().getName().compareTo(other.getClass().getName());
      }

      int lastComparison = 0;

      lastComparison = Boolean.valueOf(isSetSuccess()).compareTo(other.isSetSuccess());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetSuccess()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.success, other.success);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = Boolean.valueOf(isSetIre()).compareTo(other.isSetIre());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetIre()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.ire, other.ire);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = Boolean.valueOf(isSetAce()).compareTo(other.isSetAce());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetAce()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.ace, other.ace);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = Boolean.valueOf(isSetAse()).compareTo(other.isSetAse());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetAse()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.ase, other.ase);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = 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 {
      schemes.get(iprot.getScheme()).getScheme().read(iprot, this);
    }

    public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException {
      schemes.get(oprot.getScheme()).getScheme().write(oprot, this);
      }

    @Override
    public String toString() {
      StringBuilder sb = new StringBuilder("createExperiment_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("ire:");
      if (this.ire == null) {
        sb.append("null");
      } else {
        sb.append(this.ire);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("ace:");
      if (this.ace == null) {
        sb.append("null");
      } else {
        sb.append(this.ace);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("ase:");
      if (this.ase == null) {
        sb.append("null");
      } else {
        sb.append(this.ase);
      }
      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, 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 createExperiment_resultStandardSchemeFactory implements SchemeFactory {
      public createExperiment_resultStandardScheme getScheme() {
        return new createExperiment_resultStandardScheme();
      }
    }

    private static class createExperiment_resultStandardScheme extends StandardScheme<createExperiment_result> {

      public void read(org.apache.thrift.protocol.TProtocol iprot, createExperiment_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: // IRE
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.ire = new org.apache.airavata.model.error.InvalidRequestException();
                struct.ire.read(iprot);
                struct.setIreIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 2: // ACE
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.ace = new org.apache.airavata.model.error.AiravataClientException();
                struct.ace.read(iprot);
                struct.setAceIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 3: // ASE
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.ase = new org.apache.airavata.model.error.AiravataSystemException();
                struct.ase.read(iprot);
                struct.setAseIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 4: // 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, createExperiment_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.ire != null) {
          oprot.writeFieldBegin(IRE_FIELD_DESC);
          struct.ire.write(oprot);
          oprot.writeFieldEnd();
        }
        if (struct.ace != null) {
          oprot.writeFieldBegin(ACE_FIELD_DESC);
          struct.ace.write(oprot);
          oprot.writeFieldEnd();
        }
        if (struct.ase != null) {
          oprot.writeFieldBegin(ASE_FIELD_DESC);
          struct.ase.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 createExperiment_resultTupleSchemeFactory implements SchemeFactory {
      public createExperiment_resultTupleScheme getScheme() {
        return new createExperiment_resultTupleScheme();
      }
    }

    private static class createExperiment_resultTupleScheme extends TupleScheme<createExperiment_result> {

      @Override
      public void write(org.apache.thrift.protocol.TProtocol prot, createExperiment_result struct) throws org.apache.thrift.TException {
        TTupleProtocol oprot = (TTupleProtocol) prot;
        BitSet optionals = new BitSet();
        if (struct.isSetSuccess()) {
          optionals.set(0);
        }
        if (struct.isSetIre()) {
          optionals.set(1);
        }
        if (struct.isSetAce()) {
          optionals.set(2);
        }
        if (struct.isSetAse()) {
          optionals.set(3);
        }
        if (struct.isSetAe()) {
          optionals.set(4);
        }
        oprot.writeBitSet(optionals, 5);
        if (struct.isSetSuccess()) {
          oprot.writeString(struct.success);
        }
        if (struct.isSetIre()) {
          struct.ire.write(oprot);
        }
        if (struct.isSetAce()) {
          struct.ace.write(oprot);
        }
        if (struct.isSetAse()) {
          struct.ase.write(oprot);
        }
        if (struct.isSetAe()) {
          struct.ae.write(oprot);
        }
      }

      @Override
      public void read(org.apache.thrift.protocol.TProtocol prot, createExperiment_result struct) throws org.apache.thrift.TException {
        TTupleProtocol iprot = (TTupleProtocol) prot;
        BitSet incoming = iprot.readBitSet(5);
        if (incoming.get(0)) {
          struct.success = iprot.readString();
          struct.setSuccessIsSet(true);
        }
        if (incoming.get(1)) {
          struct.ire = new org.apache.airavata.model.error.InvalidRequestException();
          struct.ire.read(iprot);
          struct.setIreIsSet(true);
        }
        if (incoming.get(2)) {
          struct.ace = new org.apache.airavata.model.error.AiravataClientException();
          struct.ace.read(iprot);
          struct.setAceIsSet(true);
        }
        if (incoming.get(3)) {
          struct.ase = new org.apache.airavata.model.error.AiravataSystemException();
          struct.ase.read(iprot);
          struct.setAseIsSet(true);
        }
        if (incoming.get(4)) {
          struct.ae = new org.apache.airavata.model.error.AuthorizationException();
          struct.ae.read(iprot);
          struct.setAeIsSet(true);
        }
      }
    }

  }

  public static class deleteExperiment_args implements org.apache.thrift.TBase<deleteExperiment_args, deleteExperiment_args._Fields>, java.io.Serializable, Cloneable, Comparable<deleteExperiment_args>   {
    private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("deleteExperiment_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 EXPERIMENT_ID_FIELD_DESC = new org.apache.thrift.protocol.TField("experimentId", org.apache.thrift.protocol.TType.STRING, (short)2);

    private static final Map<Class<? extends IScheme>, SchemeFactory> schemes = new HashMap<Class<? extends IScheme>, SchemeFactory>();
    static {
      schemes.put(StandardScheme.class, new deleteExperiment_argsStandardSchemeFactory());
      schemes.put(TupleScheme.class, new deleteExperiment_argsTupleSchemeFactory());
    }

    public org.apache.airavata.model.security.AuthzToken authzToken; // required
    public String experimentId; // required

    /** 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"),
      EXPERIMENT_ID((short)2, "experimentId");

      private static final Map<String, _Fields> byName = new HashMap<String, _Fields>();

      static {
        for (_Fields field : EnumSet.allOf(_Fields.class)) {
          byName.put(field.getFieldName(), field);
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, or null if its not found.
       */
      public static _Fields findByThriftId(int fieldId) {
        switch(fieldId) {
          case 1: // AUTHZ_TOKEN
            return AUTHZ_TOKEN;
          case 2: // EXPERIMENT_ID
            return EXPERIMENT_ID;
          default:
            return null;
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, throwing an exception
       * if it is not found.
       */
      public static _Fields findByThriftIdOrThrow(int fieldId) {
        _Fields fields = findByThriftId(fieldId);
        if (fields == null) throw new IllegalArgumentException("Field " + fieldId + " doesn't exist!");
        return fields;
      }

      /**
       * Find the _Fields constant that matches name, or null if its not found.
       */
      public static _Fields findByName(String name) {
        return byName.get(name);
      }

      private final short _thriftId;
      private final String _fieldName;

      _Fields(short thriftId, String fieldName) {
        _thriftId = thriftId;
        _fieldName = fieldName;
      }

      public short getThriftFieldId() {
        return _thriftId;
      }

      public String getFieldName() {
        return _fieldName;
      }
    }

    // isset id assignments
    public static final Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
    static {
      Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new EnumMap<_Fields, org.apache.thrift.meta_data.FieldMetaData>(_Fields.class);
      tmpMap.put(_Fields.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.EXPERIMENT_ID, new org.apache.thrift.meta_data.FieldMetaData("experimentId", org.apache.thrift.TFieldRequirementType.REQUIRED, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING)));
      metaDataMap = Collections.unmodifiableMap(tmpMap);
      org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(deleteExperiment_args.class, metaDataMap);
    }

    public deleteExperiment_args() {
    }

    public deleteExperiment_args(
      org.apache.airavata.model.security.AuthzToken authzToken,
      String experimentId)
    {
      this();
      this.authzToken = authzToken;
      this.experimentId = experimentId;
    }

    /**
     * Performs a deep copy on <i>other</i>.
     */
    public deleteExperiment_args(deleteExperiment_args other) {
      if (other.isSetAuthzToken()) {
        this.authzToken = new org.apache.airavata.model.security.AuthzToken(other.authzToken);
      }
      if (other.isSetExperimentId()) {
        this.experimentId = other.experimentId;
      }
    }

    public deleteExperiment_args deepCopy() {
      return new deleteExperiment_args(this);
    }

    @Override
    public void clear() {
      this.authzToken = null;
      this.experimentId = null;
    }

    public org.apache.airavata.model.security.AuthzToken getAuthzToken() {
      return this.authzToken;
    }

    public deleteExperiment_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 String getExperimentId() {
      return this.experimentId;
    }

    public deleteExperiment_args setExperimentId(String experimentId) {
      this.experimentId = experimentId;
      return this;
    }

    public void unsetExperimentId() {
      this.experimentId = null;
    }

    /** Returns true if field experimentId is set (has been assigned a value) and false otherwise */
    public boolean isSetExperimentId() {
      return this.experimentId != null;
    }

    public void setExperimentIdIsSet(boolean value) {
      if (!value) {
        this.experimentId = null;
      }
    }

    public void setFieldValue(_Fields field, Object value) {
      switch (field) {
      case AUTHZ_TOKEN:
        if (value == null) {
          unsetAuthzToken();
        } else {
          setAuthzToken((org.apache.airavata.model.security.AuthzToken)value);
        }
        break;

      case EXPERIMENT_ID:
        if (value == null) {
          unsetExperimentId();
        } else {
          setExperimentId((String)value);
        }
        break;

      }
    }

    public Object getFieldValue(_Fields field) {
      switch (field) {
      case AUTHZ_TOKEN:
        return getAuthzToken();

      case EXPERIMENT_ID:
        return getExperimentId();

      }
      throw new IllegalStateException();
    }

    /** Returns true if field corresponding to fieldID is set (has been assigned a value) and false otherwise */
    public boolean isSet(_Fields field) {
      if (field == null) {
        throw new IllegalArgumentException();
      }

      switch (field) {
      case AUTHZ_TOKEN:
        return isSetAuthzToken();
      case EXPERIMENT_ID:
        return isSetExperimentId();
      }
      throw new IllegalStateException();
    }

    @Override
    public boolean equals(Object that) {
      if (that == null)
        return false;
      if (that instanceof deleteExperiment_args)
        return this.equals((deleteExperiment_args)that);
      return false;
    }

    public boolean equals(deleteExperiment_args that) {
      if (that == null)
        return false;

      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_experimentId = true && this.isSetExperimentId();
      boolean that_present_experimentId = true && that.isSetExperimentId();
      if (this_present_experimentId || that_present_experimentId) {
        if (!(this_present_experimentId && that_present_experimentId))
          return false;
        if (!this.experimentId.equals(that.experimentId))
          return false;
      }

      return true;
    }

    @Override
    public int hashCode() {
      List<Object> list = new ArrayList<Object>();

      boolean present_authzToken = true && (isSetAuthzToken());
      list.add(present_authzToken);
      if (present_authzToken)
        list.add(authzToken);

      boolean present_experimentId = true && (isSetExperimentId());
      list.add(present_experimentId);
      if (present_experimentId)
        list.add(experimentId);

      return list.hashCode();
    }

    @Override
    public int compareTo(deleteExperiment_args other) {
      if (!getClass().equals(other.getClass())) {
        return getClass().getName().compareTo(other.getClass().getName());
      }

      int lastComparison = 0;

      lastComparison = 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 = Boolean.valueOf(isSetExperimentId()).compareTo(other.isSetExperimentId());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetExperimentId()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.experimentId, other.experimentId);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      return 0;
    }

    public _Fields fieldForId(int fieldId) {
      return _Fields.findByThriftId(fieldId);
    }

    public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
      schemes.get(iprot.getScheme()).getScheme().read(iprot, this);
    }

    public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException {
      schemes.get(oprot.getScheme()).getScheme().write(oprot, this);
    }

    @Override
    public String toString() {
      StringBuilder sb = new StringBuilder("deleteExperiment_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("experimentId:");
      if (this.experimentId == null) {
        sb.append("null");
      } else {
        sb.append(this.experimentId);
      }
      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 (experimentId == null) {
        throw new org.apache.thrift.protocol.TProtocolException("Required field 'experimentId' 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, 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 deleteExperiment_argsStandardSchemeFactory implements SchemeFactory {
      public deleteExperiment_argsStandardScheme getScheme() {
        return new deleteExperiment_argsStandardScheme();
      }
    }

    private static class deleteExperiment_argsStandardScheme extends StandardScheme<deleteExperiment_args> {

      public void read(org.apache.thrift.protocol.TProtocol iprot, deleteExperiment_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: // EXPERIMENT_ID
              if (schemeField.type == org.apache.thrift.protocol.TType.STRING) {
                struct.experimentId = iprot.readString();
                struct.setExperimentIdIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            default:
              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
          }
          iprot.readFieldEnd();
        }
        iprot.readStructEnd();

        // check for required fields of primitive type, which can't be checked in the validate method
        struct.validate();
      }

      public void write(org.apache.thrift.protocol.TProtocol oprot, deleteExperiment_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.experimentId != null) {
          oprot.writeFieldBegin(EXPERIMENT_ID_FIELD_DESC);
          oprot.writeString(struct.experimentId);
          oprot.writeFieldEnd();
        }
        oprot.writeFieldStop();
        oprot.writeStructEnd();
      }

    }

    private static class deleteExperiment_argsTupleSchemeFactory implements SchemeFactory {
      public deleteExperiment_argsTupleScheme getScheme() {
        return new deleteExperiment_argsTupleScheme();
      }
    }

    private static class deleteExperiment_argsTupleScheme extends TupleScheme<deleteExperiment_args> {

      @Override
      public void write(org.apache.thrift.protocol.TProtocol prot, deleteExperiment_args struct) throws org.apache.thrift.TException {
        TTupleProtocol oprot = (TTupleProtocol) prot;
        struct.authzToken.write(oprot);
        oprot.writeString(struct.experimentId);
      }

      @Override
      public void read(org.apache.thrift.protocol.TProtocol prot, deleteExperiment_args struct) throws org.apache.thrift.TException {
        TTupleProtocol iprot = (TTupleProtocol) prot;
        struct.authzToken = new org.apache.airavata.model.security.AuthzToken();
        struct.authzToken.read(iprot);
        struct.setAuthzTokenIsSet(true);
        struct.experimentId = iprot.readString();
        struct.setExperimentIdIsSet(true);
      }
    }

  }

  public static class deleteExperiment_result implements org.apache.thrift.TBase<deleteExperiment_result, deleteExperiment_result._Fields>, java.io.Serializable, Cloneable, Comparable<deleteExperiment_result>   {
    private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("deleteExperiment_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 IRE_FIELD_DESC = new org.apache.thrift.protocol.TField("ire", org.apache.thrift.protocol.TType.STRUCT, (short)1);
    private static final org.apache.thrift.protocol.TField ACE_FIELD_DESC = new org.apache.thrift.protocol.TField("ace", org.apache.thrift.protocol.TType.STRUCT, (short)2);
    private static final org.apache.thrift.protocol.TField ASE_FIELD_DESC = new org.apache.thrift.protocol.TField("ase", org.apache.thrift.protocol.TType.STRUCT, (short)3);
    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)4);

    private static final Map<Class<? extends IScheme>, SchemeFactory> schemes = new HashMap<Class<? extends IScheme>, SchemeFactory>();
    static {
      schemes.put(StandardScheme.class, new deleteExperiment_resultStandardSchemeFactory());
      schemes.put(TupleScheme.class, new deleteExperiment_resultTupleSchemeFactory());
    }

    public boolean success; // required
    public org.apache.airavata.model.error.InvalidRequestException ire; // required
    public org.apache.airavata.model.error.AiravataClientException ace; // required
    public org.apache.airavata.model.error.AiravataSystemException ase; // 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"),
      IRE((short)1, "ire"),
      ACE((short)2, "ace"),
      ASE((short)3, "ase"),
      AE((short)4, "ae");

      private static final Map<String, _Fields> byName = new HashMap<String, _Fields>();

      static {
        for (_Fields field : EnumSet.allOf(_Fields.class)) {
          byName.put(field.getFieldName(), field);
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, or null if its not found.
       */
      public static _Fields findByThriftId(int fieldId) {
        switch(fieldId) {
          case 0: // SUCCESS
            return SUCCESS;
          case 1: // IRE
            return IRE;
          case 2: // ACE
            return ACE;
          case 3: // ASE
            return ASE;
          case 4: // 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 IllegalArgumentException("Field " + fieldId + " doesn't exist!");
        return fields;
      }

      /**
       * Find the _Fields constant that matches name, or null if its not found.
       */
      public static _Fields findByName(String name) {
        return byName.get(name);
      }

      private final short _thriftId;
      private final String _fieldName;

      _Fields(short thriftId, String fieldName) {
        _thriftId = thriftId;
        _fieldName = fieldName;
      }

      public short getThriftFieldId() {
        return _thriftId;
      }

      public String getFieldName() {
        return _fieldName;
      }
    }

    // isset id assignments
    private static final int __SUCCESS_ISSET_ID = 0;
    private byte __isset_bitfield = 0;
    public static final Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
    static {
      Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new EnumMap<_Fields, org.apache.thrift.meta_data.FieldMetaData>(_Fields.class);
      tmpMap.put(_Fields.SUCCESS, new org.apache.thrift.meta_data.FieldMetaData("success", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.BOOL)));
      tmpMap.put(_Fields.IRE, new org.apache.thrift.meta_data.FieldMetaData("ire", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRUCT)));
      tmpMap.put(_Fields.ACE, new org.apache.thrift.meta_data.FieldMetaData("ace", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRUCT)));
      tmpMap.put(_Fields.ASE, new org.apache.thrift.meta_data.FieldMetaData("ase", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRUCT)));
      tmpMap.put(_Fields.AE, new org.apache.thrift.meta_data.FieldMetaData("ae", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRUCT)));
      metaDataMap = Collections.unmodifiableMap(tmpMap);
      org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(deleteExperiment_result.class, metaDataMap);
    }

    public deleteExperiment_result() {
    }

    public deleteExperiment_result(
      boolean success,
      org.apache.airavata.model.error.InvalidRequestException ire,
      org.apache.airavata.model.error.AiravataClientException ace,
      org.apache.airavata.model.error.AiravataSystemException ase,
      org.apache.airavata.model.error.AuthorizationException ae)
    {
      this();
      this.success = success;
      setSuccessIsSet(true);
      this.ire = ire;
      this.ace = ace;
      this.ase = ase;
      this.ae = ae;
    }

    /**
     * Performs a deep copy on <i>other</i>.
     */
    public deleteExperiment_result(deleteExperiment_result other) {
      __isset_bitfield = other.__isset_bitfield;
      this.success = other.success;
      if (other.isSetIre()) {
        this.ire = new org.apache.airavata.model.error.InvalidRequestException(other.ire);
      }
      if (other.isSetAce()) {
        this.ace = new org.apache.airavata.model.error.AiravataClientException(other.ace);
      }
      if (other.isSetAse()) {
        this.ase = new org.apache.airavata.model.error.AiravataSystemException(other.ase);
      }
      if (other.isSetAe()) {
        this.ae = new org.apache.airavata.model.error.AuthorizationException(other.ae);
      }
    }

    public deleteExperiment_result deepCopy() {
      return new deleteExperiment_result(this);
    }

    @Override
    public void clear() {
      setSuccessIsSet(false);
      this.success = false;
      this.ire = null;
      this.ace = null;
      this.ase = null;
      this.ae = null;
    }

    public boolean isSuccess() {
      return this.success;
    }

    public deleteExperiment_result setSuccess(boolean success) {
      this.success = success;
      setSuccessIsSet(true);
      return this;
    }

    public void unsetSuccess() {
      __isset_bitfield = EncodingUtils.clearBit(__isset_bitfield, __SUCCESS_ISSET_ID);
    }

    /** Returns true if field success is set (has been assigned a value) and false otherwise */
    public boolean isSetSuccess() {
      return EncodingUtils.testBit(__isset_bitfield, __SUCCESS_ISSET_ID);
    }

    public void setSuccessIsSet(boolean value) {
      __isset_bitfield = EncodingUtils.setBit(__isset_bitfield, __SUCCESS_ISSET_ID, value);
    }

    public org.apache.airavata.model.error.InvalidRequestException getIre() {
      return this.ire;
    }

    public deleteExperiment_result setIre(org.apache.airavata.model.error.InvalidRequestException ire) {
      this.ire = ire;
      return this;
    }

    public void unsetIre() {
      this.ire = null;
    }

    /** Returns true if field ire is set (has been assigned a value) and false otherwise */
    public boolean isSetIre() {
      return this.ire != null;
    }

    public void setIreIsSet(boolean value) {
      if (!value) {
        this.ire = null;
      }
    }

    public org.apache.airavata.model.error.AiravataClientException getAce() {
      return this.ace;
    }

    public deleteExperiment_result setAce(org.apache.airavata.model.error.AiravataClientException ace) {
      this.ace = ace;
      return this;
    }

    public void unsetAce() {
      this.ace = null;
    }

    /** Returns true if field ace is set (has been assigned a value) and false otherwise */
    public boolean isSetAce() {
      return this.ace != null;
    }

    public void setAceIsSet(boolean value) {
      if (!value) {
        this.ace = null;
      }
    }

    public org.apache.airavata.model.error.AiravataSystemException getAse() {
      return this.ase;
    }

    public deleteExperiment_result setAse(org.apache.airavata.model.error.AiravataSystemException ase) {
      this.ase = ase;
      return this;
    }

    public void unsetAse() {
      this.ase = null;
    }

    /** Returns true if field ase is set (has been assigned a value) and false otherwise */
    public boolean isSetAse() {
      return this.ase != null;
    }

    public void setAseIsSet(boolean value) {
      if (!value) {
        this.ase = null;
      }
    }

    public org.apache.airavata.model.error.AuthorizationException getAe() {
      return this.ae;
    }

    public deleteExperiment_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, Object value) {
      switch (field) {
      case SUCCESS:
        if (value == null) {
          unsetSuccess();
        } else {
          setSuccess((Boolean)value);
        }
        break;

      case IRE:
        if (value == null) {
          unsetIre();
        } else {
          setIre((org.apache.airavata.model.error.InvalidRequestException)value);
        }
        break;

      case ACE:
        if (value == null) {
          unsetAce();
        } else {
          setAce((org.apache.airavata.model.error.AiravataClientException)value);
        }
        break;

      case ASE:
        if (value == null) {
          unsetAse();
        } else {
          setAse((org.apache.airavata.model.error.AiravataSystemException)value);
        }
        break;

      case AE:
        if (value == null) {
          unsetAe();
        } else {
          setAe((org.apache.airavata.model.error.AuthorizationException)value);
        }
        break;

      }
    }

    public Object getFieldValue(_Fields field) {
      switch (field) {
      case SUCCESS:
        return Boolean.valueOf(isSuccess());

      case IRE:
        return getIre();

      case ACE:
        return getAce();

      case ASE:
        return getAse();

      case AE:
        return getAe();

      }
      throw new IllegalStateException();
    }

    /** Returns true if field corresponding to fieldID is set (has been assigned a value) and false otherwise */
    public boolean isSet(_Fields field) {
      if (field == null) {
        throw new IllegalArgumentException();
      }

      switch (field) {
      case SUCCESS:
        return isSetSuccess();
      case IRE:
        return isSetIre();
      case ACE:
        return isSetAce();
      case ASE:
        return isSetAse();
      case AE:
        return isSetAe();
      }
      throw new IllegalStateException();
    }

    @Override
    public boolean equals(Object that) {
      if (that == null)
        return false;
      if (that instanceof deleteExperiment_result)
        return this.equals((deleteExperiment_result)that);
      return false;
    }

    public boolean equals(deleteExperiment_result that) {
      if (that == null)
        return false;

      boolean this_present_success = true;
      boolean that_present_success = true;
      if (this_present_success || that_present_success) {
        if (!(this_present_success && that_present_success))
          return false;
        if (this.success != that.success)
          return false;
      }

      boolean this_present_ire = true && this.isSetIre();
      boolean that_present_ire = true && that.isSetIre();
      if (this_present_ire || that_present_ire) {
        if (!(this_present_ire && that_present_ire))
          return false;
        if (!this.ire.equals(that.ire))
          return false;
      }

      boolean this_present_ace = true && this.isSetAce();
      boolean that_present_ace = true && that.isSetAce();
      if (this_present_ace || that_present_ace) {
        if (!(this_present_ace && that_present_ace))
          return false;
        if (!this.ace.equals(that.ace))
          return false;
      }

      boolean this_present_ase = true && this.isSetAse();
      boolean that_present_ase = true && that.isSetAse();
      if (this_present_ase || that_present_ase) {
        if (!(this_present_ase && that_present_ase))
          return false;
        if (!this.ase.equals(that.ase))
          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() {
      List<Object> list = new ArrayList<Object>();

      boolean present_success = true;
      list.add(present_success);
      if (present_success)
        list.add(success);

      boolean present_ire = true && (isSetIre());
      list.add(present_ire);
      if (present_ire)
        list.add(ire);

      boolean present_ace = true && (isSetAce());
      list.add(present_ace);
      if (present_ace)
        list.add(ace);

      boolean present_ase = true && (isSetAse());
      list.add(present_ase);
      if (present_ase)
        list.add(ase);

      boolean present_ae = true && (isSetAe());
      list.add(present_ae);
      if (present_ae)
        list.add(ae);

      return list.hashCode();
    }

    @Override
    public int compareTo(deleteExperiment_result other) {
      if (!getClass().equals(other.getClass())) {
        return getClass().getName().compareTo(other.getClass().getName());
      }

      int lastComparison = 0;

      lastComparison = Boolean.valueOf(isSetSuccess()).compareTo(other.isSetSuccess());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetSuccess()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.success, other.success);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = Boolean.valueOf(isSetIre()).compareTo(other.isSetIre());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetIre()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.ire, other.ire);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = Boolean.valueOf(isSetAce()).compareTo(other.isSetAce());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetAce()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.ace, other.ace);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = Boolean.valueOf(isSetAse()).compareTo(other.isSetAse());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetAse()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.ase, other.ase);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = 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 {
      schemes.get(iprot.getScheme()).getScheme().read(iprot, this);
    }

    public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException {
      schemes.get(oprot.getScheme()).getScheme().write(oprot, this);
      }

    @Override
    public String toString() {
      StringBuilder sb = new StringBuilder("deleteExperiment_result(");
      boolean first = true;

      sb.append("success:");
      sb.append(this.success);
      first = false;
      if (!first) sb.append(", ");
      sb.append("ire:");
      if (this.ire == null) {
        sb.append("null");
      } else {
        sb.append(this.ire);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("ace:");
      if (this.ace == null) {
        sb.append("null");
      } else {
        sb.append(this.ace);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("ase:");
      if (this.ase == null) {
        sb.append("null");
      } else {
        sb.append(this.ase);
      }
      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, 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 deleteExperiment_resultStandardSchemeFactory implements SchemeFactory {
      public deleteExperiment_resultStandardScheme getScheme() {
        return new deleteExperiment_resultStandardScheme();
      }
    }

    private static class deleteExperiment_resultStandardScheme extends StandardScheme<deleteExperiment_result> {

      public void read(org.apache.thrift.protocol.TProtocol iprot, deleteExperiment_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: // IRE
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.ire = new org.apache.airavata.model.error.InvalidRequestException();
                struct.ire.read(iprot);
                struct.setIreIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 2: // ACE
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.ace = new org.apache.airavata.model.error.AiravataClientException();
                struct.ace.read(iprot);
                struct.setAceIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 3: // ASE
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.ase = new org.apache.airavata.model.error.AiravataSystemException();
                struct.ase.read(iprot);
                struct.setAseIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 4: // 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, deleteExperiment_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.ire != null) {
          oprot.writeFieldBegin(IRE_FIELD_DESC);
          struct.ire.write(oprot);
          oprot.writeFieldEnd();
        }
        if (struct.ace != null) {
          oprot.writeFieldBegin(ACE_FIELD_DESC);
          struct.ace.write(oprot);
          oprot.writeFieldEnd();
        }
        if (struct.ase != null) {
          oprot.writeFieldBegin(ASE_FIELD_DESC);
          struct.ase.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 deleteExperiment_resultTupleSchemeFactory implements SchemeFactory {
      public deleteExperiment_resultTupleScheme getScheme() {
        return new deleteExperiment_resultTupleScheme();
      }
    }

    private static class deleteExperiment_resultTupleScheme extends TupleScheme<deleteExperiment_result> {

      @Override
      public void write(org.apache.thrift.protocol.TProtocol prot, deleteExperiment_result struct) throws org.apache.thrift.TException {
        TTupleProtocol oprot = (TTupleProtocol) prot;
        BitSet optionals = new BitSet();
        if (struct.isSetSuccess()) {
          optionals.set(0);
        }
        if (struct.isSetIre()) {
          optionals.set(1);
        }
        if (struct.isSetAce()) {
          optionals.set(2);
        }
        if (struct.isSetAse()) {
          optionals.set(3);
        }
        if (struct.isSetAe()) {
          optionals.set(4);
        }
        oprot.writeBitSet(optionals, 5);
        if (struct.isSetSuccess()) {
          oprot.writeBool(struct.success);
        }
        if (struct.isSetIre()) {
          struct.ire.write(oprot);
        }
        if (struct.isSetAce()) {
          struct.ace.write(oprot);
        }
        if (struct.isSetAse()) {
          struct.ase.write(oprot);
        }
        if (struct.isSetAe()) {
          struct.ae.write(oprot);
        }
      }

      @Override
      public void read(org.apache.thrift.protocol.TProtocol prot, deleteExperiment_result struct) throws org.apache.thrift.TException {
        TTupleProtocol iprot = (TTupleProtocol) prot;
        BitSet incoming = iprot.readBitSet(5);
        if (incoming.get(0)) {
          struct.success = iprot.readBool();
          struct.setSuccessIsSet(true);
        }
        if (incoming.get(1)) {
          struct.ire = new org.apache.airavata.model.error.InvalidRequestException();
          struct.ire.read(iprot);
          struct.setIreIsSet(true);
        }
        if (incoming.get(2)) {
          struct.ace = new org.apache.airavata.model.error.AiravataClientException();
          struct.ace.read(iprot);
          struct.setAceIsSet(true);
        }
        if (incoming.get(3)) {
          struct.ase = new org.apache.airavata.model.error.AiravataSystemException();
          struct.ase.read(iprot);
          struct.setAseIsSet(true);
        }
        if (incoming.get(4)) {
          struct.ae = new org.apache.airavata.model.error.AuthorizationException();
          struct.ae.read(iprot);
          struct.setAeIsSet(true);
        }
      }
    }

  }

  public static class getExperiment_args implements org.apache.thrift.TBase<getExperiment_args, getExperiment_args._Fields>, java.io.Serializable, Cloneable, Comparable<getExperiment_args>   {
    private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("getExperiment_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_EXPERIMENT_ID_FIELD_DESC = new org.apache.thrift.protocol.TField("airavataExperimentId", org.apache.thrift.protocol.TType.STRING, (short)2);

    private static final Map<Class<? extends IScheme>, SchemeFactory> schemes = new HashMap<Class<? extends IScheme>, SchemeFactory>();
    static {
      schemes.put(StandardScheme.class, new getExperiment_argsStandardSchemeFactory());
      schemes.put(TupleScheme.class, new getExperiment_argsTupleSchemeFactory());
    }

    public org.apache.airavata.model.security.AuthzToken authzToken; // required
    public String airavataExperimentId; // required

    /** 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_EXPERIMENT_ID((short)2, "airavataExperimentId");

      private static final Map<String, _Fields> byName = new HashMap<String, _Fields>();

      static {
        for (_Fields field : EnumSet.allOf(_Fields.class)) {
          byName.put(field.getFieldName(), field);
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, or null if its not found.
       */
      public static _Fields findByThriftId(int fieldId) {
        switch(fieldId) {
          case 1: // AUTHZ_TOKEN
            return AUTHZ_TOKEN;
          case 2: // AIRAVATA_EXPERIMENT_ID
            return AIRAVATA_EXPERIMENT_ID;
          default:
            return null;
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, throwing an exception
       * if it is not found.
       */
      public static _Fields findByThriftIdOrThrow(int fieldId) {
        _Fields fields = findByThriftId(fieldId);
        if (fields == null) throw new IllegalArgumentException("Field " + fieldId + " doesn't exist!");
        return fields;
      }

      /**
       * Find the _Fields constant that matches name, or null if its not found.
       */
      public static _Fields findByName(String name) {
        return byName.get(name);
      }

      private final short _thriftId;
      private final String _fieldName;

      _Fields(short thriftId, String fieldName) {
        _thriftId = thriftId;
        _fieldName = fieldName;
      }

      public short getThriftFieldId() {
        return _thriftId;
      }

      public String getFieldName() {
        return _fieldName;
      }
    }

    // isset id assignments
    public static final Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
    static {
      Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new EnumMap<_Fields, org.apache.thrift.meta_data.FieldMetaData>(_Fields.class);
      tmpMap.put(_Fields.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_EXPERIMENT_ID, new org.apache.thrift.meta_data.FieldMetaData("airavataExperimentId", org.apache.thrift.TFieldRequirementType.REQUIRED, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING)));
      metaDataMap = Collections.unmodifiableMap(tmpMap);
      org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(getExperiment_args.class, metaDataMap);
    }

    public getExperiment_args() {
    }

    public getExperiment_args(
      org.apache.airavata.model.security.AuthzToken authzToken,
      String airavataExperimentId)
    {
      this();
      this.authzToken = authzToken;
      this.airavataExperimentId = airavataExperimentId;
    }

    /**
     * Performs a deep copy on <i>other</i>.
     */
    public getExperiment_args(getExperiment_args other) {
      if (other.isSetAuthzToken()) {
        this.authzToken = new org.apache.airavata.model.security.AuthzToken(other.authzToken);
      }
      if (other.isSetAiravataExperimentId()) {
        this.airavataExperimentId = other.airavataExperimentId;
      }
    }

    public getExperiment_args deepCopy() {
      return new getExperiment_args(this);
    }

    @Override
    public void clear() {
      this.authzToken = null;
      this.airavataExperimentId = null;
    }

    public org.apache.airavata.model.security.AuthzToken getAuthzToken() {
      return this.authzToken;
    }

    public getExperiment_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 String getAiravataExperimentId() {
      return this.airavataExperimentId;
    }

    public getExperiment_args setAiravataExperimentId(String airavataExperimentId) {
      this.airavataExperimentId = airavataExperimentId;
      return this;
    }

    public void unsetAiravataExperimentId() {
      this.airavataExperimentId = null;
    }

    /** Returns true if field airavataExperimentId is set (has been assigned a value) and false otherwise */
    public boolean isSetAiravataExperimentId() {
      return this.airavataExperimentId != null;
    }

    public void setAiravataExperimentIdIsSet(boolean value) {
      if (!value) {
        this.airavataExperimentId = null;
      }
    }

    public void setFieldValue(_Fields field, Object value) {
      switch (field) {
      case AUTHZ_TOKEN:
        if (value == null) {
          unsetAuthzToken();
        } else {
          setAuthzToken((org.apache.airavata.model.security.AuthzToken)value);
        }
        break;

      case AIRAVATA_EXPERIMENT_ID:
        if (value == null) {
          unsetAiravataExperimentId();
        } else {
          setAiravataExperimentId((String)value);
        }
        break;

      }
    }

    public Object getFieldValue(_Fields field) {
      switch (field) {
      case AUTHZ_TOKEN:
        return getAuthzToken();

      case AIRAVATA_EXPERIMENT_ID:
        return getAiravataExperimentId();

      }
      throw new IllegalStateException();
    }

    /** Returns true if field corresponding to fieldID is set (has been assigned a value) and false otherwise */
    public boolean isSet(_Fields field) {
      if (field == null) {
        throw new IllegalArgumentException();
      }

      switch (field) {
      case AUTHZ_TOKEN:
        return isSetAuthzToken();
      case AIRAVATA_EXPERIMENT_ID:
        return isSetAiravataExperimentId();
      }
      throw new IllegalStateException();
    }

    @Override
    public boolean equals(Object that) {
      if (that == null)
        return false;
      if (that instanceof getExperiment_args)
        return this.equals((getExperiment_args)that);
      return false;
    }

    public boolean equals(getExperiment_args that) {
      if (that == null)
        return false;

      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_airavataExperimentId = true && this.isSetAiravataExperimentId();
      boolean that_present_airavataExperimentId = true && that.isSetAiravataExperimentId();
      if (this_present_airavataExperimentId || that_present_airavataExperimentId) {
        if (!(this_present_airavataExperimentId && that_present_airavataExperimentId))
          return false;
        if (!this.airavataExperimentId.equals(that.airavataExperimentId))
          return false;
      }

      return true;
    }

    @Override
    public int hashCode() {
      List<Object> list = new ArrayList<Object>();

      boolean present_authzToken = true && (isSetAuthzToken());
      list.add(present_authzToken);
      if (present_authzToken)
        list.add(authzToken);

      boolean present_airavataExperimentId = true && (isSetAiravataExperimentId());
      list.add(present_airavataExperimentId);
      if (present_airavataExperimentId)
        list.add(airavataExperimentId);

      return list.hashCode();
    }

    @Override
    public int compareTo(getExperiment_args other) {
      if (!getClass().equals(other.getClass())) {
        return getClass().getName().compareTo(other.getClass().getName());
      }

      int lastComparison = 0;

      lastComparison = 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 = Boolean.valueOf(isSetAiravataExperimentId()).compareTo(other.isSetAiravataExperimentId());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetAiravataExperimentId()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.airavataExperimentId, other.airavataExperimentId);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      return 0;
    }

    public _Fields fieldForId(int fieldId) {
      return _Fields.findByThriftId(fieldId);
    }

    public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
      schemes.get(iprot.getScheme()).getScheme().read(iprot, this);
    }

    public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException {
      schemes.get(oprot.getScheme()).getScheme().write(oprot, this);
    }

    @Override
    public String toString() {
      StringBuilder sb = new StringBuilder("getExperiment_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("airavataExperimentId:");
      if (this.airavataExperimentId == null) {
        sb.append("null");
      } else {
        sb.append(this.airavataExperimentId);
      }
      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 (airavataExperimentId == null) {
        throw new org.apache.thrift.protocol.TProtocolException("Required field 'airavataExperimentId' 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, 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 getExperiment_argsStandardSchemeFactory implements SchemeFactory {
      public getExperiment_argsStandardScheme getScheme() {
        return new getExperiment_argsStandardScheme();
      }
    }

    private static class getExperiment_argsStandardScheme extends StandardScheme<getExperiment_args> {

      public void read(org.apache.thrift.protocol.TProtocol iprot, getExperiment_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_EXPERIMENT_ID
              if (schemeField.type == org.apache.thrift.protocol.TType.STRING) {
                struct.airavataExperimentId = iprot.readString();
                struct.setAiravataExperimentIdIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            default:
              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
          }
          iprot.readFieldEnd();
        }
        iprot.readStructEnd();

        // check for required fields of primitive type, which can't be checked in the validate method
        struct.validate();
      }

      public void write(org.apache.thrift.protocol.TProtocol oprot, getExperiment_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.airavataExperimentId != null) {
          oprot.writeFieldBegin(AIRAVATA_EXPERIMENT_ID_FIELD_DESC);
          oprot.writeString(struct.airavataExperimentId);
          oprot.writeFieldEnd();
        }
        oprot.writeFieldStop();
        oprot.writeStructEnd();
      }

    }

    private static class getExperiment_argsTupleSchemeFactory implements SchemeFactory {
      public getExperiment_argsTupleScheme getScheme() {
        return new getExperiment_argsTupleScheme();
      }
    }

    private static class getExperiment_argsTupleScheme extends TupleScheme<getExperiment_args> {

      @Override
      public void write(org.apache.thrift.protocol.TProtocol prot, getExperiment_args struct) throws org.apache.thrift.TException {
        TTupleProtocol oprot = (TTupleProtocol) prot;
        struct.authzToken.write(oprot);
        oprot.writeString(struct.airavataExperimentId);
      }

      @Override
      public void read(org.apache.thrift.protocol.TProtocol prot, getExperiment_args struct) throws org.apache.thrift.TException {
        TTupleProtocol iprot = (TTupleProtocol) prot;
        struct.authzToken = new org.apache.airavata.model.security.AuthzToken();
        struct.authzToken.read(iprot);
        struct.setAuthzTokenIsSet(true);
        struct.airavataExperimentId = iprot.readString();
        struct.setAiravataExperimentIdIsSet(true);
      }
    }

  }

  public static class getExperiment_result implements org.apache.thrift.TBase<getExperiment_result, getExperiment_result._Fields>, java.io.Serializable, Cloneable, Comparable<getExperiment_result>   {
    private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("getExperiment_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 IRE_FIELD_DESC = new org.apache.thrift.protocol.TField("ire", org.apache.thrift.protocol.TType.STRUCT, (short)1);
    private static final org.apache.thrift.protocol.TField ENF_FIELD_DESC = new org.apache.thrift.protocol.TField("enf", org.apache.thrift.protocol.TType.STRUCT, (short)2);
    private static final org.apache.thrift.protocol.TField ACE_FIELD_DESC = new org.apache.thrift.protocol.TField("ace", org.apache.thrift.protocol.TType.STRUCT, (short)3);
    private static final org.apache.thrift.protocol.TField ASE_FIELD_DESC = new org.apache.thrift.protocol.TField("ase", org.apache.thrift.protocol.TType.STRUCT, (short)4);
    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)5);

    private static final Map<Class<? extends IScheme>, SchemeFactory> schemes = new HashMap<Class<? extends IScheme>, SchemeFactory>();
    static {
      schemes.put(StandardScheme.class, new getExperiment_resultStandardSchemeFactory());
      schemes.put(TupleScheme.class, new getExperiment_resultTupleSchemeFactory());
    }

    public org.apache.airavata.model.experiment.ExperimentModel success; // required
    public org.apache.airavata.model.error.InvalidRequestException ire; // required
    public org.apache.airavata.model.error.ExperimentNotFoundException enf; // required
    public org.apache.airavata.model.error.AiravataClientException ace; // required
    public org.apache.airavata.model.error.AiravataSystemException ase; // 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"),
      IRE((short)1, "ire"),
      ENF((short)2, "enf"),
      ACE((short)3, "ace"),
      ASE((short)4, "ase"),
      AE((short)5, "ae");

      private static final Map<String, _Fields> byName = new HashMap<String, _Fields>();

      static {
        for (_Fields field : EnumSet.allOf(_Fields.class)) {
          byName.put(field.getFieldName(), field);
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, or null if its not found.
       */
      public static _Fields findByThriftId(int fieldId) {
        switch(fieldId) {
          case 0: // SUCCESS
            return SUCCESS;
          case 1: // IRE
            return IRE;
          case 2: // ENF
            return ENF;
          case 3: // ACE
            return ACE;
          case 4: // ASE
            return ASE;
          case 5: // 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 IllegalArgumentException("Field " + fieldId + " doesn't exist!");
        return fields;
      }

      /**
       * Find the _Fields constant that matches name, or null if its not found.
       */
      public static _Fields findByName(String name) {
        return byName.get(name);
      }

      private final short _thriftId;
      private final String _fieldName;

      _Fields(short thriftId, String fieldName) {
        _thriftId = thriftId;
        _fieldName = fieldName;
      }

      public short getThriftFieldId() {
        return _thriftId;
      }

      public String getFieldName() {
        return _fieldName;
      }
    }

    // isset id assignments
    public static final Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
    static {
      Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new EnumMap<_Fields, org.apache.thrift.meta_data.FieldMetaData>(_Fields.class);
      tmpMap.put(_Fields.SUCCESS, new org.apache.thrift.meta_data.FieldMetaData("success", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.StructMetaData(org.apache.thrift.protocol.TType.STRUCT, org.apache.airavata.model.experiment.ExperimentModel.class)));
      tmpMap.put(_Fields.IRE, new org.apache.thrift.meta_data.FieldMetaData("ire", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRUCT)));
      tmpMap.put(_Fields.ENF, new org.apache.thrift.meta_data.FieldMetaData("enf", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRUCT)));
      tmpMap.put(_Fields.ACE, new org.apache.thrift.meta_data.FieldMetaData("ace", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRUCT)));
      tmpMap.put(_Fields.ASE, new org.apache.thrift.meta_data.FieldMetaData("ase", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRUCT)));
      tmpMap.put(_Fields.AE, new org.apache.thrift.meta_data.FieldMetaData("ae", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRUCT)));
      metaDataMap = Collections.unmodifiableMap(tmpMap);
      org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(getExperiment_result.class, metaDataMap);
    }

    public getExperiment_result() {
    }

    public getExperiment_result(
      org.apache.airavata.model.experiment.ExperimentModel success,
      org.apache.airavata.model.error.InvalidRequestException ire,
      org.apache.airavata.model.error.ExperimentNotFoundException enf,
      org.apache.airavata.model.error.AiravataClientException ace,
      org.apache.airavata.model.error.AiravataSystemException ase,
      org.apache.airavata.model.error.AuthorizationException ae)
    {
      this();
      this.success = success;
      this.ire = ire;
      this.enf = enf;
      this.ace = ace;
      this.ase = ase;
      this.ae = ae;
    }

    /**
     * Performs a deep copy on <i>other</i>.
     */
    public getExperiment_result(getExperiment_result other) {
      if (other.isSetSuccess()) {
        this.success = new org.apache.airavata.model.experiment.ExperimentModel(other.success);
      }
      if (other.isSetIre()) {
        this.ire = new org.apache.airavata.model.error.InvalidRequestException(other.ire);
      }
      if (other.isSetEnf()) {
        this.enf = new org.apache.airavata.model.error.ExperimentNotFoundException(other.enf);
      }
      if (other.isSetAce()) {
        this.ace = new org.apache.airavata.model.error.AiravataClientException(other.ace);
      }
      if (other.isSetAse()) {
        this.ase = new org.apache.airavata.model.error.AiravataSystemException(other.ase);
      }
      if (other.isSetAe()) {
        this.ae = new org.apache.airavata.model.error.AuthorizationException(other.ae);
      }
    }

    public getExperiment_result deepCopy() {
      return new getExperiment_result(this);
    }

    @Override
    public void clear() {
      this.success = null;
      this.ire = null;
      this.enf = null;
      this.ace = null;
      this.ase = null;
      this.ae = null;
    }

    public org.apache.airavata.model.experiment.ExperimentModel getSuccess() {
      return this.success;
    }

    public getExperiment_result setSuccess(org.apache.airavata.model.experiment.ExperimentModel 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.model.error.InvalidRequestException getIre() {
      return this.ire;
    }

    public getExperiment_result setIre(org.apache.airavata.model.error.InvalidRequestException ire) {
      this.ire = ire;
      return this;
    }

    public void unsetIre() {
      this.ire = null;
    }

    /** Returns true if field ire is set (has been assigned a value) and false otherwise */
    public boolean isSetIre() {
      return this.ire != null;
    }

    public void setIreIsSet(boolean value) {
      if (!value) {
        this.ire = null;
      }
    }

    public org.apache.airavata.model.error.ExperimentNotFoundException getEnf() {
      return this.enf;
    }

    public getExperiment_result setEnf(org.apache.airavata.model.error.ExperimentNotFoundException enf) {
      this.enf = enf;
      return this;
    }

    public void unsetEnf() {
      this.enf = null;
    }

    /** Returns true if field enf is set (has been assigned a value) and false otherwise */
    public boolean isSetEnf() {
      return this.enf != null;
    }

    public void setEnfIsSet(boolean value) {
      if (!value) {
        this.enf = null;
      }
    }

    public org.apache.airavata.model.error.AiravataClientException getAce() {
      return this.ace;
    }

    public getExperiment_result setAce(org.apache.airavata.model.error.AiravataClientException ace) {
      this.ace = ace;
      return this;
    }

    public void unsetAce() {
      this.ace = null;
    }

    /** Returns true if field ace is set (has been assigned a value) and false otherwise */
    public boolean isSetAce() {
      return this.ace != null;
    }

    public void setAceIsSet(boolean value) {
      if (!value) {
        this.ace = null;
      }
    }

    public org.apache.airavata.model.error.AiravataSystemException getAse() {
      return this.ase;
    }

    public getExperiment_result setAse(org.apache.airavata.model.error.AiravataSystemException ase) {
      this.ase = ase;
      return this;
    }

    public void unsetAse() {
      this.ase = null;
    }

    /** Returns true if field ase is set (has been assigned a value) and false otherwise */
    public boolean isSetAse() {
      return this.ase != null;
    }

    public void setAseIsSet(boolean value) {
      if (!value) {
        this.ase = null;
      }
    }

    public org.apache.airavata.model.error.AuthorizationException getAe() {
      return this.ae;
    }

    public getExperiment_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, Object value) {
      switch (field) {
      case SUCCESS:
        if (value == null) {
          unsetSuccess();
        } else {
          setSuccess((org.apache.airavata.model.experiment.ExperimentModel)value);
        }
        break;

      case IRE:
        if (value == null) {
          unsetIre();
        } else {
          setIre((org.apache.airavata.model.error.InvalidRequestException)value);
        }
        break;

      case ENF:
        if (value == null) {
          unsetEnf();
        } else {
          setEnf((org.apache.airavata.model.error.ExperimentNotFoundException)value);
        }
        break;

      case ACE:
        if (value == null) {
          unsetAce();
        } else {
          setAce((org.apache.airavata.model.error.AiravataClientException)value);
        }
        break;

      case ASE:
        if (value == null) {
          unsetAse();
        } else {
          setAse((org.apache.airavata.model.error.AiravataSystemException)value);
        }
        break;

      case AE:
        if (value == null) {
          unsetAe();
        } else {
          setAe((org.apache.airavata.model.error.AuthorizationException)value);
        }
        break;

      }
    }

    public Object getFieldValue(_Fields field) {
      switch (field) {
      case SUCCESS:
        return getSuccess();

      case IRE:
        return getIre();

      case ENF:
        return getEnf();

      case ACE:
        return getAce();

      case ASE:
        return getAse();

      case AE:
        return getAe();

      }
      throw new IllegalStateException();
    }

    /** Returns true if field corresponding to fieldID is set (has been assigned a value) and false otherwise */
    public boolean isSet(_Fields field) {
      if (field == null) {
        throw new IllegalArgumentException();
      }

      switch (field) {
      case SUCCESS:
        return isSetSuccess();
      case IRE:
        return isSetIre();
      case ENF:
        return isSetEnf();
      case ACE:
        return isSetAce();
      case ASE:
        return isSetAse();
      case AE:
        return isSetAe();
      }
      throw new IllegalStateException();
    }

    @Override
    public boolean equals(Object that) {
      if (that == null)
        return false;
      if (that instanceof getExperiment_result)
        return this.equals((getExperiment_result)that);
      return false;
    }

    public boolean equals(getExperiment_result that) {
      if (that == null)
        return false;

      boolean this_present_success = true && this.isSetSuccess();
      boolean that_present_success = true && that.isSetSuccess();
      if (this_present_success || that_present_success) {
        if (!(this_present_success && that_present_success))
          return false;
        if (!this.success.equals(that.success))
          return false;
      }

      boolean this_present_ire = true && this.isSetIre();
      boolean that_present_ire = true && that.isSetIre();
      if (this_present_ire || that_present_ire) {
        if (!(this_present_ire && that_present_ire))
          return false;
        if (!this.ire.equals(that.ire))
          return false;
      }

      boolean this_present_enf = true && this.isSetEnf();
      boolean that_present_enf = true && that.isSetEnf();
      if (this_present_enf || that_present_enf) {
        if (!(this_present_enf && that_present_enf))
          return false;
        if (!this.enf.equals(that.enf))
          return false;
      }

      boolean this_present_ace = true && this.isSetAce();
      boolean that_present_ace = true && that.isSetAce();
      if (this_present_ace || that_present_ace) {
        if (!(this_present_ace && that_present_ace))
          return false;
        if (!this.ace.equals(that.ace))
          return false;
      }

      boolean this_present_ase = true && this.isSetAse();
      boolean that_present_ase = true && that.isSetAse();
      if (this_present_ase || that_present_ase) {
        if (!(this_present_ase && that_present_ase))
          return false;
        if (!this.ase.equals(that.ase))
          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() {
      List<Object> list = new ArrayList<Object>();

      boolean present_success = true && (isSetSuccess());
      list.add(present_success);
      if (present_success)
        list.add(success);

      boolean present_ire = true && (isSetIre());
      list.add(present_ire);
      if (present_ire)
        list.add(ire);

      boolean present_enf = true && (isSetEnf());
      list.add(present_enf);
      if (present_enf)
        list.add(enf);

      boolean present_ace = true && (isSetAce());
      list.add(present_ace);
      if (present_ace)
        list.add(ace);

      boolean present_ase = true && (isSetAse());
      list.add(present_ase);
      if (present_ase)
        list.add(ase);

      boolean present_ae = true && (isSetAe());
      list.add(present_ae);
      if (present_ae)
        list.add(ae);

      return list.hashCode();
    }

    @Override
    public int compareTo(getExperiment_result other) {
      if (!getClass().equals(other.getClass())) {
        return getClass().getName().compareTo(other.getClass().getName());
      }

      int lastComparison = 0;

      lastComparison = Boolean.valueOf(isSetSuccess()).compareTo(other.isSetSuccess());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetSuccess()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.success, other.success);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = Boolean.valueOf(isSetIre()).compareTo(other.isSetIre());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetIre()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.ire, other.ire);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = Boolean.valueOf(isSetEnf()).compareTo(other.isSetEnf());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetEnf()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.enf, other.enf);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = Boolean.valueOf(isSetAce()).compareTo(other.isSetAce());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetAce()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.ace, other.ace);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = Boolean.valueOf(isSetAse()).compareTo(other.isSetAse());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetAse()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.ase, other.ase);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = 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 {
      schemes.get(iprot.getScheme()).getScheme().read(iprot, this);
    }

    public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException {
      schemes.get(oprot.getScheme()).getScheme().write(oprot, this);
      }

    @Override
    public String toString() {
      StringBuilder sb = new StringBuilder("getExperiment_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("ire:");
      if (this.ire == null) {
        sb.append("null");
      } else {
        sb.append(this.ire);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("enf:");
      if (this.enf == null) {
        sb.append("null");
      } else {
        sb.append(this.enf);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("ace:");
      if (this.ace == null) {
        sb.append("null");
      } else {
        sb.append(this.ace);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("ase:");
      if (this.ase == null) {
        sb.append("null");
      } else {
        sb.append(this.ase);
      }
      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, 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 getExperiment_resultStandardSchemeFactory implements SchemeFactory {
      public getExperiment_resultStandardScheme getScheme() {
        return new getExperiment_resultStandardScheme();
      }
    }

    private static class getExperiment_resultStandardScheme extends StandardScheme<getExperiment_result> {

      public void read(org.apache.thrift.protocol.TProtocol iprot, getExperiment_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.experiment.ExperimentModel();
                struct.success.read(iprot);
                struct.setSuccessIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 1: // IRE
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.ire = new org.apache.airavata.model.error.InvalidRequestException();
                struct.ire.read(iprot);
                struct.setIreIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 2: // ENF
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.enf = new org.apache.airavata.model.error.ExperimentNotFoundException();
                struct.enf.read(iprot);
                struct.setEnfIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 3: // ACE
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.ace = new org.apache.airavata.model.error.AiravataClientException();
                struct.ace.read(iprot);
                struct.setAceIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 4: // ASE
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.ase = new org.apache.airavata.model.error.AiravataSystemException();
                struct.ase.read(iprot);
                struct.setAseIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 5: // 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, getExperiment_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.ire != null) {
          oprot.writeFieldBegin(IRE_FIELD_DESC);
          struct.ire.write(oprot);
          oprot.writeFieldEnd();
        }
        if (struct.enf != null) {
          oprot.writeFieldBegin(ENF_FIELD_DESC);
          struct.enf.write(oprot);
          oprot.writeFieldEnd();
        }
        if (struct.ace != null) {
          oprot.writeFieldBegin(ACE_FIELD_DESC);
          struct.ace.write(oprot);
          oprot.writeFieldEnd();
        }
        if (struct.ase != null) {
          oprot.writeFieldBegin(ASE_FIELD_DESC);
          struct.ase.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 getExperiment_resultTupleSchemeFactory implements SchemeFactory {
      public getExperiment_resultTupleScheme getScheme() {
        return new getExperiment_resultTupleScheme();
      }
    }

    private static class getExperiment_resultTupleScheme extends TupleScheme<getExperiment_result> {

      @Override
      public void write(org.apache.thrift.protocol.TProtocol prot, getExperiment_result struct) throws org.apache.thrift.TException {
        TTupleProtocol oprot = (TTupleProtocol) prot;
        BitSet optionals = new BitSet();
        if (struct.isSetSuccess()) {
          optionals.set(0);
        }
        if (struct.isSetIre()) {
          optionals.set(1);
        }
        if (struct.isSetEnf()) {
          optionals.set(2);
        }
        if (struct.isSetAce()) {
          optionals.set(3);
        }
        if (struct.isSetAse()) {
          optionals.set(4);
        }
        if (struct.isSetAe()) {
          optionals.set(5);
        }
        oprot.writeBitSet(optionals, 6);
        if (struct.isSetSuccess()) {
          struct.success.write(oprot);
        }
        if (struct.isSetIre()) {
          struct.ire.write(oprot);
        }
        if (struct.isSetEnf()) {
          struct.enf.write(oprot);
        }
        if (struct.isSetAce()) {
          struct.ace.write(oprot);
        }
        if (struct.isSetAse()) {
          struct.ase.write(oprot);
        }
        if (struct.isSetAe()) {
          struct.ae.write(oprot);
        }
      }

      @Override
      public void read(org.apache.thrift.protocol.TProtocol prot, getExperiment_result struct) throws org.apache.thrift.TException {
        TTupleProtocol iprot = (TTupleProtocol) prot;
        BitSet incoming = iprot.readBitSet(6);
        if (incoming.get(0)) {
          struct.success = new org.apache.airavata.model.experiment.ExperimentModel();
          struct.success.read(iprot);
          struct.setSuccessIsSet(true);
        }
        if (incoming.get(1)) {
          struct.ire = new org.apache.airavata.model.error.InvalidRequestException();
          struct.ire.read(iprot);
          struct.setIreIsSet(true);
        }
        if (incoming.get(2)) {
          struct.enf = new org.apache.airavata.model.error.ExperimentNotFoundException();
          struct.enf.read(iprot);
          struct.setEnfIsSet(true);
        }
        if (incoming.get(3)) {
          struct.ace = new org.apache.airavata.model.error.AiravataClientException();
          struct.ace.read(iprot);
          struct.setAceIsSet(true);
        }
        if (incoming.get(4)) {
          struct.ase = new org.apache.airavata.model.error.AiravataSystemException();
          struct.ase.read(iprot);
          struct.setAseIsSet(true);
        }
        if (incoming.get(5)) {
          struct.ae = new org.apache.airavata.model.error.AuthorizationException();
          struct.ae.read(iprot);
          struct.setAeIsSet(true);
        }
      }
    }

  }

  public static class getDetailedExperimentTree_args implements org.apache.thrift.TBase<getDetailedExperimentTree_args, getDetailedExperimentTree_args._Fields>, java.io.Serializable, Cloneable, Comparable<getDetailedExperimentTree_args>   {
    private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("getDetailedExperimentTree_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_EXPERIMENT_ID_FIELD_DESC = new org.apache.thrift.protocol.TField("airavataExperimentId", org.apache.thrift.protocol.TType.STRING, (short)2);

    private static final Map<Class<? extends IScheme>, SchemeFactory> schemes = new HashMap<Class<? extends IScheme>, SchemeFactory>();
    static {
      schemes.put(StandardScheme.class, new getDetailedExperimentTree_argsStandardSchemeFactory());
      schemes.put(TupleScheme.class, new getDetailedExperimentTree_argsTupleSchemeFactory());
    }

    public org.apache.airavata.model.security.AuthzToken authzToken; // required
    public String airavataExperimentId; // required

    /** 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_EXPERIMENT_ID((short)2, "airavataExperimentId");

      private static final Map<String, _Fields> byName = new HashMap<String, _Fields>();

      static {
        for (_Fields field : EnumSet.allOf(_Fields.class)) {
          byName.put(field.getFieldName(), field);
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, or null if its not found.
       */
      public static _Fields findByThriftId(int fieldId) {
        switch(fieldId) {
          case 1: // AUTHZ_TOKEN
            return AUTHZ_TOKEN;
          case 2: // AIRAVATA_EXPERIMENT_ID
            return AIRAVATA_EXPERIMENT_ID;
          default:
            return null;
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, throwing an exception
       * if it is not found.
       */
      public static _Fields findByThriftIdOrThrow(int fieldId) {
        _Fields fields = findByThriftId(fieldId);
        if (fields == null) throw new IllegalArgumentException("Field " + fieldId + " doesn't exist!");
        return fields;
      }

      /**
       * Find the _Fields constant that matches name, or null if its not found.
       */
      public static _Fields findByName(String name) {
        return byName.get(name);
      }

      private final short _thriftId;
      private final String _fieldName;

      _Fields(short thriftId, String fieldName) {
        _thriftId = thriftId;
        _fieldName = fieldName;
      }

      public short getThriftFieldId() {
        return _thriftId;
      }

      public String getFieldName() {
        return _fieldName;
      }
    }

    // isset id assignments
    public static final Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
    static {
      Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new EnumMap<_Fields, org.apache.thrift.meta_data.FieldMetaData>(_Fields.class);
      tmpMap.put(_Fields.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_EXPERIMENT_ID, new org.apache.thrift.meta_data.FieldMetaData("airavataExperimentId", org.apache.thrift.TFieldRequirementType.REQUIRED, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING)));
      metaDataMap = Collections.unmodifiableMap(tmpMap);
      org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(getDetailedExperimentTree_args.class, metaDataMap);
    }

    public getDetailedExperimentTree_args() {
    }

    public getDetailedExperimentTree_args(
      org.apache.airavata.model.security.AuthzToken authzToken,
      String airavataExperimentId)
    {
      this();
      this.authzToken = authzToken;
      this.airavataExperimentId = airavataExperimentId;
    }

    /**
     * Performs a deep copy on <i>other</i>.
     */
    public getDetailedExperimentTree_args(getDetailedExperimentTree_args other) {
      if (other.isSetAuthzToken()) {
        this.authzToken = new org.apache.airavata.model.security.AuthzToken(other.authzToken);
      }
      if (other.isSetAiravataExperimentId()) {
        this.airavataExperimentId = other.airavataExperimentId;
      }
    }

    public getDetailedExperimentTree_args deepCopy() {
      return new getDetailedExperimentTree_args(this);
    }

    @Override
    public void clear() {
      this.authzToken = null;
      this.airavataExperimentId = null;
    }

    public org.apache.airavata.model.security.AuthzToken getAuthzToken() {
      return this.authzToken;
    }

    public getDetailedExperimentTree_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 String getAiravataExperimentId() {
      return this.airavataExperimentId;
    }

    public getDetailedExperimentTree_args setAiravataExperimentId(String airavataExperimentId) {
      this.airavataExperimentId = airavataExperimentId;
      return this;
    }

    public void unsetAiravataExperimentId() {
      this.airavataExperimentId = null;
    }

    /** Returns true if field airavataExperimentId is set (has been assigned a value) and false otherwise */
    public boolean isSetAiravataExperimentId() {
      return this.airavataExperimentId != null;
    }

    public void setAiravataExperimentIdIsSet(boolean value) {
      if (!value) {
        this.airavataExperimentId = null;
      }
    }

    public void setFieldValue(_Fields field, Object value) {
      switch (field) {
      case AUTHZ_TOKEN:
        if (value == null) {
          unsetAuthzToken();
        } else {
          setAuthzToken((org.apache.airavata.model.security.AuthzToken)value);
        }
        break;

      case AIRAVATA_EXPERIMENT_ID:
        if (value == null) {
          unsetAiravataExperimentId();
        } else {
          setAiravataExperimentId((String)value);
        }
        break;

      }
    }

    public Object getFieldValue(_Fields field) {
      switch (field) {
      case AUTHZ_TOKEN:
        return getAuthzToken();

      case AIRAVATA_EXPERIMENT_ID:
        return getAiravataExperimentId();

      }
      throw new IllegalStateException();
    }

    /** Returns true if field corresponding to fieldID is set (has been assigned a value) and false otherwise */
    public boolean isSet(_Fields field) {
      if (field == null) {
        throw new IllegalArgumentException();
      }

      switch (field) {
      case AUTHZ_TOKEN:
        return isSetAuthzToken();
      case AIRAVATA_EXPERIMENT_ID:
        return isSetAiravataExperimentId();
      }
      throw new IllegalStateException();
    }

    @Override
    public boolean equals(Object that) {
      if (that == null)
        return false;
      if (that instanceof getDetailedExperimentTree_args)
        return this.equals((getDetailedExperimentTree_args)that);
      return false;
    }

    public boolean equals(getDetailedExperimentTree_args that) {
      if (that == null)
        return false;

      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_airavataExperimentId = true && this.isSetAiravataExperimentId();
      boolean that_present_airavataExperimentId = true && that.isSetAiravataExperimentId();
      if (this_present_airavataExperimentId || that_present_airavataExperimentId) {
        if (!(this_present_airavataExperimentId && that_present_airavataExperimentId))
          return false;
        if (!this.airavataExperimentId.equals(that.airavataExperimentId))
          return false;
      }

      return true;
    }

    @Override
    public int hashCode() {
      List<Object> list = new ArrayList<Object>();

      boolean present_authzToken = true && (isSetAuthzToken());
      list.add(present_authzToken);
      if (present_authzToken)
        list.add(authzToken);

      boolean present_airavataExperimentId = true && (isSetAiravataExperimentId());
      list.add(present_airavataExperimentId);
      if (present_airavataExperimentId)
        list.add(airavataExperimentId);

      return list.hashCode();
    }

    @Override
    public int compareTo(getDetailedExperimentTree_args other) {
      if (!getClass().equals(other.getClass())) {
        return getClass().getName().compareTo(other.getClass().getName());
      }

      int lastComparison = 0;

      lastComparison = 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 = Boolean.valueOf(isSetAiravataExperimentId()).compareTo(other.isSetAiravataExperimentId());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetAiravataExperimentId()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.airavataExperimentId, other.airavataExperimentId);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      return 0;
    }

    public _Fields fieldForId(int fieldId) {
      return _Fields.findByThriftId(fieldId);
    }

    public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
      schemes.get(iprot.getScheme()).getScheme().read(iprot, this);
    }

    public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException {
      schemes.get(oprot.getScheme()).getScheme().write(oprot, this);
    }

    @Override
    public String toString() {
      StringBuilder sb = new StringBuilder("getDetailedExperimentTree_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("airavataExperimentId:");
      if (this.airavataExperimentId == null) {
        sb.append("null");
      } else {
        sb.append(this.airavataExperimentId);
      }
      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 (airavataExperimentId == null) {
        throw new org.apache.thrift.protocol.TProtocolException("Required field 'airavataExperimentId' 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, 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 getDetailedExperimentTree_argsStandardSchemeFactory implements SchemeFactory {
      public getDetailedExperimentTree_argsStandardScheme getScheme() {
        return new getDetailedExperimentTree_argsStandardScheme();
      }
    }

    private static class getDetailedExperimentTree_argsStandardScheme extends StandardScheme<getDetailedExperimentTree_args> {

      public void read(org.apache.thrift.protocol.TProtocol iprot, getDetailedExperimentTree_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_EXPERIMENT_ID
              if (schemeField.type == org.apache.thrift.protocol.TType.STRING) {
                struct.airavataExperimentId = iprot.readString();
                struct.setAiravataExperimentIdIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            default:
              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
          }
          iprot.readFieldEnd();
        }
        iprot.readStructEnd();

        // check for required fields of primitive type, which can't be checked in the validate method
        struct.validate();
      }

      public void write(org.apache.thrift.protocol.TProtocol oprot, getDetailedExperimentTree_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.airavataExperimentId != null) {
          oprot.writeFieldBegin(AIRAVATA_EXPERIMENT_ID_FIELD_DESC);
          oprot.writeString(struct.airavataExperimentId);
          oprot.writeFieldEnd();
        }
        oprot.writeFieldStop();
        oprot.writeStructEnd();
      }

    }

    private static class getDetailedExperimentTree_argsTupleSchemeFactory implements SchemeFactory {
      public getDetailedExperimentTree_argsTupleScheme getScheme() {
        return new getDetailedExperimentTree_argsTupleScheme();
      }
    }

    private static class getDetailedExperimentTree_argsTupleScheme extends TupleScheme<getDetailedExperimentTree_args> {

      @Override
      public void write(org.apache.thrift.protocol.TProtocol prot, getDetailedExperimentTree_args struct) throws org.apache.thrift.TException {
        TTupleProtocol oprot = (TTupleProtocol) prot;
        struct.authzToken.write(oprot);
        oprot.writeString(struct.airavataExperimentId);
      }

      @Override
      public void read(org.apache.thrift.protocol.TProtocol prot, getDetailedExperimentTree_args struct) throws org.apache.thrift.TException {
        TTupleProtocol iprot = (TTupleProtocol) prot;
        struct.authzToken = new org.apache.airavata.model.security.AuthzToken();
        struct.authzToken.read(iprot);
        struct.setAuthzTokenIsSet(true);
        struct.airavataExperimentId = iprot.readString();
        struct.setAiravataExperimentIdIsSet(true);
      }
    }

  }

  public static class getDetailedExperimentTree_result implements org.apache.thrift.TBase<getDetailedExperimentTree_result, getDetailedExperimentTree_result._Fields>, java.io.Serializable, Cloneable, Comparable<getDetailedExperimentTree_result>   {
    private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("getDetailedExperimentTree_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 IRE_FIELD_DESC = new org.apache.thrift.protocol.TField("ire", org.apache.thrift.protocol.TType.STRUCT, (short)1);
    private static final org.apache.thrift.protocol.TField ENF_FIELD_DESC = new org.apache.thrift.protocol.TField("enf", org.apache.thrift.protocol.TType.STRUCT, (short)2);
    private static final org.apache.thrift.protocol.TField ACE_FIELD_DESC = new org.apache.thrift.protocol.TField("ace", org.apache.thrift.protocol.TType.STRUCT, (short)3);
    private static final org.apache.thrift.protocol.TField ASE_FIELD_DESC = new org.apache.thrift.protocol.TField("ase", org.apache.thrift.protocol.TType.STRUCT, (short)4);
    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)5);

    private static final Map<Class<? extends IScheme>, SchemeFactory> schemes = new HashMap<Class<? extends IScheme>, SchemeFactory>();
    static {
      schemes.put(StandardScheme.class, new getDetailedExperimentTree_resultStandardSchemeFactory());
      schemes.put(TupleScheme.class, new getDetailedExperimentTree_resultTupleSchemeFactory());
    }

    public org.apache.airavata.model.experiment.ExperimentModel success; // required
    public org.apache.airavata.model.error.InvalidRequestException ire; // required
    public org.apache.airavata.model.error.ExperimentNotFoundException enf; // required
    public org.apache.airavata.model.error.AiravataClientException ace; // required
    public org.apache.airavata.model.error.AiravataSystemException ase; // 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"),
      IRE((short)1, "ire"),
      ENF((short)2, "enf"),
      ACE((short)3, "ace"),
      ASE((short)4, "ase"),
      AE((short)5, "ae");

      private static final Map<String, _Fields> byName = new HashMap<String, _Fields>();

      static {
        for (_Fields field : EnumSet.allOf(_Fields.class)) {
          byName.put(field.getFieldName(), field);
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, or null if its not found.
       */
      public static _Fields findByThriftId(int fieldId) {
        switch(fieldId) {
          case 0: // SUCCESS
            return SUCCESS;
          case 1: // IRE
            return IRE;
          case 2: // ENF
            return ENF;
          case 3: // ACE
            return ACE;
          case 4: // ASE
            return ASE;
          case 5: // 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 IllegalArgumentException("Field " + fieldId + " doesn't exist!");
        return fields;
      }

      /**
       * Find the _Fields constant that matches name, or null if its not found.
       */
      public static _Fields findByName(String name) {
        return byName.get(name);
      }

      private final short _thriftId;
      private final String _fieldName;

      _Fields(short thriftId, String fieldName) {
        _thriftId = thriftId;
        _fieldName = fieldName;
      }

      public short getThriftFieldId() {
        return _thriftId;
      }

      public String getFieldName() {
        return _fieldName;
      }
    }

    // isset id assignments
    public static final Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
    static {
      Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new EnumMap<_Fields, org.apache.thrift.meta_data.FieldMetaData>(_Fields.class);
      tmpMap.put(_Fields.SUCCESS, new org.apache.thrift.meta_data.FieldMetaData("success", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.StructMetaData(org.apache.thrift.protocol.TType.STRUCT, org.apache.airavata.model.experiment.ExperimentModel.class)));
      tmpMap.put(_Fields.IRE, new org.apache.thrift.meta_data.FieldMetaData("ire", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRUCT)));
      tmpMap.put(_Fields.ENF, new org.apache.thrift.meta_data.FieldMetaData("enf", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRUCT)));
      tmpMap.put(_Fields.ACE, new org.apache.thrift.meta_data.FieldMetaData("ace", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRUCT)));
      tmpMap.put(_Fields.ASE, new org.apache.thrift.meta_data.FieldMetaData("ase", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRUCT)));
      tmpMap.put(_Fields.AE, new org.apache.thrift.meta_data.FieldMetaData("ae", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRUCT)));
      metaDataMap = Collections.unmodifiableMap(tmpMap);
      org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(getDetailedExperimentTree_result.class, metaDataMap);
    }

    public getDetailedExperimentTree_result() {
    }

    public getDetailedExperimentTree_result(
      org.apache.airavata.model.experiment.ExperimentModel success,
      org.apache.airavata.model.error.InvalidRequestException ire,
      org.apache.airavata.model.error.ExperimentNotFoundException enf,
      org.apache.airavata.model.error.AiravataClientException ace,
      org.apache.airavata.model.error.AiravataSystemException ase,
      org.apache.airavata.model.error.AuthorizationException ae)
    {
      this();
      this.success = success;
      this.ire = ire;
      this.enf = enf;
      this.ace = ace;
      this.ase = ase;
      this.ae = ae;
    }

    /**
     * Performs a deep copy on <i>other</i>.
     */
    public getDetailedExperimentTree_result(getDetailedExperimentTree_result other) {
      if (other.isSetSuccess()) {
        this.success = new org.apache.airavata.model.experiment.ExperimentModel(other.success);
      }
      if (other.isSetIre()) {
        this.ire = new org.apache.airavata.model.error.InvalidRequestException(other.ire);
      }
      if (other.isSetEnf()) {
        this.enf = new org.apache.airavata.model.error.ExperimentNotFoundException(other.enf);
      }
      if (other.isSetAce()) {
        this.ace = new org.apache.airavata.model.error.AiravataClientException(other.ace);
      }
      if (other.isSetAse()) {
        this.ase = new org.apache.airavata.model.error.AiravataSystemException(other.ase);
      }
      if (other.isSetAe()) {
        this.ae = new org.apache.airavata.model.error.AuthorizationException(other.ae);
      }
    }

    public getDetailedExperimentTree_result deepCopy() {
      return new getDetailedExperimentTree_result(this);
    }

    @Override
    public void clear() {
      this.success = null;
      this.ire = null;
      this.enf = null;
      this.ace = null;
      this.ase = null;
      this.ae = null;
    }

    public org.apache.airavata.model.experiment.ExperimentModel getSuccess() {
      return this.success;
    }

    public getDetailedExperimentTree_result setSuccess(org.apache.airavata.model.experiment.ExperimentModel 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.model.error.InvalidRequestException getIre() {
      return this.ire;
    }

    public getDetailedExperimentTree_result setIre(org.apache.airavata.model.error.InvalidRequestException ire) {
      this.ire = ire;
      return this;
    }

    public void unsetIre() {
      this.ire = null;
    }

    /** Returns true if field ire is set (has been assigned a value) and false otherwise */
    public boolean isSetIre() {
      return this.ire != null;
    }

    public void setIreIsSet(boolean value) {
      if (!value) {
        this.ire = null;
      }
    }

    public org.apache.airavata.model.error.ExperimentNotFoundException getEnf() {
      return this.enf;
    }

    public getDetailedExperimentTree_result setEnf(org.apache.airavata.model.error.ExperimentNotFoundException enf) {
      this.enf = enf;
      return this;
    }

    public void unsetEnf() {
      this.enf = null;
    }

    /** Returns true if field enf is set (has been assigned a value) and false otherwise */
    public boolean isSetEnf() {
      return this.enf != null;
    }

    public void setEnfIsSet(boolean value) {
      if (!value) {
        this.enf = null;
      }
    }

    public org.apache.airavata.model.error.AiravataClientException getAce() {
      return this.ace;
    }

    public getDetailedExperimentTree_result setAce(org.apache.airavata.model.error.AiravataClientException ace) {
      this.ace = ace;
      return this;
    }

    public void unsetAce() {
      this.ace = null;
    }

    /** Returns true if field ace is set (has been assigned a value) and false otherwise */
    public boolean isSetAce() {
      return this.ace != null;
    }

    public void setAceIsSet(boolean value) {
      if (!value) {
        this.ace = null;
      }
    }

    public org.apache.airavata.model.error.AiravataSystemException getAse() {
      return this.ase;
    }

    public getDetailedExperimentTree_result setAse(org.apache.airavata.model.error.AiravataSystemException ase) {
      this.ase = ase;
      return this;
    }

    public void unsetAse() {
      this.ase = null;
    }

    /** Returns true if field ase is set (has been assigned a value) and false otherwise */
    public boolean isSetAse() {
      return this.ase != null;
    }

    public void setAseIsSet(boolean value) {
      if (!value) {
        this.ase = null;
      }
    }

    public org.apache.airavata.model.error.AuthorizationException getAe() {
      return this.ae;
    }

    public getDetailedExperimentTree_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, Object value) {
      switch (field) {
      case SUCCESS:
        if (value == null) {
          unsetSuccess();
        } else {
          setSuccess((org.apache.airavata.model.experiment.ExperimentModel)value);
        }
        break;

      case IRE:
        if (value == null) {
          unsetIre();
        } else {
          setIre((org.apache.airavata.model.error.InvalidRequestException)value);
        }
        break;

      case ENF:
        if (value == null) {
          unsetEnf();
        } else {
          setEnf((org.apache.airavata.model.error.ExperimentNotFoundException)value);
        }
        break;

      case ACE:
        if (value == null) {
          unsetAce();
        } else {
          setAce((org.apache.airavata.model.error.AiravataClientException)value);
        }
        break;

      case ASE:
        if (value == null) {
          unsetAse();
        } else {
          setAse((org.apache.airavata.model.error.AiravataSystemException)value);
        }
        break;

      case AE:
        if (value == null) {
          unsetAe();
        } else {
          setAe((org.apache.airavata.model.error.AuthorizationException)value);
        }
        break;

      }
    }

    public Object getFieldValue(_Fields field) {
      switch (field) {
      case SUCCESS:
        return getSuccess();

      case IRE:
        return getIre();

      case ENF:
        return getEnf();

      case ACE:
        return getAce();

      case ASE:
        return getAse();

      case AE:
        return getAe();

      }
      throw new IllegalStateException();
    }

    /** Returns true if field corresponding to fieldID is set (has been assigned a value) and false otherwise */
    public boolean isSet(_Fields field) {
      if (field == null) {
        throw new IllegalArgumentException();
      }

      switch (field) {
      case SUCCESS:
        return isSetSuccess();
      case IRE:
        return isSetIre();
      case ENF:
        return isSetEnf();
      case ACE:
        return isSetAce();
      case ASE:
        return isSetAse();
      case AE:
        return isSetAe();
      }
      throw new IllegalStateException();
    }

    @Override
    public boolean equals(Object that) {
      if (that == null)
        return false;
      if (that instanceof getDetailedExperimentTree_result)
        return this.equals((getDetailedExperimentTree_result)that);
      return false;
    }

    public boolean equals(getDetailedExperimentTree_result that) {
      if (that == null)
        return false;

      boolean this_present_success = true && this.isSetSuccess();
      boolean that_present_success = true && that.isSetSuccess();
      if (this_present_success || that_present_success) {
        if (!(this_present_success && that_present_success))
          return false;
        if (!this.success.equals(that.success))
          return false;
      }

      boolean this_present_ire = true && this.isSetIre();
      boolean that_present_ire = true && that.isSetIre();
      if (this_present_ire || that_present_ire) {
        if (!(this_present_ire && that_present_ire))
          return false;
        if (!this.ire.equals(that.ire))
          return false;
      }

      boolean this_present_enf = true && this.isSetEnf();
      boolean that_present_enf = true && that.isSetEnf();
      if (this_present_enf || that_present_enf) {
        if (!(this_present_enf && that_present_enf))
          return false;
        if (!this.enf.equals(that.enf))
          return false;
      }

      boolean this_present_ace = true && this.isSetAce();
      boolean that_present_ace = true && that.isSetAce();
      if (this_present_ace || that_present_ace) {
        if (!(this_present_ace && that_present_ace))
          return false;
        if (!this.ace.equals(that.ace))
          return false;
      }

      boolean this_present_ase = true && this.isSetAse();
      boolean that_present_ase = true && that.isSetAse();
      if (this_present_ase || that_present_ase) {
        if (!(this_present_ase && that_present_ase))
          return false;
        if (!this.ase.equals(that.ase))
          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() {
      List<Object> list = new ArrayList<Object>();

      boolean present_success = true && (isSetSuccess());
      list.add(present_success);
      if (present_success)
        list.add(success);

      boolean present_ire = true && (isSetIre());
      list.add(present_ire);
      if (present_ire)
        list.add(ire);

      boolean present_enf = true && (isSetEnf());
      list.add(present_enf);
      if (present_enf)
        list.add(enf);

      boolean present_ace = true && (isSetAce());
      list.add(present_ace);
      if (present_ace)
        list.add(ace);

      boolean present_ase = true && (isSetAse());
      list.add(present_ase);
      if (present_ase)
        list.add(ase);

      boolean present_ae = true && (isSetAe());
      list.add(present_ae);
      if (present_ae)
        list.add(ae);

      return list.hashCode();
    }

    @Override
    public int compareTo(getDetailedExperimentTree_result other) {
      if (!getClass().equals(other.getClass())) {
        return getClass().getName().compareTo(other.getClass().getName());
      }

      int lastComparison = 0;

      lastComparison = Boolean.valueOf(isSetSuccess()).compareTo(other.isSetSuccess());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetSuccess()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.success, other.success);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = Boolean.valueOf(isSetIre()).compareTo(other.isSetIre());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetIre()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.ire, other.ire);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = Boolean.valueOf(isSetEnf()).compareTo(other.isSetEnf());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetEnf()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.enf, other.enf);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = Boolean.valueOf(isSetAce()).compareTo(other.isSetAce());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetAce()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.ace, other.ace);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = Boolean.valueOf(isSetAse()).compareTo(other.isSetAse());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetAse()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.ase, other.ase);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = 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 {
      schemes.get(iprot.getScheme()).getScheme().read(iprot, this);
    }

    public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException {
      schemes.get(oprot.getScheme()).getScheme().write(oprot, this);
      }

    @Override
    public String toString() {
      StringBuilder sb = new StringBuilder("getDetailedExperimentTree_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("ire:");
      if (this.ire == null) {
        sb.append("null");
      } else {
        sb.append(this.ire);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("enf:");
      if (this.enf == null) {
        sb.append("null");
      } else {
        sb.append(this.enf);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("ace:");
      if (this.ace == null) {
        sb.append("null");
      } else {
        sb.append(this.ace);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("ase:");
      if (this.ase == null) {
        sb.append("null");
      } else {
        sb.append(this.ase);
      }
      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, 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 getDetailedExperimentTree_resultStandardSchemeFactory implements SchemeFactory {
      public getDetailedExperimentTree_resultStandardScheme getScheme() {
        return new getDetailedExperimentTree_resultStandardScheme();
      }
    }

    private static class getDetailedExperimentTree_resultStandardScheme extends StandardScheme<getDetailedExperimentTree_result> {

      public void read(org.apache.thrift.protocol.TProtocol iprot, getDetailedExperimentTree_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.experiment.ExperimentModel();
                struct.success.read(iprot);
                struct.setSuccessIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 1: // IRE
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.ire = new org.apache.airavata.model.error.InvalidRequestException();
                struct.ire.read(iprot);
                struct.setIreIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 2: // ENF
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.enf = new org.apache.airavata.model.error.ExperimentNotFoundException();
                struct.enf.read(iprot);
                struct.setEnfIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 3: // ACE
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.ace = new org.apache.airavata.model.error.AiravataClientException();
                struct.ace.read(iprot);
                struct.setAceIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 4: // ASE
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.ase = new org.apache.airavata.model.error.AiravataSystemException();
                struct.ase.read(iprot);
                struct.setAseIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 5: // 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, getDetailedExperimentTree_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.ire != null) {
          oprot.writeFieldBegin(IRE_FIELD_DESC);
          struct.ire.write(oprot);
          oprot.writeFieldEnd();
        }
        if (struct.enf != null) {
          oprot.writeFieldBegin(ENF_FIELD_DESC);
          struct.enf.write(oprot);
          oprot.writeFieldEnd();
        }
        if (struct.ace != null) {
          oprot.writeFieldBegin(ACE_FIELD_DESC);
          struct.ace.write(oprot);
          oprot.writeFieldEnd();
        }
        if (struct.ase != null) {
          oprot.writeFieldBegin(ASE_FIELD_DESC);
          struct.ase.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 getDetailedExperimentTree_resultTupleSchemeFactory implements SchemeFactory {
      public getDetailedExperimentTree_resultTupleScheme getScheme() {
        return new getDetailedExperimentTree_resultTupleScheme();
      }
    }

    private static class getDetailedExperimentTree_resultTupleScheme extends TupleScheme<getDetailedExperimentTree_result> {

      @Override
      public void write(org.apache.thrift.protocol.TProtocol prot, getDetailedExperimentTree_result struct) throws org.apache.thrift.TException {
        TTupleProtocol oprot = (TTupleProtocol) prot;
        BitSet optionals = new BitSet();
        if (struct.isSetSuccess()) {
          optionals.set(0);
        }
        if (struct.isSetIre()) {
          optionals.set(1);
        }
        if (struct.isSetEnf()) {
          optionals.set(2);
        }
        if (struct.isSetAce()) {
          optionals.set(3);
        }
        if (struct.isSetAse()) {
          optionals.set(4);
        }
        if (struct.isSetAe()) {
          optionals.set(5);
        }
        oprot.writeBitSet(optionals, 6);
        if (struct.isSetSuccess()) {
          struct.success.write(oprot);
        }
        if (struct.isSetIre()) {
          struct.ire.write(oprot);
        }
        if (struct.isSetEnf()) {
          struct.enf.write(oprot);
        }
        if (struct.isSetAce()) {
          struct.ace.write(oprot);
        }
        if (struct.isSetAse()) {
          struct.ase.write(oprot);
        }
        if (struct.isSetAe()) {
          struct.ae.write(oprot);
        }
      }

      @Override
      public void read(org.apache.thrift.protocol.TProtocol prot, getDetailedExperimentTree_result struct) throws org.apache.thrift.TException {
        TTupleProtocol iprot = (TTupleProtocol) prot;
        BitSet incoming = iprot.readBitSet(6);
        if (incoming.get(0)) {
          struct.success = new org.apache.airavata.model.experiment.ExperimentModel();
          struct.success.read(iprot);
          struct.setSuccessIsSet(true);
        }
        if (incoming.get(1)) {
          struct.ire = new org.apache.airavata.model.error.InvalidRequestException();
          struct.ire.read(iprot);
          struct.setIreIsSet(true);
        }
        if (incoming.get(2)) {
          struct.enf = new org.apache.airavata.model.error.ExperimentNotFoundException();
          struct.enf.read(iprot);
          struct.setEnfIsSet(true);
        }
        if (incoming.get(3)) {
          struct.ace = new org.apache.airavata.model.error.AiravataClientException();
          struct.ace.read(iprot);
          struct.setAceIsSet(true);
        }
        if (incoming.get(4)) {
          struct.ase = new org.apache.airavata.model.error.AiravataSystemException();
          struct.ase.read(iprot);
          struct.setAseIsSet(true);
        }
        if (incoming.get(5)) {
          struct.ae = new org.apache.airavata.model.error.AuthorizationException();
          struct.ae.read(iprot);
          struct.setAeIsSet(true);
        }
      }
    }

  }

  public static class updateExperiment_args implements org.apache.thrift.TBase<updateExperiment_args, updateExperiment_args._Fields>, java.io.Serializable, Cloneable, Comparable<updateExperiment_args>   {
    private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("updateExperiment_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_EXPERIMENT_ID_FIELD_DESC = new org.apache.thrift.protocol.TField("airavataExperimentId", org.apache.thrift.protocol.TType.STRING, (short)2);
    private static final org.apache.thrift.protocol.TField EXPERIMENT_FIELD_DESC = new org.apache.thrift.protocol.TField("experiment", org.apache.thrift.protocol.TType.STRUCT, (short)3);

    private static final Map<Class<? extends IScheme>, SchemeFactory> schemes = new HashMap<Class<? extends IScheme>, SchemeFactory>();
    static {
      schemes.put(StandardScheme.class, new updateExperiment_argsStandardSchemeFactory());
      schemes.put(TupleScheme.class, new updateExperiment_argsTupleSchemeFactory());
    }

    public org.apache.airavata.model.security.AuthzToken authzToken; // required
    public String airavataExperimentId; // required
    public org.apache.airavata.model.experiment.ExperimentModel experiment; // required

    /** 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_EXPERIMENT_ID((short)2, "airavataExperimentId"),
      EXPERIMENT((short)3, "experiment");

      private static final Map<String, _Fields> byName = new HashMap<String, _Fields>();

      static {
        for (_Fields field : EnumSet.allOf(_Fields.class)) {
          byName.put(field.getFieldName(), field);
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, or null if its not found.
       */
      public static _Fields findByThriftId(int fieldId) {
        switch(fieldId) {
          case 1: // AUTHZ_TOKEN
            return AUTHZ_TOKEN;
          case 2: // AIRAVATA_EXPERIMENT_ID
            return AIRAVATA_EXPERIMENT_ID;
          case 3: // EXPERIMENT
            return EXPERIMENT;
          default:
            return null;
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, throwing an exception
       * if it is not found.
       */
      public static _Fields findByThriftIdOrThrow(int fieldId) {
        _Fields fields = findByThriftId(fieldId);
        if (fields == null) throw new IllegalArgumentException("Field " + fieldId + " doesn't exist!");
        return fields;
      }

      /**
       * Find the _Fields constant that matches name, or null if its not found.
       */
      public static _Fields findByName(String name) {
        return byName.get(name);
      }

      private final short _thriftId;
      private final String _fieldName;

      _Fields(short thriftId, String fieldName) {
        _thriftId = thriftId;
        _fieldName = fieldName;
      }

      public short getThriftFieldId() {
        return _thriftId;
      }

      public String getFieldName() {
        return _fieldName;
      }
    }

    // isset id assignments
    public static final Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
    static {
      Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new EnumMap<_Fields, org.apache.thrift.meta_data.FieldMetaData>(_Fields.class);
      tmpMap.put(_Fields.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_EXPERIMENT_ID, new org.apache.thrift.meta_data.FieldMetaData("airavataExperimentId", org.apache.thrift.TFieldRequirementType.REQUIRED, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING)));
      tmpMap.put(_Fields.EXPERIMENT, new org.apache.thrift.meta_data.FieldMetaData("experiment", org.apache.thrift.TFieldRequirementType.REQUIRED, 
          new org.apache.thrift.meta_data.StructMetaData(org.apache.thrift.protocol.TType.STRUCT, org.apache.airavata.model.experiment.ExperimentModel.class)));
      metaDataMap = Collections.unmodifiableMap(tmpMap);
      org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(updateExperiment_args.class, metaDataMap);
    }

    public updateExperiment_args() {
    }

    public updateExperiment_args(
      org.apache.airavata.model.security.AuthzToken authzToken,
      String airavataExperimentId,
      org.apache.airavata.model.experiment.ExperimentModel experiment)
    {
      this();
      this.authzToken = authzToken;
      this.airavataExperimentId = airavataExperimentId;
      this.experiment = experiment;
    }

    /**
     * Performs a deep copy on <i>other</i>.
     */
    public updateExperiment_args(updateExperiment_args other) {
      if (other.isSetAuthzToken()) {
        this.authzToken = new org.apache.airavata.model.security.AuthzToken(other.authzToken);
      }
      if (other.isSetAiravataExperimentId()) {
        this.airavataExperimentId = other.airavataExperimentId;
      }
      if (other.isSetExperiment()) {
        this.experiment = new org.apache.airavata.model.experiment.ExperimentModel(other.experiment);
      }
    }

    public updateExperiment_args deepCopy() {
      return new updateExperiment_args(this);
    }

    @Override
    public void clear() {
      this.authzToken = null;
      this.airavataExperimentId = null;
      this.experiment = null;
    }

    public org.apache.airavata.model.security.AuthzToken getAuthzToken() {
      return this.authzToken;
    }

    public updateExperiment_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 String getAiravataExperimentId() {
      return this.airavataExperimentId;
    }

    public updateExperiment_args setAiravataExperimentId(String airavataExperimentId) {
      this.airavataExperimentId = airavataExperimentId;
      return this;
    }

    public void unsetAiravataExperimentId() {
      this.airavataExperimentId = null;
    }

    /** Returns true if field airavataExperimentId is set (has been assigned a value) and false otherwise */
    public boolean isSetAiravataExperimentId() {
      return this.airavataExperimentId != null;
    }

    public void setAiravataExperimentIdIsSet(boolean value) {
      if (!value) {
        this.airavataExperimentId = null;
      }
    }

    public org.apache.airavata.model.experiment.ExperimentModel getExperiment() {
      return this.experiment;
    }

    public updateExperiment_args setExperiment(org.apache.airavata.model.experiment.ExperimentModel experiment) {
      this.experiment = experiment;
      return this;
    }

    public void unsetExperiment() {
      this.experiment = null;
    }

    /** Returns true if field experiment is set (has been assigned a value) and false otherwise */
    public boolean isSetExperiment() {
      return this.experiment != null;
    }

    public void setExperimentIsSet(boolean value) {
      if (!value) {
        this.experiment = null;
      }
    }

    public void setFieldValue(_Fields field, Object value) {
      switch (field) {
      case AUTHZ_TOKEN:
        if (value == null) {
          unsetAuthzToken();
        } else {
          setAuthzToken((org.apache.airavata.model.security.AuthzToken)value);
        }
        break;

      case AIRAVATA_EXPERIMENT_ID:
        if (value == null) {
          unsetAiravataExperimentId();
        } else {
          setAiravataExperimentId((String)value);
        }
        break;

      case EXPERIMENT:
        if (value == null) {
          unsetExperiment();
        } else {
          setExperiment((org.apache.airavata.model.experiment.ExperimentModel)value);
        }
        break;

      }
    }

    public Object getFieldValue(_Fields field) {
      switch (field) {
      case AUTHZ_TOKEN:
        return getAuthzToken();

      case AIRAVATA_EXPERIMENT_ID:
        return getAiravataExperimentId();

      case EXPERIMENT:
        return getExperiment();

      }
      throw new IllegalStateException();
    }

    /** Returns true if field corresponding to fieldID is set (has been assigned a value) and false otherwise */
    public boolean isSet(_Fields field) {
      if (field == null) {
        throw new IllegalArgumentException();
      }

      switch (field) {
      case AUTHZ_TOKEN:
        return isSetAuthzToken();
      case AIRAVATA_EXPERIMENT_ID:
        return isSetAiravataExperimentId();
      case EXPERIMENT:
        return isSetExperiment();
      }
      throw new IllegalStateException();
    }

    @Override
    public boolean equals(Object that) {
      if (that == null)
        return false;
      if (that instanceof updateExperiment_args)
        return this.equals((updateExperiment_args)that);
      return false;
    }

    public boolean equals(updateExperiment_args that) {
      if (that == null)
        return false;

      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_airavataExperimentId = true && this.isSetAiravataExperimentId();
      boolean that_present_airavataExperimentId = true && that.isSetAiravataExperimentId();
      if (this_present_airavataExperimentId || that_present_airavataExperimentId) {
        if (!(this_present_airavataExperimentId && that_present_airavataExperimentId))
          return false;
        if (!this.airavataExperimentId.equals(that.airavataExperimentId))
          return false;
      }

      boolean this_present_experiment = true && this.isSetExperiment();
      boolean that_present_experiment = true && that.isSetExperiment();
      if (this_present_experiment || that_present_experiment) {
        if (!(this_present_experiment && that_present_experiment))
          return false;
        if (!this.experiment.equals(that.experiment))
          return false;
      }

      return true;
    }

    @Override
    public int hashCode() {
      List<Object> list = new ArrayList<Object>();

      boolean present_authzToken = true && (isSetAuthzToken());
      list.add(present_authzToken);
      if (present_authzToken)
        list.add(authzToken);

      boolean present_airavataExperimentId = true && (isSetAiravataExperimentId());
      list.add(present_airavataExperimentId);
      if (present_airavataExperimentId)
        list.add(airavataExperimentId);

      boolean present_experiment = true && (isSetExperiment());
      list.add(present_experiment);
      if (present_experiment)
        list.add(experiment);

      return list.hashCode();
    }

    @Override
    public int compareTo(updateExperiment_args other) {
      if (!getClass().equals(other.getClass())) {
        return getClass().getName().compareTo(other.getClass().getName());
      }

      int lastComparison = 0;

      lastComparison = 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 = Boolean.valueOf(isSetAiravataExperimentId()).compareTo(other.isSetAiravataExperimentId());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetAiravataExperimentId()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.airavataExperimentId, other.airavataExperimentId);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = Boolean.valueOf(isSetExperiment()).compareTo(other.isSetExperiment());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetExperiment()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.experiment, other.experiment);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      return 0;
    }

    public _Fields fieldForId(int fieldId) {
      return _Fields.findByThriftId(fieldId);
    }

    public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
      schemes.get(iprot.getScheme()).getScheme().read(iprot, this);
    }

    public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException {
      schemes.get(oprot.getScheme()).getScheme().write(oprot, this);
    }

    @Override
    public String toString() {
      StringBuilder sb = new StringBuilder("updateExperiment_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("airavataExperimentId:");
      if (this.airavataExperimentId == null) {
        sb.append("null");
      } else {
        sb.append(this.airavataExperimentId);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("experiment:");
      if (this.experiment == null) {
        sb.append("null");
      } else {
        sb.append(this.experiment);
      }
      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 (airavataExperimentId == null) {
        throw new org.apache.thrift.protocol.TProtocolException("Required field 'airavataExperimentId' was not present! Struct: " + toString());
      }
      if (experiment == null) {
        throw new org.apache.thrift.protocol.TProtocolException("Required field 'experiment' was not present! Struct: " + toString());
      }
      // check for sub-struct validity
      if (authzToken != null) {
        authzToken.validate();
      }
      if (experiment != null) {
        experiment.validate();
      }
    }

    private void writeObject(java.io.ObjectOutputStream out) throws java.io.IOException {
      try {
        write(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(out)));
      } catch (org.apache.thrift.TException te) {
        throw new java.io.IOException(te);
      }
    }

    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, ClassNotFoundException {
      try {
        read(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(in)));
      } catch (org.apache.thrift.TException te) {
        throw new java.io.IOException(te);
      }
    }

    private static class updateExperiment_argsStandardSchemeFactory implements SchemeFactory {
      public updateExperiment_argsStandardScheme getScheme() {
        return new updateExperiment_argsStandardScheme();
      }
    }

    private static class updateExperiment_argsStandardScheme extends StandardScheme<updateExperiment_args> {

      public void read(org.apache.thrift.protocol.TProtocol iprot, updateExperiment_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_EXPERIMENT_ID
              if (schemeField.type == org.apache.thrift.protocol.TType.STRING) {
                struct.airavataExperimentId = iprot.readString();
                struct.setAiravataExperimentIdIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 3: // EXPERIMENT
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.experiment = new org.apache.airavata.model.experiment.ExperimentModel();
                struct.experiment.read(iprot);
                struct.setExperimentIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            default:
              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
          }
          iprot.readFieldEnd();
        }
        iprot.readStructEnd();

        // check for required fields of primitive type, which can't be checked in the validate method
        struct.validate();
      }

      public void write(org.apache.thrift.protocol.TProtocol oprot, updateExperiment_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.airavataExperimentId != null) {
          oprot.writeFieldBegin(AIRAVATA_EXPERIMENT_ID_FIELD_DESC);
          oprot.writeString(struct.airavataExperimentId);
          oprot.writeFieldEnd();
        }
        if (struct.experiment != null) {
          oprot.writeFieldBegin(EXPERIMENT_FIELD_DESC);
          struct.experiment.write(oprot);
          oprot.writeFieldEnd();
        }
        oprot.writeFieldStop();
        oprot.writeStructEnd();
      }

    }

    private static class updateExperiment_argsTupleSchemeFactory implements SchemeFactory {
      public updateExperiment_argsTupleScheme getScheme() {
        return new updateExperiment_argsTupleScheme();
      }
    }

    private static class updateExperiment_argsTupleScheme extends TupleScheme<updateExperiment_args> {

      @Override
      public void write(org.apache.thrift.protocol.TProtocol prot, updateExperiment_args struct) throws org.apache.thrift.TException {
        TTupleProtocol oprot = (TTupleProtocol) prot;
        struct.authzToken.write(oprot);
        oprot.writeString(struct.airavataExperimentId);
        struct.experiment.write(oprot);
      }

      @Override
      public void read(org.apache.thrift.protocol.TProtocol prot, updateExperiment_args struct) throws org.apache.thrift.TException {
        TTupleProtocol iprot = (TTupleProtocol) prot;
        struct.authzToken = new org.apache.airavata.model.security.AuthzToken();
        struct.authzToken.read(iprot);
        struct.setAuthzTokenIsSet(true);
        struct.airavataExperimentId = iprot.readString();
        struct.setAiravataExperimentIdIsSet(true);
        struct.experiment = new org.apache.airavata.model.experiment.ExperimentModel();
        struct.experiment.read(iprot);
        struct.setExperimentIsSet(true);
      }
    }

  }

  public static class updateExperiment_result implements org.apache.thrift.TBase<updateExperiment_result, updateExperiment_result._Fields>, java.io.Serializable, Cloneable, Comparable<updateExperiment_result>   {
    private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("updateExperiment_result");

    private static final org.apache.thrift.protocol.TField IRE_FIELD_DESC = new org.apache.thrift.protocol.TField("ire", org.apache.thrift.protocol.TType.STRUCT, (short)1);
    private static final org.apache.thrift.protocol.TField ENF_FIELD_DESC = new org.apache.thrift.protocol.TField("enf", org.apache.thrift.protocol.TType.STRUCT, (short)2);
    private static final org.apache.thrift.protocol.TField ACE_FIELD_DESC = new org.apache.thrift.protocol.TField("ace", org.apache.thrift.protocol.TType.STRUCT, (short)3);
    private static final org.apache.thrift.protocol.TField ASE_FIELD_DESC = new org.apache.thrift.protocol.TField("ase", org.apache.thrift.protocol.TType.STRUCT, (short)4);
    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)5);

    private static final Map<Class<? extends IScheme>, SchemeFactory> schemes = new HashMap<Class<? extends IScheme>, SchemeFactory>();
    static {
      schemes.put(StandardScheme.class, new updateExperiment_resultStandardSchemeFactory());
      schemes.put(TupleScheme.class, new updateExperiment_resultTupleSchemeFactory());
    }

    public org.apache.airavata.model.error.InvalidRequestException ire; // required
    public org.apache.airavata.model.error.ExperimentNotFoundException enf; // required
    public org.apache.airavata.model.error.AiravataClientException ace; // required
    public org.apache.airavata.model.error.AiravataSystemException ase; // 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 {
      IRE((short)1, "ire"),
      ENF((short)2, "enf"),
      ACE((short)3, "ace"),
      ASE((short)4, "ase"),
      AE((short)5, "ae");

      private static final Map<String, _Fields> byName = new HashMap<String, _Fields>();

      static {
        for (_Fields field : EnumSet.allOf(_Fields.class)) {
          byName.put(field.getFieldName(), field);
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, or null if its not found.
       */
      public static _Fields findByThriftId(int fieldId) {
        switch(fieldId) {
          case 1: // IRE
            return IRE;
          case 2: // ENF
            return ENF;
          case 3: // ACE
            return ACE;
          case 4: // ASE
            return ASE;
          case 5: // 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 IllegalArgumentException("Field " + fieldId + " doesn't exist!");
        return fields;
      }

      /**
       * Find the _Fields constant that matches name, or null if its not found.
       */
      public static _Fields findByName(String name) {
        return byName.get(name);
      }

      private final short _thriftId;
      private final String _fieldName;

      _Fields(short thriftId, String fieldName) {
        _thriftId = thriftId;
        _fieldName = fieldName;
      }

      public short getThriftFieldId() {
        return _thriftId;
      }

      public String getFieldName() {
        return _fieldName;
      }
    }

    // isset id assignments
    public static final Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
    static {
      Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new EnumMap<_Fields, org.apache.thrift.meta_data.FieldMetaData>(_Fields.class);
      tmpMap.put(_Fields.IRE, new org.apache.thrift.meta_data.FieldMetaData("ire", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRUCT)));
      tmpMap.put(_Fields.ENF, new org.apache.thrift.meta_data.FieldMetaData("enf", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRUCT)));
      tmpMap.put(_Fields.ACE, new org.apache.thrift.meta_data.FieldMetaData("ace", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRUCT)));
      tmpMap.put(_Fields.ASE, new org.apache.thrift.meta_data.FieldMetaData("ase", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRUCT)));
      tmpMap.put(_Fields.AE, new org.apache.thrift.meta_data.FieldMetaData("ae", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRUCT)));
      metaDataMap = Collections.unmodifiableMap(tmpMap);
      org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(updateExperiment_result.class, metaDataMap);
    }

    public updateExperiment_result() {
    }

    public updateExperiment_result(
      org.apache.airavata.model.error.InvalidRequestException ire,
      org.apache.airavata.model.error.ExperimentNotFoundException enf,
      org.apache.airavata.model.error.AiravataClientException ace,
      org.apache.airavata.model.error.AiravataSystemException ase,
      org.apache.airavata.model.error.AuthorizationException ae)
    {
      this();
      this.ire = ire;
      this.enf = enf;
      this.ace = ace;
      this.ase = ase;
      this.ae = ae;
    }

    /**
     * Performs a deep copy on <i>other</i>.
     */
    public updateExperiment_result(updateExperiment_result other) {
      if (other.isSetIre()) {
        this.ire = new org.apache.airavata.model.error.InvalidRequestException(other.ire);
      }
      if (other.isSetEnf()) {
        this.enf = new org.apache.airavata.model.error.ExperimentNotFoundException(other.enf);
      }
      if (other.isSetAce()) {
        this.ace = new org.apache.airavata.model.error.AiravataClientException(other.ace);
      }
      if (other.isSetAse()) {
        this.ase = new org.apache.airavata.model.error.AiravataSystemException(other.ase);
      }
      if (other.isSetAe()) {
        this.ae = new org.apache.airavata.model.error.AuthorizationException(other.ae);
      }
    }

    public updateExperiment_result deepCopy() {
      return new updateExperiment_result(this);
    }

    @Override
    public void clear() {
      this.ire = null;
      this.enf = null;
      this.ace = null;
      this.ase = null;
      this.ae = null;
    }

    public org.apache.airavata.model.error.InvalidRequestException getIre() {
      return this.ire;
    }

    public updateExperiment_result setIre(org.apache.airavata.model.error.InvalidRequestException ire) {
      this.ire = ire;
      return this;
    }

    public void unsetIre() {
      this.ire = null;
    }

    /** Returns true if field ire is set (has been assigned a value) and false otherwise */
    public boolean isSetIre() {
      return this.ire != null;
    }

    public void setIreIsSet(boolean value) {
      if (!value) {
        this.ire = null;
      }
    }

    public org.apache.airavata.model.error.ExperimentNotFoundException getEnf() {
      return this.enf;
    }

    public updateExperiment_result setEnf(org.apache.airavata.model.error.ExperimentNotFoundException enf) {
      this.enf = enf;
      return this;
    }

    public void unsetEnf() {
      this.enf = null;
    }

    /** Returns true if field enf is set (has been assigned a value) and false otherwise */
    public boolean isSetEnf() {
      return this.enf != null;
    }

    public void setEnfIsSet(boolean value) {
      if (!value) {
        this.enf = null;
      }
    }

    public org.apache.airavata.model.error.AiravataClientException getAce() {
      return this.ace;
    }

    public updateExperiment_result setAce(org.apache.airavata.model.error.AiravataClientException ace) {
      this.ace = ace;
      return this;
    }

    public void unsetAce() {
      this.ace = null;
    }

    /** Returns true if field ace is set (has been assigned a value) and false otherwise */
    public boolean isSetAce() {
      return this.ace != null;
    }

    public void setAceIsSet(boolean value) {
      if (!value) {
        this.ace = null;
      }
    }

    public org.apache.airavata.model.error.AiravataSystemException getAse() {
      return this.ase;
    }

    public updateExperiment_result setAse(org.apache.airavata.model.error.AiravataSystemException ase) {
      this.ase = ase;
      return this;
    }

    public void unsetAse() {
      this.ase = null;
    }

    /** Returns true if field ase is set (has been assigned a value) and false otherwise */
    public boolean isSetAse() {
      return this.ase != null;
    }

    public void setAseIsSet(boolean value) {
      if (!value) {
        this.ase = null;
      }
    }

    public org.apache.airavata.model.error.AuthorizationException getAe() {
      return this.ae;
    }

    public updateExperiment_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, Object value) {
      switch (field) {
      case IRE:
        if (value == null) {
          unsetIre();
        } else {
          setIre((org.apache.airavata.model.error.InvalidRequestException)value);
        }
        break;

      case ENF:
        if (value == null) {
          unsetEnf();
        } else {
          setEnf((org.apache.airavata.model.error.ExperimentNotFoundException)value);
        }
        break;

      case ACE:
        if (value == null) {
          unsetAce();
        } else {
          setAce((org.apache.airavata.model.error.AiravataClientException)value);
        }
        break;

      case ASE:
        if (value == null) {
          unsetAse();
        } else {
          setAse((org.apache.airavata.model.error.AiravataSystemException)value);
        }
        break;

      case AE:
        if (value == null) {
          unsetAe();
        } else {
          setAe((org.apache.airavata.model.error.AuthorizationException)value);
        }
        break;

      }
    }

    public Object getFieldValue(_Fields field) {
      switch (field) {
      case IRE:
        return getIre();

      case ENF:
        return getEnf();

      case ACE:
        return getAce();

      case ASE:
        return getAse();

      case AE:
        return getAe();

      }
      throw new IllegalStateException();
    }

    /** Returns true if field corresponding to fieldID is set (has been assigned a value) and false otherwise */
    public boolean isSet(_Fields field) {
      if (field == null) {
        throw new IllegalArgumentException();
      }

      switch (field) {
      case IRE:
        return isSetIre();
      case ENF:
        return isSetEnf();
      case ACE:
        return isSetAce();
      case ASE:
        return isSetAse();
      case AE:
        return isSetAe();
      }
      throw new IllegalStateException();
    }

    @Override
    public boolean equals(Object that) {
      if (that == null)
        return false;
      if (that instanceof updateExperiment_result)
        return this.equals((updateExperiment_result)that);
      return false;
    }

    public boolean equals(updateExperiment_result that) {
      if (that == null)
        return false;

      boolean this_present_ire = true && this.isSetIre();
      boolean that_present_ire = true && that.isSetIre();
      if (this_present_ire || that_present_ire) {
        if (!(this_present_ire && that_present_ire))
          return false;
        if (!this.ire.equals(that.ire))
          return false;
      }

      boolean this_present_enf = true && this.isSetEnf();
      boolean that_present_enf = true && that.isSetEnf();
      if (this_present_enf || that_present_enf) {
        if (!(this_present_enf && that_present_enf))
          return false;
        if (!this.enf.equals(that.enf))
          return false;
      }

      boolean this_present_ace = true && this.isSetAce();
      boolean that_present_ace = true && that.isSetAce();
      if (this_present_ace || that_present_ace) {
        if (!(this_present_ace && that_present_ace))
          return false;
        if (!this.ace.equals(that.ace))
          return false;
      }

      boolean this_present_ase = true && this.isSetAse();
      boolean that_present_ase = true && that.isSetAse();
      if (this_present_ase || that_present_ase) {
        if (!(this_present_ase && that_present_ase))
          return false;
        if (!this.ase.equals(that.ase))
          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() {
      List<Object> list = new ArrayList<Object>();

      boolean present_ire = true && (isSetIre());
      list.add(present_ire);
      if (present_ire)
        list.add(ire);

      boolean present_enf = true && (isSetEnf());
      list.add(present_enf);
      if (present_enf)
        list.add(enf);

      boolean present_ace = true && (isSetAce());
      list.add(present_ace);
      if (present_ace)
        list.add(ace);

      boolean present_ase = true && (isSetAse());
      list.add(present_ase);
      if (present_ase)
        list.add(ase);

      boolean present_ae = true && (isSetAe());
      list.add(present_ae);
      if (present_ae)
        list.add(ae);

      return list.hashCode();
    }

    @Override
    public int compareTo(updateExperiment_result other) {
      if (!getClass().equals(other.getClass())) {
        return getClass().getName().compareTo(other.getClass().getName());
      }

      int lastComparison = 0;

      lastComparison = Boolean.valueOf(isSetIre()).compareTo(other.isSetIre());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetIre()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.ire, other.ire);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = Boolean.valueOf(isSetEnf()).compareTo(other.isSetEnf());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetEnf()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.enf, other.enf);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = Boolean.valueOf(isSetAce()).compareTo(other.isSetAce());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetAce()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.ace, other.ace);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = Boolean.valueOf(isSetAse()).compareTo(other.isSetAse());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetAse()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.ase, other.ase);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = 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 {
      schemes.get(iprot.getScheme()).getScheme().read(iprot, this);
    }

    public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException {
      schemes.get(oprot.getScheme()).getScheme().write(oprot, this);
      }

    @Override
    public String toString() {
      StringBuilder sb = new StringBuilder("updateExperiment_result(");
      boolean first = true;

      sb.append("ire:");
      if (this.ire == null) {
        sb.append("null");
      } else {
        sb.append(this.ire);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("enf:");
      if (this.enf == null) {
        sb.append("null");
      } else {
        sb.append(this.enf);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("ace:");
      if (this.ace == null) {
        sb.append("null");
      } else {
        sb.append(this.ace);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("ase:");
      if (this.ase == null) {
        sb.append("null");
      } else {
        sb.append(this.ase);
      }
      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, 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 updateExperiment_resultStandardSchemeFactory implements SchemeFactory {
      public updateExperiment_resultStandardScheme getScheme() {
        return new updateExperiment_resultStandardScheme();
      }
    }

    private static class updateExperiment_resultStandardScheme extends StandardScheme<updateExperiment_result> {

      public void read(org.apache.thrift.protocol.TProtocol iprot, updateExperiment_result struct) throws org.apache.thrift.TException {
        org.apache.thrift.protocol.TField schemeField;
        iprot.readStructBegin();
        while (true)
        {
          schemeField = iprot.readFieldBegin();
          if (schemeField.type == org.apache.thrift.protocol.TType.STOP) { 
            break;
          }
          switch (schemeField.id) {
            case 1: // IRE
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.ire = new org.apache.airavata.model.error.InvalidRequestException();
                struct.ire.read(iprot);
                struct.setIreIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 2: // ENF
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.enf = new org.apache.airavata.model.error.ExperimentNotFoundException();
                struct.enf.read(iprot);
                struct.setEnfIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 3: // ACE
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.ace = new org.apache.airavata.model.error.AiravataClientException();
                struct.ace.read(iprot);
                struct.setAceIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 4: // ASE
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.ase = new org.apache.airavata.model.error.AiravataSystemException();
                struct.ase.read(iprot);
                struct.setAseIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 5: // 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, updateExperiment_result struct) throws org.apache.thrift.TException {
        struct.validate();

        oprot.writeStructBegin(STRUCT_DESC);
        if (struct.ire != null) {
          oprot.writeFieldBegin(IRE_FIELD_DESC);
          struct.ire.write(oprot);
          oprot.writeFieldEnd();
        }
        if (struct.enf != null) {
          oprot.writeFieldBegin(ENF_FIELD_DESC);
          struct.enf.write(oprot);
          oprot.writeFieldEnd();
        }
        if (struct.ace != null) {
          oprot.writeFieldBegin(ACE_FIELD_DESC);
          struct.ace.write(oprot);
          oprot.writeFieldEnd();
        }
        if (struct.ase != null) {
          oprot.writeFieldBegin(ASE_FIELD_DESC);
          struct.ase.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 updateExperiment_resultTupleSchemeFactory implements SchemeFactory {
      public updateExperiment_resultTupleScheme getScheme() {
        return new updateExperiment_resultTupleScheme();
      }
    }

    private static class updateExperiment_resultTupleScheme extends TupleScheme<updateExperiment_result> {

      @Override
      public void write(org.apache.thrift.protocol.TProtocol prot, updateExperiment_result struct) throws org.apache.thrift.TException {
        TTupleProtocol oprot = (TTupleProtocol) prot;
        BitSet optionals = new BitSet();
        if (struct.isSetIre()) {
          optionals.set(0);
        }
        if (struct.isSetEnf()) {
          optionals.set(1);
        }
        if (struct.isSetAce()) {
          optionals.set(2);
        }
        if (struct.isSetAse()) {
          optionals.set(3);
        }
        if (struct.isSetAe()) {
          optionals.set(4);
        }
        oprot.writeBitSet(optionals, 5);
        if (struct.isSetIre()) {
          struct.ire.write(oprot);
        }
        if (struct.isSetEnf()) {
          struct.enf.write(oprot);
        }
        if (struct.isSetAce()) {
          struct.ace.write(oprot);
        }
        if (struct.isSetAse()) {
          struct.ase.write(oprot);
        }
        if (struct.isSetAe()) {
          struct.ae.write(oprot);
        }
      }

      @Override
      public void read(org.apache.thrift.protocol.TProtocol prot, updateExperiment_result struct) throws org.apache.thrift.TException {
        TTupleProtocol iprot = (TTupleProtocol) prot;
        BitSet incoming = iprot.readBitSet(5);
        if (incoming.get(0)) {
          struct.ire = new org.apache.airavata.model.error.InvalidRequestException();
          struct.ire.read(iprot);
          struct.setIreIsSet(true);
        }
        if (incoming.get(1)) {
          struct.enf = new org.apache.airavata.model.error.ExperimentNotFoundException();
          struct.enf.read(iprot);
          struct.setEnfIsSet(true);
        }
        if (incoming.get(2)) {
          struct.ace = new org.apache.airavata.model.error.AiravataClientException();
          struct.ace.read(iprot);
          struct.setAceIsSet(true);
        }
        if (incoming.get(3)) {
          struct.ase = new org.apache.airavata.model.error.AiravataSystemException();
          struct.ase.read(iprot);
          struct.setAseIsSet(true);
        }
        if (incoming.get(4)) {
          struct.ae = new org.apache.airavata.model.error.AuthorizationException();
          struct.ae.read(iprot);
          struct.setAeIsSet(true);
        }
      }
    }

  }

  public static class updateExperimentConfiguration_args implements org.apache.thrift.TBase<updateExperimentConfiguration_args, updateExperimentConfiguration_args._Fields>, java.io.Serializable, Cloneable, Comparable<updateExperimentConfiguration_args>   {
    private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("updateExperimentConfiguration_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_EXPERIMENT_ID_FIELD_DESC = new org.apache.thrift.protocol.TField("airavataExperimentId", org.apache.thrift.protocol.TType.STRING, (short)2);
    private static final org.apache.thrift.protocol.TField USER_CONFIGURATION_FIELD_DESC = new org.apache.thrift.protocol.TField("userConfiguration", org.apache.thrift.protocol.TType.STRUCT, (short)3);

    private static final Map<Class<? extends IScheme>, SchemeFactory> schemes = new HashMap<Class<? extends IScheme>, SchemeFactory>();
    static {
      schemes.put(StandardScheme.class, new updateExperimentConfiguration_argsStandardSchemeFactory());
      schemes.put(TupleScheme.class, new updateExperimentConfiguration_argsTupleSchemeFactory());
    }

    public org.apache.airavata.model.security.AuthzToken authzToken; // required
    public String airavataExperimentId; // required
    public org.apache.airavata.model.experiment.UserConfigurationDataModel userConfiguration; // required

    /** 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_EXPERIMENT_ID((short)2, "airavataExperimentId"),
      USER_CONFIGURATION((short)3, "userConfiguration");

      private static final Map<String, _Fields> byName = new HashMap<String, _Fields>();

      static {
        for (_Fields field : EnumSet.allOf(_Fields.class)) {
          byName.put(field.getFieldName(), field);
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, or null if its not found.
       */
      public static _Fields findByThriftId(int fieldId) {
        switch(fieldId) {
          case 1: // AUTHZ_TOKEN
            return AUTHZ_TOKEN;
          case 2: // AIRAVATA_EXPERIMENT_ID
            return AIRAVATA_EXPERIMENT_ID;
          case 3: // USER_CONFIGURATION
            return USER_CONFIGURATION;
          default:
            return null;
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, throwing an exception
       * if it is not found.
       */
      public static _Fields findByThriftIdOrThrow(int fieldId) {
        _Fields fields = findByThriftId(fieldId);
        if (fields == null) throw new IllegalArgumentException("Field " + fieldId + " doesn't exist!");
        return fields;
      }

      /**
       * Find the _Fields constant that matches name, or null if its not found.
       */
      public static _Fields findByName(String name) {
        return byName.get(name);
      }

      private final short _thriftId;
      private final String _fieldName;

      _Fields(short thriftId, String fieldName) {
        _thriftId = thriftId;
        _fieldName = fieldName;
      }

      public short getThriftFieldId() {
        return _thriftId;
      }

      public String getFieldName() {
        return _fieldName;
      }
    }

    // isset id assignments
    public static final Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
    static {
      Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new EnumMap<_Fields, org.apache.thrift.meta_data.FieldMetaData>(_Fields.class);
      tmpMap.put(_Fields.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_EXPERIMENT_ID, new org.apache.thrift.meta_data.FieldMetaData("airavataExperimentId", org.apache.thrift.TFieldRequirementType.REQUIRED, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING)));
      tmpMap.put(_Fields.USER_CONFIGURATION, new org.apache.thrift.meta_data.FieldMetaData("userConfiguration", org.apache.thrift.TFieldRequirementType.REQUIRED, 
          new org.apache.thrift.meta_data.StructMetaData(org.apache.thrift.protocol.TType.STRUCT, org.apache.airavata.model.experiment.UserConfigurationDataModel.class)));
      metaDataMap = Collections.unmodifiableMap(tmpMap);
      org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(updateExperimentConfiguration_args.class, metaDataMap);
    }

    public updateExperimentConfiguration_args() {
    }

    public updateExperimentConfiguration_args(
      org.apache.airavata.model.security.AuthzToken authzToken,
      String airavataExperimentId,
      org.apache.airavata.model.experiment.UserConfigurationDataModel userConfiguration)
    {
      this();
      this.authzToken = authzToken;
      this.airavataExperimentId = airavataExperimentId;
      this.userConfiguration = userConfiguration;
    }

    /**
     * Performs a deep copy on <i>other</i>.
     */
    public updateExperimentConfiguration_args(updateExperimentConfiguration_args other) {
      if (other.isSetAuthzToken()) {
        this.authzToken = new org.apache.airavata.model.security.AuthzToken(other.authzToken);
      }
      if (other.isSetAiravataExperimentId()) {
        this.airavataExperimentId = other.airavataExperimentId;
      }
      if (other.isSetUserConfiguration()) {
        this.userConfiguration = new org.apache.airavata.model.experiment.UserConfigurationDataModel(other.userConfiguration);
      }
    }

    public updateExperimentConfiguration_args deepCopy() {
      return new updateExperimentConfiguration_args(this);
    }

    @Override
    public void clear() {
      this.authzToken = null;
      this.airavataExperimentId = null;
      this.userConfiguration = null;
    }

    public org.apache.airavata.model.security.AuthzToken getAuthzToken() {
      return this.authzToken;
    }

    public updateExperimentConfiguration_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 String getAiravataExperimentId() {
      return this.airavataExperimentId;
    }

    public updateExperimentConfiguration_args setAiravataExperimentId(String airavataExperimentId) {
      this.airavataExperimentId = airavataExperimentId;
      return this;
    }

    public void unsetAiravataExperimentId() {
      this.airavataExperimentId = null;
    }

    /** Returns true if field airavataExperimentId is set (has been assigned a value) and false otherwise */
    public boolean isSetAiravataExperimentId() {
      return this.airavataExperimentId != null;
    }

    public void setAiravataExperimentIdIsSet(boolean value) {
      if (!value) {
        this.airavataExperimentId = null;
      }
    }

    public org.apache.airavata.model.experiment.UserConfigurationDataModel getUserConfiguration() {
      return this.userConfiguration;
    }

    public updateExperimentConfiguration_args setUserConfiguration(org.apache.airavata.model.experiment.UserConfigurationDataModel userConfiguration) {
      this.userConfiguration = userConfiguration;
      return this;
    }

    public void unsetUserConfiguration() {
      this.userConfiguration = null;
    }

    /** Returns true if field userConfiguration is set (has been assigned a value) and false otherwise */
    public boolean isSetUserConfiguration() {
      return this.userConfiguration != null;
    }

    public void setUserConfigurationIsSet(boolean value) {
      if (!value) {
        this.userConfiguration = null;
      }
    }

    public void setFieldValue(_Fields field, Object value) {
      switch (field) {
      case AUTHZ_TOKEN:
        if (value == null) {
          unsetAuthzToken();
        } else {
          setAuthzToken((org.apache.airavata.model.security.AuthzToken)value);
        }
        break;

      case AIRAVATA_EXPERIMENT_ID:
        if (value == null) {
          unsetAiravataExperimentId();
        } else {
          setAiravataExperimentId((String)value);
        }
        break;

      case USER_CONFIGURATION:
        if (value == null) {
          unsetUserConfiguration();
        } else {
          setUserConfiguration((org.apache.airavata.model.experiment.UserConfigurationDataModel)value);
        }
        break;

      }
    }

    public Object getFieldValue(_Fields field) {
      switch (field) {
      case AUTHZ_TOKEN:
        return getAuthzToken();

      case AIRAVATA_EXPERIMENT_ID:
        return getAiravataExperimentId();

      case USER_CONFIGURATION:
        return getUserConfiguration();

      }
      throw new IllegalStateException();
    }

    /** Returns true if field corresponding to fieldID is set (has been assigned a value) and false otherwise */
    public boolean isSet(_Fields field) {
      if (field == null) {
        throw new IllegalArgumentException();
      }

      switch (field) {
      case AUTHZ_TOKEN:
        return isSetAuthzToken();
      case AIRAVATA_EXPERIMENT_ID:
        return isSetAiravataExperimentId();
      case USER_CONFIGURATION:
        return isSetUserConfiguration();
      }
      throw new IllegalStateException();
    }

    @Override
    public boolean equals(Object that) {
      if (that == null)
        return false;
      if (that instanceof updateExperimentConfiguration_args)
        return this.equals((updateExperimentConfiguration_args)that);
      return false;
    }

    public boolean equals(updateExperimentConfiguration_args that) {
      if (that == null)
        return false;

      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_airavataExperimentId = true && this.isSetAiravataExperimentId();
      boolean that_present_airavataExperimentId = true && that.isSetAiravataExperimentId();
      if (this_present_airavataExperimentId || that_present_airavataExperimentId) {
        if (!(this_present_airavataExperimentId && that_present_airavataExperimentId))
          return false;
        if (!this.airavataExperimentId.equals(that.airavataExperimentId))
          return false;
      }

      boolean this_present_userConfiguration = true && this.isSetUserConfiguration();
      boolean that_present_userConfiguration = true && that.isSetUserConfiguration();
      if (this_present_userConfiguration || that_present_userConfiguration) {
        if (!(this_present_userConfiguration && that_present_userConfiguration))
          return false;
        if (!this.userConfiguration.equals(that.userConfiguration))
          return false;
      }

      return true;
    }

    @Override
    public int hashCode() {
      List<Object> list = new ArrayList<Object>();

      boolean present_authzToken = true && (isSetAuthzToken());
      list.add(present_authzToken);
      if (present_authzToken)
        list.add(authzToken);

      boolean present_airavataExperimentId = true && (isSetAiravataExperimentId());
      list.add(present_airavataExperimentId);
      if (present_airavataExperimentId)
        list.add(airavataExperimentId);

      boolean present_userConfiguration = true && (isSetUserConfiguration());
      list.add(present_userConfiguration);
      if (present_userConfiguration)
        list.add(userConfiguration);

      return list.hashCode();
    }

    @Override
    public int compareTo(updateExperimentConfiguration_args other) {
      if (!getClass().equals(other.getClass())) {
        return getClass().getName().compareTo(other.getClass().getName());
      }

      int lastComparison = 0;

      lastComparison = 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 = Boolean.valueOf(isSetAiravataExperimentId()).compareTo(other.isSetAiravataExperimentId());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetAiravataExperimentId()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.airavataExperimentId, other.airavataExperimentId);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = Boolean.valueOf(isSetUserConfiguration()).compareTo(other.isSetUserConfiguration());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetUserConfiguration()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.userConfiguration, other.userConfiguration);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      return 0;
    }

    public _Fields fieldForId(int fieldId) {
      return _Fields.findByThriftId(fieldId);
    }

    public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
      schemes.get(iprot.getScheme()).getScheme().read(iprot, this);
    }

    public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException {
      schemes.get(oprot.getScheme()).getScheme().write(oprot, this);
    }

    @Override
    public String toString() {
      StringBuilder sb = new StringBuilder("updateExperimentConfiguration_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("airavataExperimentId:");
      if (this.airavataExperimentId == null) {
        sb.append("null");
      } else {
        sb.append(this.airavataExperimentId);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("userConfiguration:");
      if (this.userConfiguration == null) {
        sb.append("null");
      } else {
        sb.append(this.userConfiguration);
      }
      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 (airavataExperimentId == null) {
        throw new org.apache.thrift.protocol.TProtocolException("Required field 'airavataExperimentId' was not present! Struct: " + toString());
      }
      if (userConfiguration == null) {
        throw new org.apache.thrift.protocol.TProtocolException("Required field 'userConfiguration' was not present! Struct: " + toString());
      }
      // check for sub-struct validity
      if (authzToken != null) {
        authzToken.validate();
      }
      if (userConfiguration != null) {
        userConfiguration.validate();
      }
    }

    private void writeObject(java.io.ObjectOutputStream out) throws java.io.IOException {
      try {
        write(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(out)));
      } catch (org.apache.thrift.TException te) {
        throw new java.io.IOException(te);
      }
    }

    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, ClassNotFoundException {
      try {
        read(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(in)));
      } catch (org.apache.thrift.TException te) {
        throw new java.io.IOException(te);
      }
    }

    private static class updateExperimentConfiguration_argsStandardSchemeFactory implements SchemeFactory {
      public updateExperimentConfiguration_argsStandardScheme getScheme() {
        return new updateExperimentConfiguration_argsStandardScheme();
      }
    }

    private static class updateExperimentConfiguration_argsStandardScheme extends StandardScheme<updateExperimentConfiguration_args> {

      public void read(org.apache.thrift.protocol.TProtocol iprot, updateExperimentConfiguration_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_EXPERIMENT_ID
              if (schemeField.type == org.apache.thrift.protocol.TType.STRING) {
                struct.airavataExperimentId = iprot.readString();
                struct.setAiravataExperimentIdIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 3: // USER_CONFIGURATION
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.userConfiguration = new org.apache.airavata.model.experiment.UserConfigurationDataModel();
                struct.userConfiguration.read(iprot);
                struct.setUserConfigurationIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            default:
              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
          }
          iprot.readFieldEnd();
        }
        iprot.readStructEnd();

        // check for required fields of primitive type, which can't be checked in the validate method
        struct.validate();
      }

      public void write(org.apache.thrift.protocol.TProtocol oprot, updateExperimentConfiguration_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.airavataExperimentId != null) {
          oprot.writeFieldBegin(AIRAVATA_EXPERIMENT_ID_FIELD_DESC);
          oprot.writeString(struct.airavataExperimentId);
          oprot.writeFieldEnd();
        }
        if (struct.userConfiguration != null) {
          oprot.writeFieldBegin(USER_CONFIGURATION_FIELD_DESC);
          struct.userConfiguration.write(oprot);
          oprot.writeFieldEnd();
        }
        oprot.writeFieldStop();
        oprot.writeStructEnd();
      }

    }

    private static class updateExperimentConfiguration_argsTupleSchemeFactory implements SchemeFactory {
      public updateExperimentConfiguration_argsTupleScheme getScheme() {
        return new updateExperimentConfiguration_argsTupleScheme();
      }
    }

    private static class updateExperimentConfiguration_argsTupleScheme extends TupleScheme<updateExperimentConfiguration_args> {

      @Override
      public void write(org.apache.thrift.protocol.TProtocol prot, updateExperimentConfiguration_args struct) throws org.apache.thrift.TException {
        TTupleProtocol oprot = (TTupleProtocol) prot;
        struct.authzToken.write(oprot);
        oprot.writeString(struct.airavataExperimentId);
        struct.userConfiguration.write(oprot);
      }

      @Override
      public void read(org.apache.thrift.protocol.TProtocol prot, updateExperimentConfiguration_args struct) throws org.apache.thrift.TException {
        TTupleProtocol iprot = (TTupleProtocol) prot;
        struct.authzToken = new org.apache.airavata.model.security.AuthzToken();
        struct.authzToken.read(iprot);
        struct.setAuthzTokenIsSet(true);
        struct.airavataExperimentId = iprot.readString();
        struct.setAiravataExperimentIdIsSet(true);
        struct.userConfiguration = new org.apache.airavata.model.experiment.UserConfigurationDataModel();
        struct.userConfiguration.read(iprot);
        struct.setUserConfigurationIsSet(true);
      }
    }

  }

  public static class updateExperimentConfiguration_result implements org.apache.thrift.TBase<updateExperimentConfiguration_result, updateExperimentConfiguration_result._Fields>, java.io.Serializable, Cloneable, Comparable<updateExperimentConfiguration_result>   {
    private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("updateExperimentConfiguration_result");

    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)1);

    private static final Map<Class<? extends IScheme>, SchemeFactory> schemes = new HashMap<Class<? extends IScheme>, SchemeFactory>();
    static {
      schemes.put(StandardScheme.class, new updateExperimentConfiguration_resultStandardSchemeFactory());
      schemes.put(TupleScheme.class, new updateExperimentConfiguration_resultTupleSchemeFactory());
    }

    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 {
      AE((short)1, "ae");

      private static final Map<String, _Fields> byName = new HashMap<String, _Fields>();

      static {
        for (_Fields field : EnumSet.allOf(_Fields.class)) {
          byName.put(field.getFieldName(), field);
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, or null if its not found.
       */
      public static _Fields findByThriftId(int fieldId) {
        switch(fieldId) {
          case 1: // 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 IllegalArgumentException("Field " + fieldId + " doesn't exist!");
        return fields;
      }

      /**
       * Find the _Fields constant that matches name, or null if its not found.
       */
      public static _Fields findByName(String name) {
        return byName.get(name);
      }

      private final short _thriftId;
      private final String _fieldName;

      _Fields(short thriftId, String fieldName) {
        _thriftId = thriftId;
        _fieldName = fieldName;
      }

      public short getThriftFieldId() {
        return _thriftId;
      }

      public String getFieldName() {
        return _fieldName;
      }
    }

    // isset id assignments
    public static final Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
    static {
      Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new EnumMap<_Fields, org.apache.thrift.meta_data.FieldMetaData>(_Fields.class);
      tmpMap.put(_Fields.AE, new org.apache.thrift.meta_data.FieldMetaData("ae", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRUCT)));
      metaDataMap = Collections.unmodifiableMap(tmpMap);
      org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(updateExperimentConfiguration_result.class, metaDataMap);
    }

    public updateExperimentConfiguration_result() {
    }

    public updateExperimentConfiguration_result(
      org.apache.airavata.model.error.AuthorizationException ae)
    {
      this();
      this.ae = ae;
    }

    /**
     * Performs a deep copy on <i>other</i>.
     */
    public updateExperimentConfiguration_result(updateExperimentConfiguration_result other) {
      if (other.isSetAe()) {
        this.ae = new org.apache.airavata.model.error.AuthorizationException(other.ae);
      }
    }

    public updateExperimentConfiguration_result deepCopy() {
      return new updateExperimentConfiguration_result(this);
    }

    @Override
    public void clear() {
      this.ae = null;
    }

    public org.apache.airavata.model.error.AuthorizationException getAe() {
      return this.ae;
    }

    public updateExperimentConfiguration_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, Object value) {
      switch (field) {
      case AE:
        if (value == null) {
          unsetAe();
        } else {
          setAe((org.apache.airavata.model.error.AuthorizationException)value);
        }
        break;

      }
    }

    public Object getFieldValue(_Fields field) {
      switch (field) {
      case AE:
        return getAe();

      }
      throw new IllegalStateException();
    }

    /** Returns true if field corresponding to fieldID is set (has been assigned a value) and false otherwise */
    public boolean isSet(_Fields field) {
      if (field == null) {
        throw new IllegalArgumentException();
      }

      switch (field) {
      case AE:
        return isSetAe();
      }
      throw new IllegalStateException();
    }

    @Override
    public boolean equals(Object that) {
      if (that == null)
        return false;
      if (that instanceof updateExperimentConfiguration_result)
        return this.equals((updateExperimentConfiguration_result)that);
      return false;
    }

    public boolean equals(updateExperimentConfiguration_result that) {
      if (that == null)
        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() {
      List<Object> list = new ArrayList<Object>();

      boolean present_ae = true && (isSetAe());
      list.add(present_ae);
      if (present_ae)
        list.add(ae);

      return list.hashCode();
    }

    @Override
    public int compareTo(updateExperimentConfiguration_result other) {
      if (!getClass().equals(other.getClass())) {
        return getClass().getName().compareTo(other.getClass().getName());
      }

      int lastComparison = 0;

      lastComparison = 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 {
      schemes.get(iprot.getScheme()).getScheme().read(iprot, this);
    }

    public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException {
      schemes.get(oprot.getScheme()).getScheme().write(oprot, this);
      }

    @Override
    public String toString() {
      StringBuilder sb = new StringBuilder("updateExperimentConfiguration_result(");
      boolean first = true;

      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, 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 updateExperimentConfiguration_resultStandardSchemeFactory implements SchemeFactory {
      public updateExperimentConfiguration_resultStandardScheme getScheme() {
        return new updateExperimentConfiguration_resultStandardScheme();
      }
    }

    private static class updateExperimentConfiguration_resultStandardScheme extends StandardScheme<updateExperimentConfiguration_result> {

      public void read(org.apache.thrift.protocol.TProtocol iprot, updateExperimentConfiguration_result struct) throws org.apache.thrift.TException {
        org.apache.thrift.protocol.TField schemeField;
        iprot.readStructBegin();
        while (true)
        {
          schemeField = iprot.readFieldBegin();
          if (schemeField.type == org.apache.thrift.protocol.TType.STOP) { 
            break;
          }
          switch (schemeField.id) {
            case 1: // 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, updateExperimentConfiguration_result struct) throws org.apache.thrift.TException {
        struct.validate();

        oprot.writeStructBegin(STRUCT_DESC);
        if (struct.ae != null) {
          oprot.writeFieldBegin(AE_FIELD_DESC);
          struct.ae.write(oprot);
          oprot.writeFieldEnd();
        }
        oprot.writeFieldStop();
        oprot.writeStructEnd();
      }

    }

    private static class updateExperimentConfiguration_resultTupleSchemeFactory implements SchemeFactory {
      public updateExperimentConfiguration_resultTupleScheme getScheme() {
        return new updateExperimentConfiguration_resultTupleScheme();
      }
    }

    private static class updateExperimentConfiguration_resultTupleScheme extends TupleScheme<updateExperimentConfiguration_result> {

      @Override
      public void write(org.apache.thrift.protocol.TProtocol prot, updateExperimentConfiguration_result struct) throws org.apache.thrift.TException {
        TTupleProtocol oprot = (TTupleProtocol) prot;
        BitSet optionals = new BitSet();
        if (struct.isSetAe()) {
          optionals.set(0);
        }
        oprot.writeBitSet(optionals, 1);
        if (struct.isSetAe()) {
          struct.ae.write(oprot);
        }
      }

      @Override
      public void read(org.apache.thrift.protocol.TProtocol prot, updateExperimentConfiguration_result struct) throws org.apache.thrift.TException {
        TTupleProtocol iprot = (TTupleProtocol) prot;
        BitSet incoming = iprot.readBitSet(1);
        if (incoming.get(0)) {
          struct.ae = new org.apache.airavata.model.error.AuthorizationException();
          struct.ae.read(iprot);
          struct.setAeIsSet(true);
        }
      }
    }

  }

  public static class updateResourceScheduleing_args implements org.apache.thrift.TBase<updateResourceScheduleing_args, updateResourceScheduleing_args._Fields>, java.io.Serializable, Cloneable, Comparable<updateResourceScheduleing_args>   {
    private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("updateResourceScheduleing_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_EXPERIMENT_ID_FIELD_DESC = new org.apache.thrift.protocol.TField("airavataExperimentId", org.apache.thrift.protocol.TType.STRING, (short)2);
    private static final org.apache.thrift.protocol.TField RESOURCE_SCHEDULING_FIELD_DESC = new org.apache.thrift.protocol.TField("resourceScheduling", org.apache.thrift.protocol.TType.STRUCT, (short)3);

    private static final Map<Class<? extends IScheme>, SchemeFactory> schemes = new HashMap<Class<? extends IScheme>, SchemeFactory>();
    static {
      schemes.put(StandardScheme.class, new updateResourceScheduleing_argsStandardSchemeFactory());
      schemes.put(TupleScheme.class, new updateResourceScheduleing_argsTupleSchemeFactory());
    }

    public org.apache.airavata.model.security.AuthzToken authzToken; // required
    public String airavataExperimentId; // required
    public org.apache.airavata.model.scheduling.ComputationalResourceSchedulingModel resourceScheduling; // required

    /** 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_EXPERIMENT_ID((short)2, "airavataExperimentId"),
      RESOURCE_SCHEDULING((short)3, "resourceScheduling");

      private static final Map<String, _Fields> byName = new HashMap<String, _Fields>();

      static {
        for (_Fields field : EnumSet.allOf(_Fields.class)) {
          byName.put(field.getFieldName(), field);
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, or null if its not found.
       */
      public static _Fields findByThriftId(int fieldId) {
        switch(fieldId) {
          case 1: // AUTHZ_TOKEN
            return AUTHZ_TOKEN;
          case 2: // AIRAVATA_EXPERIMENT_ID
            return AIRAVATA_EXPERIMENT_ID;
          case 3: // RESOURCE_SCHEDULING
            return RESOURCE_SCHEDULING;
          default:
            return null;
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, throwing an exception
       * if it is not found.
       */
      public static _Fields findByThriftIdOrThrow(int fieldId) {
        _Fields fields = findByThriftId(fieldId);
        if (fields == null) throw new IllegalArgumentException("Field " + fieldId + " doesn't exist!");
        return fields;
      }

      /**
       * Find the _Fields constant that matches name, or null if its not found.
       */
      public static _Fields findByName(String name) {
        return byName.get(name);
      }

      private final short _thriftId;
      private final String _fieldName;

      _Fields(short thriftId, String fieldName) {
        _thriftId = thriftId;
        _fieldName = fieldName;
      }

      public short getThriftFieldId() {
        return _thriftId;
      }

      public String getFieldName() {
        return _fieldName;
      }
    }

    // isset id assignments
    public static final Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
    static {
      Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new EnumMap<_Fields, org.apache.thrift.meta_data.FieldMetaData>(_Fields.class);
      tmpMap.put(_Fields.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_EXPERIMENT_ID, new org.apache.thrift.meta_data.FieldMetaData("airavataExperimentId", org.apache.thrift.TFieldRequirementType.REQUIRED, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING)));
      tmpMap.put(_Fields.RESOURCE_SCHEDULING, new org.apache.thrift.meta_data.FieldMetaData("resourceScheduling", org.apache.thrift.TFieldRequirementType.REQUIRED, 
          new org.apache.thrift.meta_data.StructMetaData(org.apache.thrift.protocol.TType.STRUCT, org.apache.airavata.model.scheduling.ComputationalResourceSchedulingModel.class)));
      metaDataMap = Collections.unmodifiableMap(tmpMap);
      org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(updateResourceScheduleing_args.class, metaDataMap);
    }

    public updateResourceScheduleing_args() {
    }

    public updateResourceScheduleing_args(
      org.apache.airavata.model.security.AuthzToken authzToken,
      String airavataExperimentId,
      org.apache.airavata.model.scheduling.ComputationalResourceSchedulingModel resourceScheduling)
    {
      this();
      this.authzToken = authzToken;
      this.airavataExperimentId = airavataExperimentId;
      this.resourceScheduling = resourceScheduling;
    }

    /**
     * Performs a deep copy on <i>other</i>.
     */
    public updateResourceScheduleing_args(updateResourceScheduleing_args other) {
      if (other.isSetAuthzToken()) {
        this.authzToken = new org.apache.airavata.model.security.AuthzToken(other.authzToken);
      }
      if (other.isSetAiravataExperimentId()) {
        this.airavataExperimentId = other.airavataExperimentId;
      }
      if (other.isSetResourceScheduling()) {
        this.resourceScheduling = new org.apache.airavata.model.scheduling.ComputationalResourceSchedulingModel(other.resourceScheduling);
      }
    }

    public updateResourceScheduleing_args deepCopy() {
      return new updateResourceScheduleing_args(this);
    }

    @Override
    public void clear() {
      this.authzToken = null;
      this.airavataExperimentId = null;
      this.resourceScheduling = null;
    }

    public org.apache.airavata.model.security.AuthzToken getAuthzToken() {
      return this.authzToken;
    }

    public updateResourceScheduleing_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 String getAiravataExperimentId() {
      return this.airavataExperimentId;
    }

    public updateResourceScheduleing_args setAiravataExperimentId(String airavataExperimentId) {
      this.airavataExperimentId = airavataExperimentId;
      return this;
    }

    public void unsetAiravataExperimentId() {
      this.airavataExperimentId = null;
    }

    /** Returns true if field airavataExperimentId is set (has been assigned a value) and false otherwise */
    public boolean isSetAiravataExperimentId() {
      return this.airavataExperimentId != null;
    }

    public void setAiravataExperimentIdIsSet(boolean value) {
      if (!value) {
        this.airavataExperimentId = null;
      }
    }

    public org.apache.airavata.model.scheduling.ComputationalResourceSchedulingModel getResourceScheduling() {
      return this.resourceScheduling;
    }

    public updateResourceScheduleing_args setResourceScheduling(org.apache.airavata.model.scheduling.ComputationalResourceSchedulingModel resourceScheduling) {
      this.resourceScheduling = resourceScheduling;
      return this;
    }

    public void unsetResourceScheduling() {
      this.resourceScheduling = null;
    }

    /** Returns true if field resourceScheduling is set (has been assigned a value) and false otherwise */
    public boolean isSetResourceScheduling() {
      return this.resourceScheduling != null;
    }

    public void setResourceSchedulingIsSet(boolean value) {
      if (!value) {
        this.resourceScheduling = null;
      }
    }

    public void setFieldValue(_Fields field, Object value) {
      switch (field) {
      case AUTHZ_TOKEN:
        if (value == null) {
          unsetAuthzToken();
        } else {
          setAuthzToken((org.apache.airavata.model.security.AuthzToken)value);
        }
        break;

      case AIRAVATA_EXPERIMENT_ID:
        if (value == null) {
          unsetAiravataExperimentId();
        } else {
          setAiravataExperimentId((String)value);
        }
        break;

      case RESOURCE_SCHEDULING:
        if (value == null) {
          unsetResourceScheduling();
        } else {
          setResourceScheduling((org.apache.airavata.model.scheduling.ComputationalResourceSchedulingModel)value);
        }
        break;

      }
    }

    public Object getFieldValue(_Fields field) {
      switch (field) {
      case AUTHZ_TOKEN:
        return getAuthzToken();

      case AIRAVATA_EXPERIMENT_ID:
        return getAiravataExperimentId();

      case RESOURCE_SCHEDULING:
        return getResourceScheduling();

      }
      throw new IllegalStateException();
    }

    /** Returns true if field corresponding to fieldID is set (has been assigned a value) and false otherwise */
    public boolean isSet(_Fields field) {
      if (field == null) {
        throw new IllegalArgumentException();
      }

      switch (field) {
      case AUTHZ_TOKEN:
        return isSetAuthzToken();
      case AIRAVATA_EXPERIMENT_ID:
        return isSetAiravataExperimentId();
      case RESOURCE_SCHEDULING:
        return isSetResourceScheduling();
      }
      throw new IllegalStateException();
    }

    @Override
    public boolean equals(Object that) {
      if (that == null)
        return false;
      if (that instanceof updateResourceScheduleing_args)
        return this.equals((updateResourceScheduleing_args)that);
      return false;
    }

    public boolean equals(updateResourceScheduleing_args that) {
      if (that == null)
        return false;

      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_airavataExperimentId = true && this.isSetAiravataExperimentId();
      boolean that_present_airavataExperimentId = true && that.isSetAiravataExperimentId();
      if (this_present_airavataExperimentId || that_present_airavataExperimentId) {
        if (!(this_present_airavataExperimentId && that_present_airavataExperimentId))
          return false;
        if (!this.airavataExperimentId.equals(that.airavataExperimentId))
          return false;
      }

      boolean this_present_resourceScheduling = true && this.isSetResourceScheduling();
      boolean that_present_resourceScheduling = true && that.isSetResourceScheduling();
      if (this_present_resourceScheduling || that_present_resourceScheduling) {
        if (!(this_present_resourceScheduling && that_present_resourceScheduling))
          return false;
        if (!this.resourceScheduling.equals(that.resourceScheduling))
          return false;
      }

      return true;
    }

    @Override
    public int hashCode() {
      List<Object> list = new ArrayList<Object>();

      boolean present_authzToken = true && (isSetAuthzToken());
      list.add(present_authzToken);
      if (present_authzToken)
        list.add(authzToken);

      boolean present_airavataExperimentId = true && (isSetAiravataExperimentId());
      list.add(present_airavataExperimentId);
      if (present_airavataExperimentId)
        list.add(airavataExperimentId);

      boolean present_resourceScheduling = true && (isSetResourceScheduling());
      list.add(present_resourceScheduling);
      if (present_resourceScheduling)
        list.add(resourceScheduling);

      return list.hashCode();
    }

    @Override
    public int compareTo(updateResourceScheduleing_args other) {
      if (!getClass().equals(other.getClass())) {
        return getClass().getName().compareTo(other.getClass().getName());
      }

      int lastComparison = 0;

      lastComparison = 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 = Boolean.valueOf(isSetAiravataExperimentId()).compareTo(other.isSetAiravataExperimentId());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetAiravataExperimentId()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.airavataExperimentId, other.airavataExperimentId);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = Boolean.valueOf(isSetResourceScheduling()).compareTo(other.isSetResourceScheduling());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetResourceScheduling()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.resourceScheduling, other.resourceScheduling);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      return 0;
    }

    public _Fields fieldForId(int fieldId) {
      return _Fields.findByThriftId(fieldId);
    }

    public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
      schemes.get(iprot.getScheme()).getScheme().read(iprot, this);
    }

    public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException {
      schemes.get(oprot.getScheme()).getScheme().write(oprot, this);
    }

    @Override
    public String toString() {
      StringBuilder sb = new StringBuilder("updateResourceScheduleing_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("airavataExperimentId:");
      if (this.airavataExperimentId == null) {
        sb.append("null");
      } else {
        sb.append(this.airavataExperimentId);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("resourceScheduling:");
      if (this.resourceScheduling == null) {
        sb.append("null");
      } else {
        sb.append(this.resourceScheduling);
      }
      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 (airavataExperimentId == null) {
        throw new org.apache.thrift.protocol.TProtocolException("Required field 'airavataExperimentId' was not present! Struct: " + toString());
      }
      if (resourceScheduling == null) {
        throw new org.apache.thrift.protocol.TProtocolException("Required field 'resourceScheduling' was not present! Struct: " + toString());
      }
      // check for sub-struct validity
      if (authzToken != null) {
        authzToken.validate();
      }
      if (resourceScheduling != null) {
        resourceScheduling.validate();
      }
    }

    private void writeObject(java.io.ObjectOutputStream out) throws java.io.IOException {
      try {
        write(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(out)));
      } catch (org.apache.thrift.TException te) {
        throw new java.io.IOException(te);
      }
    }

    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, ClassNotFoundException {
      try {
        read(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(in)));
      } catch (org.apache.thrift.TException te) {
        throw new java.io.IOException(te);
      }
    }

    private static class updateResourceScheduleing_argsStandardSchemeFactory implements SchemeFactory {
      public updateResourceScheduleing_argsStandardScheme getScheme() {
        return new updateResourceScheduleing_argsStandardScheme();
      }
    }

    private static class updateResourceScheduleing_argsStandardScheme extends StandardScheme<updateResourceScheduleing_args> {

      public void read(org.apache.thrift.protocol.TProtocol iprot, updateResourceScheduleing_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_EXPERIMENT_ID
              if (schemeField.type == org.apache.thrift.protocol.TType.STRING) {
                struct.airavataExperimentId = iprot.readString();
                struct.setAiravataExperimentIdIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 3: // RESOURCE_SCHEDULING
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.resourceScheduling = new org.apache.airavata.model.scheduling.ComputationalResourceSchedulingModel();
                struct.resourceScheduling.read(iprot);
                struct.setResourceSchedulingIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            default:
              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
          }
          iprot.readFieldEnd();
        }
        iprot.readStructEnd();

        // check for required fields of primitive type, which can't be checked in the validate method
        struct.validate();
      }

      public void write(org.apache.thrift.protocol.TProtocol oprot, updateResourceScheduleing_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.airavataExperimentId != null) {
          oprot.writeFieldBegin(AIRAVATA_EXPERIMENT_ID_FIELD_DESC);
          oprot.writeString(struct.airavataExperimentId);
          oprot.writeFieldEnd();
        }
        if (struct.resourceScheduling != null) {
          oprot.writeFieldBegin(RESOURCE_SCHEDULING_FIELD_DESC);
          struct.resourceScheduling.write(oprot);
          oprot.writeFieldEnd();
        }
        oprot.writeFieldStop();
        oprot.writeStructEnd();
      }

    }

    private static class updateResourceScheduleing_argsTupleSchemeFactory implements SchemeFactory {
      public updateResourceScheduleing_argsTupleScheme getScheme() {
        return new updateResourceScheduleing_argsTupleScheme();
      }
    }

    private static class updateResourceScheduleing_argsTupleScheme extends TupleScheme<updateResourceScheduleing_args> {

      @Override
      public void write(org.apache.thrift.protocol.TProtocol prot, updateResourceScheduleing_args struct) throws org.apache.thrift.TException {
        TTupleProtocol oprot = (TTupleProtocol) prot;
        struct.authzToken.write(oprot);
        oprot.writeString(struct.airavataExperimentId);
        struct.resourceScheduling.write(oprot);
      }

      @Override
      public void read(org.apache.thrift.protocol.TProtocol prot, updateResourceScheduleing_args struct) throws org.apache.thrift.TException {
        TTupleProtocol iprot = (TTupleProtocol) prot;
        struct.authzToken = new org.apache.airavata.model.security.AuthzToken();
        struct.authzToken.read(iprot);
        struct.setAuthzTokenIsSet(true);
        struct.airavataExperimentId = iprot.readString();
        struct.setAiravataExperimentIdIsSet(true);
        struct.resourceScheduling = new org.apache.airavata.model.scheduling.ComputationalResourceSchedulingModel();
        struct.resourceScheduling.read(iprot);
        struct.setResourceSchedulingIsSet(true);
      }
    }

  }

  public static class updateResourceScheduleing_result implements org.apache.thrift.TBase<updateResourceScheduleing_result, updateResourceScheduleing_result._Fields>, java.io.Serializable, Cloneable, Comparable<updateResourceScheduleing_result>   {
    private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("updateResourceScheduleing_result");

    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)1);

    private static final Map<Class<? extends IScheme>, SchemeFactory> schemes = new HashMap<Class<? extends IScheme>, SchemeFactory>();
    static {
      schemes.put(StandardScheme.class, new updateResourceScheduleing_resultStandardSchemeFactory());
      schemes.put(TupleScheme.class, new updateResourceScheduleing_resultTupleSchemeFactory());
    }

    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 {
      AE((short)1, "ae");

      private static final Map<String, _Fields> byName = new HashMap<String, _Fields>();

      static {
        for (_Fields field : EnumSet.allOf(_Fields.class)) {
          byName.put(field.getFieldName(), field);
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, or null if its not found.
       */
      public static _Fields findByThriftId(int fieldId) {
        switch(fieldId) {
          case 1: // 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 IllegalArgumentException("Field " + fieldId + " doesn't exist!");
        return fields;
      }

      /**
       * Find the _Fields constant that matches name, or null if its not found.
       */
      public static _Fields findByName(String name) {
        return byName.get(name);
      }

      private final short _thriftId;
      private final String _fieldName;

      _Fields(short thriftId, String fieldName) {
        _thriftId = thriftId;
        _fieldName = fieldName;
      }

      public short getThriftFieldId() {
        return _thriftId;
      }

      public String getFieldName() {
        return _fieldName;
      }
    }

    // isset id assignments
    public static final Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
    static {
      Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new EnumMap<_Fields, org.apache.thrift.meta_data.FieldMetaData>(_Fields.class);
      tmpMap.put(_Fields.AE, new org.apache.thrift.meta_data.FieldMetaData("ae", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRUCT)));
      metaDataMap = Collections.unmodifiableMap(tmpMap);
      org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(updateResourceScheduleing_result.class, metaDataMap);
    }

    public updateResourceScheduleing_result() {
    }

    public updateResourceScheduleing_result(
      org.apache.airavata.model.error.AuthorizationException ae)
    {
      this();
      this.ae = ae;
    }

    /**
     * Performs a deep copy on <i>other</i>.
     */
    public updateResourceScheduleing_result(updateResourceScheduleing_result other) {
      if (other.isSetAe()) {
        this.ae = new org.apache.airavata.model.error.AuthorizationException(other.ae);
      }
    }

    public updateResourceScheduleing_result deepCopy() {
      return new updateResourceScheduleing_result(this);
    }

    @Override
    public void clear() {
      this.ae = null;
    }

    public org.apache.airavata.model.error.AuthorizationException getAe() {
      return this.ae;
    }

    public updateResourceScheduleing_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, Object value) {
      switch (field) {
      case AE:
        if (value == null) {
          unsetAe();
        } else {
          setAe((org.apache.airavata.model.error.AuthorizationException)value);
        }
        break;

      }
    }

    public Object getFieldValue(_Fields field) {
      switch (field) {
      case AE:
        return getAe();

      }
      throw new IllegalStateException();
    }

    /** Returns true if field corresponding to fieldID is set (has been assigned a value) and false otherwise */
    public boolean isSet(_Fields field) {
      if (field == null) {
        throw new IllegalArgumentException();
      }

      switch (field) {
      case AE:
        return isSetAe();
      }
      throw new IllegalStateException();
    }

    @Override
    public boolean equals(Object that) {
      if (that == null)
        return false;
      if (that instanceof updateResourceScheduleing_result)
        return this.equals((updateResourceScheduleing_result)that);
      return false;
    }

    public boolean equals(updateResourceScheduleing_result that) {
      if (that == null)
        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() {
      List<Object> list = new ArrayList<Object>();

      boolean present_ae = true && (isSetAe());
      list.add(present_ae);
      if (present_ae)
        list.add(ae);

      return list.hashCode();
    }

    @Override
    public int compareTo(updateResourceScheduleing_result other) {
      if (!getClass().equals(other.getClass())) {
        return getClass().getName().compareTo(other.getClass().getName());
      }

      int lastComparison = 0;

      lastComparison = 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 {
      schemes.get(iprot.getScheme()).getScheme().read(iprot, this);
    }

    public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException {
      schemes.get(oprot.getScheme()).getScheme().write(oprot, this);
      }

    @Override
    public String toString() {
      StringBuilder sb = new StringBuilder("updateResourceScheduleing_result(");
      boolean first = true;

      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, 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 updateResourceScheduleing_resultStandardSchemeFactory implements SchemeFactory {
      public updateResourceScheduleing_resultStandardScheme getScheme() {
        return new updateResourceScheduleing_resultStandardScheme();
      }
    }

    private static class updateResourceScheduleing_resultStandardScheme extends StandardScheme<updateResourceScheduleing_result> {

      public void read(org.apache.thrift.protocol.TProtocol iprot, updateResourceScheduleing_result struct) throws org.apache.thrift.TException {
        org.apache.thrift.protocol.TField schemeField;
        iprot.readStructBegin();
        while (true)
        {
          schemeField = iprot.readFieldBegin();
          if (schemeField.type == org.apache.thrift.protocol.TType.STOP) { 
            break;
          }
          switch (schemeField.id) {
            case 1: // 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, updateResourceScheduleing_result struct) throws org.apache.thrift.TException {
        struct.validate();

        oprot.writeStructBegin(STRUCT_DESC);
        if (struct.ae != null) {
          oprot.writeFieldBegin(AE_FIELD_DESC);
          struct.ae.write(oprot);
          oprot.writeFieldEnd();
        }
        oprot.writeFieldStop();
        oprot.writeStructEnd();
      }

    }

    private static class updateResourceScheduleing_resultTupleSchemeFactory implements SchemeFactory {
      public updateResourceScheduleing_resultTupleScheme getScheme() {
        return new updateResourceScheduleing_resultTupleScheme();
      }
    }

    private static class updateResourceScheduleing_resultTupleScheme extends TupleScheme<updateResourceScheduleing_result> {

      @Override
      public void write(org.apache.thrift.protocol.TProtocol prot, updateResourceScheduleing_result struct) throws org.apache.thrift.TException {
        TTupleProtocol oprot = (TTupleProtocol) prot;
        BitSet optionals = new BitSet();
        if (struct.isSetAe()) {
          optionals.set(0);
        }
        oprot.writeBitSet(optionals, 1);
        if (struct.isSetAe()) {
          struct.ae.write(oprot);
        }
      }

      @Override
      public void read(org.apache.thrift.protocol.TProtocol prot, updateResourceScheduleing_result struct) throws org.apache.thrift.TException {
        TTupleProtocol iprot = (TTupleProtocol) prot;
        BitSet incoming = iprot.readBitSet(1);
        if (incoming.get(0)) {
          struct.ae = new org.apache.airavata.model.error.AuthorizationException();
          struct.ae.read(iprot);
          struct.setAeIsSet(true);
        }
      }
    }

  }

  public static class validateExperiment_args implements org.apache.thrift.TBase<validateExperiment_args, validateExperiment_args._Fields>, java.io.Serializable, Cloneable, Comparable<validateExperiment_args>   {
    private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("validateExperiment_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_EXPERIMENT_ID_FIELD_DESC = new org.apache.thrift.protocol.TField("airavataExperimentId", org.apache.thrift.protocol.TType.STRING, (short)2);

    private static final Map<Class<? extends IScheme>, SchemeFactory> schemes = new HashMap<Class<? extends IScheme>, SchemeFactory>();
    static {
      schemes.put(StandardScheme.class, new validateExperiment_argsStandardSchemeFactory());
      schemes.put(TupleScheme.class, new validateExperiment_argsTupleSchemeFactory());
    }

    public org.apache.airavata.model.security.AuthzToken authzToken; // required
    public String airavataExperimentId; // required

    /** 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_EXPERIMENT_ID((short)2, "airavataExperimentId");

      private static final Map<String, _Fields> byName = new HashMap<String, _Fields>();

      static {
        for (_Fields field : EnumSet.allOf(_Fields.class)) {
          byName.put(field.getFieldName(), field);
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, or null if its not found.
       */
      public static _Fields findByThriftId(int fieldId) {
        switch(fieldId) {
          case 1: // AUTHZ_TOKEN
            return AUTHZ_TOKEN;
          case 2: // AIRAVATA_EXPERIMENT_ID
            return AIRAVATA_EXPERIMENT_ID;
          default:
            return null;
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, throwing an exception
       * if it is not found.
       */
      public static _Fields findByThriftIdOrThrow(int fieldId) {
        _Fields fields = findByThriftId(fieldId);
        if (fields == null) throw new IllegalArgumentException("Field " + fieldId + " doesn't exist!");
        return fields;
      }

      /**
       * Find the _Fields constant that matches name, or null if its not found.
       */
      public static _Fields findByName(String name) {
        return byName.get(name);
      }

      private final short _thriftId;
      private final String _fieldName;

      _Fields(short thriftId, String fieldName) {
        _thriftId = thriftId;
        _fieldName = fieldName;
      }

      public short getThriftFieldId() {
        return _thriftId;
      }

      public String getFieldName() {
        return _fieldName;
      }
    }

    // isset id assignments
    public static final Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
    static {
      Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new EnumMap<_Fields, org.apache.thrift.meta_data.FieldMetaData>(_Fields.class);
      tmpMap.put(_Fields.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_EXPERIMENT_ID, new org.apache.thrift.meta_data.FieldMetaData("airavataExperimentId", org.apache.thrift.TFieldRequirementType.REQUIRED, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING)));
      metaDataMap = Collections.unmodifiableMap(tmpMap);
      org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(validateExperiment_args.class, metaDataMap);
    }

    public validateExperiment_args() {
    }

    public validateExperiment_args(
      org.apache.airavata.model.security.AuthzToken authzToken,
      String airavataExperimentId)
    {
      this();
      this.authzToken = authzToken;
      this.airavataExperimentId = airavataExperimentId;
    }

    /**
     * Performs a deep copy on <i>other</i>.
     */
    public validateExperiment_args(validateExperiment_args other) {
      if (other.isSetAuthzToken()) {
        this.authzToken = new org.apache.airavata.model.security.AuthzToken(other.authzToken);
      }
      if (other.isSetAiravataExperimentId()) {
        this.airavataExperimentId = other.airavataExperimentId;
      }
    }

    public validateExperiment_args deepCopy() {
      return new validateExperiment_args(this);
    }

    @Override
    public void clear() {
      this.authzToken = null;
      this.airavataExperimentId = null;
    }

    public org.apache.airavata.model.security.AuthzToken getAuthzToken() {
      return this.authzToken;
    }

    public validateExperiment_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 String getAiravataExperimentId() {
      return this.airavataExperimentId;
    }

    public validateExperiment_args setAiravataExperimentId(String airavataExperimentId) {
      this.airavataExperimentId = airavataExperimentId;
      return this;
    }

    public void unsetAiravataExperimentId() {
      this.airavataExperimentId = null;
    }

    /** Returns true if field airavataExperimentId is set (has been assigned a value) and false otherwise */
    public boolean isSetAiravataExperimentId() {
      return this.airavataExperimentId != null;
    }

    public void setAiravataExperimentIdIsSet(boolean value) {
      if (!value) {
        this.airavataExperimentId = null;
      }
    }

    public void setFieldValue(_Fields field, Object value) {
      switch (field) {
      case AUTHZ_TOKEN:
        if (value == null) {
          unsetAuthzToken();
        } else {
          setAuthzToken((org.apache.airavata.model.security.AuthzToken)value);
        }
        break;

      case AIRAVATA_EXPERIMENT_ID:
        if (value == null) {
          unsetAiravataExperimentId();
        } else {
          setAiravataExperimentId((String)value);
        }
        break;

      }
    }

    public Object getFieldValue(_Fields field) {
      switch (field) {
      case AUTHZ_TOKEN:
        return getAuthzToken();

      case AIRAVATA_EXPERIMENT_ID:
        return getAiravataExperimentId();

      }
      throw new IllegalStateException();
    }

    /** Returns true if field corresponding to fieldID is set (has been assigned a value) and false otherwise */
    public boolean isSet(_Fields field) {
      if (field == null) {
        throw new IllegalArgumentException();
      }

      switch (field) {
      case AUTHZ_TOKEN:
        return isSetAuthzToken();
      case AIRAVATA_EXPERIMENT_ID:
        return isSetAiravataExperimentId();
      }
      throw new IllegalStateException();
    }

    @Override
    public boolean equals(Object that) {
      if (that == null)
        return false;
      if (that instanceof validateExperiment_args)
        return this.equals((validateExperiment_args)that);
      return false;
    }

    public boolean equals(validateExperiment_args that) {
      if (that == null)
        return false;

      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_airavataExperimentId = true && this.isSetAiravataExperimentId();
      boolean that_present_airavataExperimentId = true && that.isSetAiravataExperimentId();
      if (this_present_airavataExperimentId || that_present_airavataExperimentId) {
        if (!(this_present_airavataExperimentId && that_present_airavataExperimentId))
          return false;
        if (!this.airavataExperimentId.equals(that.airavataExperimentId))
          return false;
      }

      return true;
    }

    @Override
    public int hashCode() {
      List<Object> list = new ArrayList<Object>();

      boolean present_authzToken = true && (isSetAuthzToken());
      list.add(present_authzToken);
      if (present_authzToken)
        list.add(authzToken);

      boolean present_airavataExperimentId = true && (isSetAiravataExperimentId());
      list.add(present_airavataExperimentId);
      if (present_airavataExperimentId)
        list.add(airavataExperimentId);

      return list.hashCode();
    }

    @Override
    public int compareTo(validateExperiment_args other) {
      if (!getClass().equals(other.getClass())) {
        return getClass().getName().compareTo(other.getClass().getName());
      }

      int lastComparison = 0;

      lastComparison = 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 = Boolean.valueOf(isSetAiravataExperimentId()).compareTo(other.isSetAiravataExperimentId());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetAiravataExperimentId()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.airavataExperimentId, other.airavataExperimentId);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      return 0;
    }

    public _Fields fieldForId(int fieldId) {
      return _Fields.findByThriftId(fieldId);
    }

    public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
      schemes.get(iprot.getScheme()).getScheme().read(iprot, this);
    }

    public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException {
      schemes.get(oprot.getScheme()).getScheme().write(oprot, this);
    }

    @Override
    public String toString() {
      StringBuilder sb = new StringBuilder("validateExperiment_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("airavataExperimentId:");
      if (this.airavataExperimentId == null) {
        sb.append("null");
      } else {
        sb.append(this.airavataExperimentId);
      }
      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 (airavataExperimentId == null) {
        throw new org.apache.thrift.protocol.TProtocolException("Required field 'airavataExperimentId' 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, 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 validateExperiment_argsStandardSchemeFactory implements SchemeFactory {
      public validateExperiment_argsStandardScheme getScheme() {
        return new validateExperiment_argsStandardScheme();
      }
    }

    private static class validateExperiment_argsStandardScheme extends StandardScheme<validateExperiment_args> {

      public void read(org.apache.thrift.protocol.TProtocol iprot, validateExperiment_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_EXPERIMENT_ID
              if (schemeField.type == org.apache.thrift.protocol.TType.STRING) {
                struct.airavataExperimentId = iprot.readString();
                struct.setAiravataExperimentIdIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            default:
              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
          }
          iprot.readFieldEnd();
        }
        iprot.readStructEnd();

        // check for required fields of primitive type, which can't be checked in the validate method
        struct.validate();
      }

      public void write(org.apache.thrift.protocol.TProtocol oprot, validateExperiment_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.airavataExperimentId != null) {
          oprot.writeFieldBegin(AIRAVATA_EXPERIMENT_ID_FIELD_DESC);
          oprot.writeString(struct.airavataExperimentId);
          oprot.writeFieldEnd();
        }
        oprot.writeFieldStop();
        oprot.writeStructEnd();
      }

    }

    private static class validateExperiment_argsTupleSchemeFactory implements SchemeFactory {
      public validateExperiment_argsTupleScheme getScheme() {
        return new validateExperiment_argsTupleScheme();
      }
    }

    private static class validateExperiment_argsTupleScheme extends TupleScheme<validateExperiment_args> {

      @Override
      public void write(org.apache.thrift.protocol.TProtocol prot, validateExperiment_args struct) throws org.apache.thrift.TException {
        TTupleProtocol oprot = (TTupleProtocol) prot;
        struct.authzToken.write(oprot);
        oprot.writeString(struct.airavataExperimentId);
      }

      @Override
      public void read(org.apache.thrift.protocol.TProtocol prot, validateExperiment_args struct) throws org.apache.thrift.TException {
        TTupleProtocol iprot = (TTupleProtocol) prot;
        struct.authzToken = new org.apache.airavata.model.security.AuthzToken();
        struct.authzToken.read(iprot);
        struct.setAuthzTokenIsSet(true);
        struct.airavataExperimentId = iprot.readString();
        struct.setAiravataExperimentIdIsSet(true);
      }
    }

  }

  public static class validateExperiment_result implements org.apache.thrift.TBase<validateExperiment_result, validateExperiment_result._Fields>, java.io.Serializable, Cloneable, Comparable<validateExperiment_result>   {
    private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("validateExperiment_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 IRE_FIELD_DESC = new org.apache.thrift.protocol.TField("ire", org.apache.thrift.protocol.TType.STRUCT, (short)1);
    private static final org.apache.thrift.protocol.TField ENF_FIELD_DESC = new org.apache.thrift.protocol.TField("enf", org.apache.thrift.protocol.TType.STRUCT, (short)2);
    private static final org.apache.thrift.protocol.TField ACE_FIELD_DESC = new org.apache.thrift.protocol.TField("ace", org.apache.thrift.protocol.TType.STRUCT, (short)3);
    private static final org.apache.thrift.protocol.TField ASE_FIELD_DESC = new org.apache.thrift.protocol.TField("ase", org.apache.thrift.protocol.TType.STRUCT, (short)4);
    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)5);

    private static final Map<Class<? extends IScheme>, SchemeFactory> schemes = new HashMap<Class<? extends IScheme>, SchemeFactory>();
    static {
      schemes.put(StandardScheme.class, new validateExperiment_resultStandardSchemeFactory());
      schemes.put(TupleScheme.class, new validateExperiment_resultTupleSchemeFactory());
    }

    public boolean success; // required
    public org.apache.airavata.model.error.InvalidRequestException ire; // required
    public org.apache.airavata.model.error.ExperimentNotFoundException enf; // required
    public org.apache.airavata.model.error.AiravataClientException ace; // required
    public org.apache.airavata.model.error.AiravataSystemException ase; // 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"),
      IRE((short)1, "ire"),
      ENF((short)2, "enf"),
      ACE((short)3, "ace"),
      ASE((short)4, "ase"),
      AE((short)5, "ae");

      private static final Map<String, _Fields> byName = new HashMap<String, _Fields>();

      static {
        for (_Fields field : EnumSet.allOf(_Fields.class)) {
          byName.put(field.getFieldName(), field);
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, or null if its not found.
       */
      public static _Fields findByThriftId(int fieldId) {
        switch(fieldId) {
          case 0: // SUCCESS
            return SUCCESS;
          case 1: // IRE
            return IRE;
          case 2: // ENF
            return ENF;
          case 3: // ACE
            return ACE;
          case 4: // ASE
            return ASE;
          case 5: // 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 IllegalArgumentException("Field " + fieldId + " doesn't exist!");
        return fields;
      }

      /**
       * Find the _Fields constant that matches name, or null if its not found.
       */
      public static _Fields findByName(String name) {
        return byName.get(name);
      }

      private final short _thriftId;
      private final String _fieldName;

      _Fields(short thriftId, String fieldName) {
        _thriftId = thriftId;
        _fieldName = fieldName;
      }

      public short getThriftFieldId() {
        return _thriftId;
      }

      public String getFieldName() {
        return _fieldName;
      }
    }

    // isset id assignments
    private static final int __SUCCESS_ISSET_ID = 0;
    private byte __isset_bitfield = 0;
    public static final Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
    static {
      Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new EnumMap<_Fields, org.apache.thrift.meta_data.FieldMetaData>(_Fields.class);
      tmpMap.put(_Fields.SUCCESS, new org.apache.thrift.meta_data.FieldMetaData("success", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.BOOL)));
      tmpMap.put(_Fields.IRE, new org.apache.thrift.meta_data.FieldMetaData("ire", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRUCT)));
      tmpMap.put(_Fields.ENF, new org.apache.thrift.meta_data.FieldMetaData("enf", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRUCT)));
      tmpMap.put(_Fields.ACE, new org.apache.thrift.meta_data.FieldMetaData("ace", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRUCT)));
      tmpMap.put(_Fields.ASE, new org.apache.thrift.meta_data.FieldMetaData("ase", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRUCT)));
      tmpMap.put(_Fields.AE, new org.apache.thrift.meta_data.FieldMetaData("ae", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRUCT)));
      metaDataMap = Collections.unmodifiableMap(tmpMap);
      org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(validateExperiment_result.class, metaDataMap);
    }

    public validateExperiment_result() {
    }

    public validateExperiment_result(
      boolean success,
      org.apache.airavata.model.error.InvalidRequestException ire,
      org.apache.airavata.model.error.ExperimentNotFoundException enf,
      org.apache.airavata.model.error.AiravataClientException ace,
      org.apache.airavata.model.error.AiravataSystemException ase,
      org.apache.airavata.model.error.AuthorizationException ae)
    {
      this();
      this.success = success;
      setSuccessIsSet(true);
      this.ire = ire;
      this.enf = enf;
      this.ace = ace;
      this.ase = ase;
      this.ae = ae;
    }

    /**
     * Performs a deep copy on <i>other</i>.
     */
    public validateExperiment_result(validateExperiment_result other) {
      __isset_bitfield = other.__isset_bitfield;
      this.success = other.success;
      if (other.isSetIre()) {
        this.ire = new org.apache.airavata.model.error.InvalidRequestException(other.ire);
      }
      if (other.isSetEnf()) {
        this.enf = new org.apache.airavata.model.error.ExperimentNotFoundException(other.enf);
      }
      if (other.isSetAce()) {
        this.ace = new org.apache.airavata.model.error.AiravataClientException(other.ace);
      }
      if (other.isSetAse()) {
        this.ase = new org.apache.airavata.model.error.AiravataSystemException(other.ase);
      }
      if (other.isSetAe()) {
        this.ae = new org.apache.airavata.model.error.AuthorizationException(other.ae);
      }
    }

    public validateExperiment_result deepCopy() {
      return new validateExperiment_result(this);
    }

    @Override
    public void clear() {
      setSuccessIsSet(false);
      this.success = false;
      this.ire = null;
      this.enf = null;
      this.ace = null;
      this.ase = null;
      this.ae = null;
    }

    public boolean isSuccess() {
      return this.success;
    }

    public validateExperiment_result setSuccess(boolean success) {
      this.success = success;
      setSuccessIsSet(true);
      return this;
    }

    public void unsetSuccess() {
      __isset_bitfield = EncodingUtils.clearBit(__isset_bitfield, __SUCCESS_ISSET_ID);
    }

    /** Returns true if field success is set (has been assigned a value) and false otherwise */
    public boolean isSetSuccess() {
      return EncodingUtils.testBit(__isset_bitfield, __SUCCESS_ISSET_ID);
    }

    public void setSuccessIsSet(boolean value) {
      __isset_bitfield = EncodingUtils.setBit(__isset_bitfield, __SUCCESS_ISSET_ID, value);
    }

    public org.apache.airavata.model.error.InvalidRequestException getIre() {
      return this.ire;
    }

    public validateExperiment_result setIre(org.apache.airavata.model.error.InvalidRequestException ire) {
      this.ire = ire;
      return this;
    }

    public void unsetIre() {
      this.ire = null;
    }

    /** Returns true if field ire is set (has been assigned a value) and false otherwise */
    public boolean isSetIre() {
      return this.ire != null;
    }

    public void setIreIsSet(boolean value) {
      if (!value) {
        this.ire = null;
      }
    }

    public org.apache.airavata.model.error.ExperimentNotFoundException getEnf() {
      return this.enf;
    }

    public validateExperiment_result setEnf(org.apache.airavata.model.error.ExperimentNotFoundException enf) {
      this.enf = enf;
      return this;
    }

    public void unsetEnf() {
      this.enf = null;
    }

    /** Returns true if field enf is set (has been assigned a value) and false otherwise */
    public boolean isSetEnf() {
      return this.enf != null;
    }

    public void setEnfIsSet(boolean value) {
      if (!value) {
        this.enf = null;
      }
    }

    public org.apache.airavata.model.error.AiravataClientException getAce() {
      return this.ace;
    }

    public validateExperiment_result setAce(org.apache.airavata.model.error.AiravataClientException ace) {
      this.ace = ace;
      return this;
    }

    public void unsetAce() {
      this.ace = null;
    }

    /** Returns true if field ace is set (has been assigned a value) and false otherwise */
    public boolean isSetAce() {
      return this.ace != null;
    }

    public void setAceIsSet(boolean value) {
      if (!value) {
        this.ace = null;
      }
    }

    public org.apache.airavata.model.error.AiravataSystemException getAse() {
      return this.ase;
    }

    public validateExperiment_result setAse(org.apache.airavata.model.error.AiravataSystemException ase) {
      this.ase = ase;
      return this;
    }

    public void unsetAse() {
      this.ase = null;
    }

    /** Returns true if field ase is set (has been assigned a value) and false otherwise */
    public boolean isSetAse() {
      return this.ase != null;
    }

    public void setAseIsSet(boolean value) {
      if (!value) {
        this.ase = null;
      }
    }

    public org.apache.airavata.model.error.AuthorizationException getAe() {
      return this.ae;
    }

    public validateExperiment_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, Object value) {
      switch (field) {
      case SUCCESS:
        if (value == null) {
          unsetSuccess();
        } else {
          setSuccess((Boolean)value);
        }
        break;

      case IRE:
        if (value == null) {
          unsetIre();
        } else {
          setIre((org.apache.airavata.model.error.InvalidRequestException)value);
        }
        break;

      case ENF:
        if (value == null) {
          unsetEnf();
        } else {
          setEnf((org.apache.airavata.model.error.ExperimentNotFoundException)value);
        }
        break;

      case ACE:
        if (value == null) {
          unsetAce();
        } else {
          setAce((org.apache.airavata.model.error.AiravataClientException)value);
        }
        break;

      case ASE:
        if (value == null) {
          unsetAse();
        } else {
          setAse((org.apache.airavata.model.error.AiravataSystemException)value);
        }
        break;

      case AE:
        if (value == null) {
          unsetAe();
        } else {
          setAe((org.apache.airavata.model.error.AuthorizationException)value);
        }
        break;

      }
    }

    public Object getFieldValue(_Fields field) {
      switch (field) {
      case SUCCESS:
        return Boolean.valueOf(isSuccess());

      case IRE:
        return getIre();

      case ENF:
        return getEnf();

      case ACE:
        return getAce();

      case ASE:
        return getAse();

      case AE:
        return getAe();

      }
      throw new IllegalStateException();
    }

    /** Returns true if field corresponding to fieldID is set (has been assigned a value) and false otherwise */
    public boolean isSet(_Fields field) {
      if (field == null) {
        throw new IllegalArgumentException();
      }

      switch (field) {
      case SUCCESS:
        return isSetSuccess();
      case IRE:
        return isSetIre();
      case ENF:
        return isSetEnf();
      case ACE:
        return isSetAce();
      case ASE:
        return isSetAse();
      case AE:
        return isSetAe();
      }
      throw new IllegalStateException();
    }

    @Override
    public boolean equals(Object that) {
      if (that == null)
        return false;
      if (that instanceof validateExperiment_result)
        return this.equals((validateExperiment_result)that);
      return false;
    }

    public boolean equals(validateExperiment_result that) {
      if (that == null)
        return false;

      boolean this_present_success = true;
      boolean that_present_success = true;
      if (this_present_success || that_present_success) {
        if (!(this_present_success && that_present_success))
          return false;
        if (this.success != that.success)
          return false;
      }

      boolean this_present_ire = true && this.isSetIre();
      boolean that_present_ire = true && that.isSetIre();
      if (this_present_ire || that_present_ire) {
        if (!(this_present_ire && that_present_ire))
          return false;
        if (!this.ire.equals(that.ire))
          return false;
      }

      boolean this_present_enf = true && this.isSetEnf();
      boolean that_present_enf = true && that.isSetEnf();
      if (this_present_enf || that_present_enf) {
        if (!(this_present_enf && that_present_enf))
          return false;
        if (!this.enf.equals(that.enf))
          return false;
      }

      boolean this_present_ace = true && this.isSetAce();
      boolean that_present_ace = true && that.isSetAce();
      if (this_present_ace || that_present_ace) {
        if (!(this_present_ace && that_present_ace))
          return false;
        if (!this.ace.equals(that.ace))
          return false;
      }

      boolean this_present_ase = true && this.isSetAse();
      boolean that_present_ase = true && that.isSetAse();
      if (this_present_ase || that_present_ase) {
        if (!(this_present_ase && that_present_ase))
          return false;
        if (!this.ase.equals(that.ase))
          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() {
      List<Object> list = new ArrayList<Object>();

      boolean present_success = true;
      list.add(present_success);
      if (present_success)
        list.add(success);

      boolean present_ire = true && (isSetIre());
      list.add(present_ire);
      if (present_ire)
        list.add(ire);

      boolean present_enf = true && (isSetEnf());
      list.add(present_enf);
      if (present_enf)
        list.add(enf);

      boolean present_ace = true && (isSetAce());
      list.add(present_ace);
      if (present_ace)
        list.add(ace);

      boolean present_ase = true && (isSetAse());
      list.add(present_ase);
      if (present_ase)
        list.add(ase);

      boolean present_ae = true && (isSetAe());
      list.add(present_ae);
      if (present_ae)
        list.add(ae);

      return list.hashCode();
    }

    @Override
    public int compareTo(validateExperiment_result other) {
      if (!getClass().equals(other.getClass())) {
        return getClass().getName().compareTo(other.getClass().getName());
      }

      int lastComparison = 0;

      lastComparison = Boolean.valueOf(isSetSuccess()).compareTo(other.isSetSuccess());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetSuccess()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.success, other.success);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = Boolean.valueOf(isSetIre()).compareTo(other.isSetIre());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetIre()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.ire, other.ire);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = Boolean.valueOf(isSetEnf()).compareTo(other.isSetEnf());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetEnf()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.enf, other.enf);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = Boolean.valueOf(isSetAce()).compareTo(other.isSetAce());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetAce()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.ace, other.ace);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = Boolean.valueOf(isSetAse()).compareTo(other.isSetAse());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetAse()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.ase, other.ase);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = 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 {
      schemes.get(iprot.getScheme()).getScheme().read(iprot, this);
    }

    public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException {
      schemes.get(oprot.getScheme()).getScheme().write(oprot, this);
      }

    @Override
    public String toString() {
      StringBuilder sb = new StringBuilder("validateExperiment_result(");
      boolean first = true;

      sb.append("success:");
      sb.append(this.success);
      first = false;
      if (!first) sb.append(", ");
      sb.append("ire:");
      if (this.ire == null) {
        sb.append("null");
      } else {
        sb.append(this.ire);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("enf:");
      if (this.enf == null) {
        sb.append("null");
      } else {
        sb.append(this.enf);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("ace:");
      if (this.ace == null) {
        sb.append("null");
      } else {
        sb.append(this.ace);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("ase:");
      if (this.ase == null) {
        sb.append("null");
      } else {
        sb.append(this.ase);
      }
      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, 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 validateExperiment_resultStandardSchemeFactory implements SchemeFactory {
      public validateExperiment_resultStandardScheme getScheme() {
        return new validateExperiment_resultStandardScheme();
      }
    }

    private static class validateExperiment_resultStandardScheme extends StandardScheme<validateExperiment_result> {

      public void read(org.apache.thrift.protocol.TProtocol iprot, validateExperiment_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: // IRE
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.ire = new org.apache.airavata.model.error.InvalidRequestException();
                struct.ire.read(iprot);
                struct.setIreIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 2: // ENF
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.enf = new org.apache.airavata.model.error.ExperimentNotFoundException();
                struct.enf.read(iprot);
                struct.setEnfIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 3: // ACE
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.ace = new org.apache.airavata.model.error.AiravataClientException();
                struct.ace.read(iprot);
                struct.setAceIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 4: // ASE
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.ase = new org.apache.airavata.model.error.AiravataSystemException();
                struct.ase.read(iprot);
                struct.setAseIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 5: // 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, validateExperiment_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.ire != null) {
          oprot.writeFieldBegin(IRE_FIELD_DESC);
          struct.ire.write(oprot);
          oprot.writeFieldEnd();
        }
        if (struct.enf != null) {
          oprot.writeFieldBegin(ENF_FIELD_DESC);
          struct.enf.write(oprot);
          oprot.writeFieldEnd();
        }
        if (struct.ace != null) {
          oprot.writeFieldBegin(ACE_FIELD_DESC);
          struct.ace.write(oprot);
          oprot.writeFieldEnd();
        }
        if (struct.ase != null) {
          oprot.writeFieldBegin(ASE_FIELD_DESC);
          struct.ase.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 validateExperiment_resultTupleSchemeFactory implements SchemeFactory {
      public validateExperiment_resultTupleScheme getScheme() {
        return new validateExperiment_resultTupleScheme();
      }
    }

    private static class validateExperiment_resultTupleScheme extends TupleScheme<validateExperiment_result> {

      @Override
      public void write(org.apache.thrift.protocol.TProtocol prot, validateExperiment_result struct) throws org.apache.thrift.TException {
        TTupleProtocol oprot = (TTupleProtocol) prot;
        BitSet optionals = new BitSet();
        if (struct.isSetSuccess()) {
          optionals.set(0);
        }
        if (struct.isSetIre()) {
          optionals.set(1);
        }
        if (struct.isSetEnf()) {
          optionals.set(2);
        }
        if (struct.isSetAce()) {
          optionals.set(3);
        }
        if (struct.isSetAse()) {
          optionals.set(4);
        }
        if (struct.isSetAe()) {
          optionals.set(5);
        }
        oprot.writeBitSet(optionals, 6);
        if (struct.isSetSuccess()) {
          oprot.writeBool(struct.success);
        }
        if (struct.isSetIre()) {
          struct.ire.write(oprot);
        }
        if (struct.isSetEnf()) {
          struct.enf.write(oprot);
        }
        if (struct.isSetAce()) {
          struct.ace.write(oprot);
        }
        if (struct.isSetAse()) {
          struct.ase.write(oprot);
        }
        if (struct.isSetAe()) {
          struct.ae.write(oprot);
        }
      }

      @Override
      public void read(org.apache.thrift.protocol.TProtocol prot, validateExperiment_result struct) throws org.apache.thrift.TException {
        TTupleProtocol iprot = (TTupleProtocol) prot;
        BitSet incoming = iprot.readBitSet(6);
        if (incoming.get(0)) {
          struct.success = iprot.readBool();
          struct.setSuccessIsSet(true);
        }
        if (incoming.get(1)) {
          struct.ire = new org.apache.airavata.model.error.InvalidRequestException();
          struct.ire.read(iprot);
          struct.setIreIsSet(true);
        }
        if (incoming.get(2)) {
          struct.enf = new org.apache.airavata.model.error.ExperimentNotFoundException();
          struct.enf.read(iprot);
          struct.setEnfIsSet(true);
        }
        if (incoming.get(3)) {
          struct.ace = new org.apache.airavata.model.error.AiravataClientException();
          struct.ace.read(iprot);
          struct.setAceIsSet(true);
        }
        if (incoming.get(4)) {
          struct.ase = new org.apache.airavata.model.error.AiravataSystemException();
          struct.ase.read(iprot);
          struct.setAseIsSet(true);
        }
        if (incoming.get(5)) {
          struct.ae = new org.apache.airavata.model.error.AuthorizationException();
          struct.ae.read(iprot);
          struct.setAeIsSet(true);
        }
      }
    }

  }

  public static class launchExperiment_args implements org.apache.thrift.TBase<launchExperiment_args, launchExperiment_args._Fields>, java.io.Serializable, Cloneable, Comparable<launchExperiment_args>   {
    private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("launchExperiment_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_EXPERIMENT_ID_FIELD_DESC = new org.apache.thrift.protocol.TField("airavataExperimentId", 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 Map<Class<? extends IScheme>, SchemeFactory> schemes = new HashMap<Class<? extends IScheme>, SchemeFactory>();
    static {
      schemes.put(StandardScheme.class, new launchExperiment_argsStandardSchemeFactory());
      schemes.put(TupleScheme.class, new launchExperiment_argsTupleSchemeFactory());
    }

    public org.apache.airavata.model.security.AuthzToken authzToken; // required
    public String airavataExperimentId; // required
    public 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_EXPERIMENT_ID((short)2, "airavataExperimentId"),
      GATEWAY_ID((short)3, "gatewayId");

      private static final Map<String, _Fields> byName = new HashMap<String, _Fields>();

      static {
        for (_Fields field : EnumSet.allOf(_Fields.class)) {
          byName.put(field.getFieldName(), field);
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, or null if its not found.
       */
      public static _Fields findByThriftId(int fieldId) {
        switch(fieldId) {
          case 1: // AUTHZ_TOKEN
            return AUTHZ_TOKEN;
          case 2: // AIRAVATA_EXPERIMENT_ID
            return AIRAVATA_EXPERIMENT_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 IllegalArgumentException("Field " + fieldId + " doesn't exist!");
        return fields;
      }

      /**
       * Find the _Fields constant that matches name, or null if its not found.
       */
      public static _Fields findByName(String name) {
        return byName.get(name);
      }

      private final short _thriftId;
      private final String _fieldName;

      _Fields(short thriftId, String fieldName) {
        _thriftId = thriftId;
        _fieldName = fieldName;
      }

      public short getThriftFieldId() {
        return _thriftId;
      }

      public String getFieldName() {
        return _fieldName;
      }
    }

    // isset id assignments
    public static final Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
    static {
      Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new EnumMap<_Fields, org.apache.thrift.meta_data.FieldMetaData>(_Fields.class);
      tmpMap.put(_Fields.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_EXPERIMENT_ID, new org.apache.thrift.meta_data.FieldMetaData("airavataExperimentId", 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 = Collections.unmodifiableMap(tmpMap);
      org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(launchExperiment_args.class, metaDataMap);
    }

    public launchExperiment_args() {
    }

    public launchExperiment_args(
      org.apache.airavata.model.security.AuthzToken authzToken,
      String airavataExperimentId,
      String gatewayId)
    {
      this();
      this.authzToken = authzToken;
      this.airavataExperimentId = airavataExperimentId;
      this.gatewayId = gatewayId;
    }

    /**
     * Performs a deep copy on <i>other</i>.
     */
    public launchExperiment_args(launchExperiment_args other) {
      if (other.isSetAuthzToken()) {
        this.authzToken = new org.apache.airavata.model.security.AuthzToken(other.authzToken);
      }
      if (other.isSetAiravataExperimentId()) {
        this.airavataExperimentId = other.airavataExperimentId;
      }
      if (other.isSetGatewayId()) {
        this.gatewayId = other.gatewayId;
      }
    }

    public launchExperiment_args deepCopy() {
      return new launchExperiment_args(this);
    }

    @Override
    public void clear() {
      this.authzToken = null;
      this.airavataExperimentId = null;
      this.gatewayId = null;
    }

    public org.apache.airavata.model.security.AuthzToken getAuthzToken() {
      return this.authzToken;
    }

    public launchExperiment_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 String getAiravataExperimentId() {
      return this.airavataExperimentId;
    }

    public launchExperiment_args setAiravataExperimentId(String airavataExperimentId) {
      this.airavataExperimentId = airavataExperimentId;
      return this;
    }

    public void unsetAiravataExperimentId() {
      this.airavataExperimentId = null;
    }

    /** Returns true if field airavataExperimentId is set (has been assigned a value) and false otherwise */
    public boolean isSetAiravataExperimentId() {
      return this.airavataExperimentId != null;
    }

    public void setAiravataExperimentIdIsSet(boolean value) {
      if (!value) {
        this.airavataExperimentId = null;
      }
    }

    public String getGatewayId() {
      return this.gatewayId;
    }

    public launchExperiment_args setGatewayId(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, Object value) {
      switch (field) {
      case AUTHZ_TOKEN:
        if (value == null) {
          unsetAuthzToken();
        } else {
          setAuthzToken((org.apache.airavata.model.security.AuthzToken)value);
        }
        break;

      case AIRAVATA_EXPERIMENT_ID:
        if (value == null) {
          unsetAiravataExperimentId();
        } else {
          setAiravataExperimentId((String)value);
        }
        break;

      case GATEWAY_ID:
        if (value == null) {
          unsetGatewayId();
        } else {
          setGatewayId((String)value);
        }
        break;

      }
    }

    public Object getFieldValue(_Fields field) {
      switch (field) {
      case AUTHZ_TOKEN:
        return getAuthzToken();

      case AIRAVATA_EXPERIMENT_ID:
        return getAiravataExperimentId();

      case GATEWAY_ID:
        return getGatewayId();

      }
      throw new IllegalStateException();
    }

    /** Returns true if field corresponding to fieldID is set (has been assigned a value) and false otherwise */
    public boolean isSet(_Fields field) {
      if (field == null) {
        throw new IllegalArgumentException();
      }

      switch (field) {
      case AUTHZ_TOKEN:
        return isSetAuthzToken();
      case AIRAVATA_EXPERIMENT_ID:
        return isSetAiravataExperimentId();
      case GATEWAY_ID:
        return isSetGatewayId();
      }
      throw new IllegalStateException();
    }

    @Override
    public boolean equals(Object that) {
      if (that == null)
        return false;
      if (that instanceof launchExperiment_args)
        return this.equals((launchExperiment_args)that);
      return false;
    }

    public boolean equals(launchExperiment_args that) {
      if (that == null)
        return false;

      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_airavataExperimentId = true && this.isSetAiravataExperimentId();
      boolean that_present_airavataExperimentId = true && that.isSetAiravataExperimentId();
      if (this_present_airavataExperimentId || that_present_airavataExperimentId) {
        if (!(this_present_airavataExperimentId && that_present_airavataExperimentId))
          return false;
        if (!this.airavataExperimentId.equals(that.airavataExperimentId))
          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() {
      List<Object> list = new ArrayList<Object>();

      boolean present_authzToken = true && (isSetAuthzToken());
      list.add(present_authzToken);
      if (present_authzToken)
        list.add(authzToken);

      boolean present_airavataExperimentId = true && (isSetAiravataExperimentId());
      list.add(present_airavataExperimentId);
      if (present_airavataExperimentId)
        list.add(airavataExperimentId);

      boolean present_gatewayId = true && (isSetGatewayId());
      list.add(present_gatewayId);
      if (present_gatewayId)
        list.add(gatewayId);

      return list.hashCode();
    }

    @Override
    public int compareTo(launchExperiment_args other) {
      if (!getClass().equals(other.getClass())) {
        return getClass().getName().compareTo(other.getClass().getName());
      }

      int lastComparison = 0;

      lastComparison = 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 = Boolean.valueOf(isSetAiravataExperimentId()).compareTo(other.isSetAiravataExperimentId());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetAiravataExperimentId()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.airavataExperimentId, other.airavataExperimentId);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = 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 {
      schemes.get(iprot.getScheme()).getScheme().read(iprot, this);
    }

    public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException {
      schemes.get(oprot.getScheme()).getScheme().write(oprot, this);
    }

    @Override
    public String toString() {
      StringBuilder sb = new StringBuilder("launchExperiment_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("airavataExperimentId:");
      if (this.airavataExperimentId == null) {
        sb.append("null");
      } else {
        sb.append(this.airavataExperimentId);
      }
      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 (airavataExperimentId == null) {
        throw new org.apache.thrift.protocol.TProtocolException("Required field 'airavataExperimentId' 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, 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 launchExperiment_argsStandardSchemeFactory implements SchemeFactory {
      public launchExperiment_argsStandardScheme getScheme() {
        return new launchExperiment_argsStandardScheme();
      }
    }

    private static class launchExperiment_argsStandardScheme extends StandardScheme<launchExperiment_args> {

      public void read(org.apache.thrift.protocol.TProtocol iprot, launchExperiment_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_EXPERIMENT_ID
              if (schemeField.type == org.apache.thrift.protocol.TType.STRING) {
                struct.airavataExperimentId = iprot.readString();
                struct.setAiravataExperimentIdIsSet(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, launchExperiment_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.airavataExperimentId != null) {
          oprot.writeFieldBegin(AIRAVATA_EXPERIMENT_ID_FIELD_DESC);
          oprot.writeString(struct.airavataExperimentId);
          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 launchExperiment_argsTupleSchemeFactory implements SchemeFactory {
      public launchExperiment_argsTupleScheme getScheme() {
        return new launchExperiment_argsTupleScheme();
      }
    }

    private static class launchExperiment_argsTupleScheme extends TupleScheme<launchExperiment_args> {

      @Override
      public void write(org.apache.thrift.protocol.TProtocol prot, launchExperiment_args struct) throws org.apache.thrift.TException {
        TTupleProtocol oprot = (TTupleProtocol) prot;
        struct.authzToken.write(oprot);
        oprot.writeString(struct.airavataExperimentId);
        oprot.writeString(struct.gatewayId);
      }

      @Override
      public void read(org.apache.thrift.protocol.TProtocol prot, launchExperiment_args struct) throws org.apache.thrift.TException {
        TTupleProtocol iprot = (TTupleProtocol) prot;
        struct.authzToken = new org.apache.airavata.model.security.AuthzToken();
        struct.authzToken.read(iprot);
        struct.setAuthzTokenIsSet(true);
        struct.airavataExperimentId = iprot.readString();
        struct.setAiravataExperimentIdIsSet(true);
        struct.gatewayId = iprot.readString();
        struct.setGatewayIdIsSet(true);
      }
    }

  }

  public static class launchExperiment_result implements org.apache.thrift.TBase<launchExperiment_result, launchExperiment_result._Fields>, java.io.Serializable, Cloneable, Comparable<launchExperiment_result>   {
    private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("launchExperiment_result");

    private static final org.apache.thrift.protocol.TField IRE_FIELD_DESC = new org.apache.thrift.protocol.TField("ire", org.apache.thrift.protocol.TType.STRUCT, (short)1);
    private static final org.apache.thrift.protocol.TField ENF_FIELD_DESC = new org.apache.thrift.protocol.TField("enf", org.apache.thrift.protocol.TType.STRUCT, (short)2);
    private static final org.apache.thrift.protocol.TField ACE_FIELD_DESC = new org.apache.thrift.protocol.TField("ace", org.apache.thrift.protocol.TType.STRUCT, (short)3);
    private static final org.apache.thrift.protocol.TField ASE_FIELD_DESC = new org.apache.thrift.protocol.TField("ase", org.apache.thrift.protocol.TType.STRUCT, (short)4);
    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)5);

    private static final Map<Class<? extends IScheme>, SchemeFactory> schemes = new HashMap<Class<? extends IScheme>, SchemeFactory>();
    static {
      schemes.put(StandardScheme.class, new launchExperiment_resultStandardSchemeFactory());
      schemes.put(TupleScheme.class, new launchExperiment_resultTupleSchemeFactory());
    }

    public org.apache.airavata.model.error.InvalidRequestException ire; // required
    public org.apache.airavata.model.error.ExperimentNotFoundException enf; // required
    public org.apache.airavata.model.error.AiravataClientException ace; // required
    public org.apache.airavata.model.error.AiravataSystemException ase; // 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 {
      IRE((short)1, "ire"),
      ENF((short)2, "enf"),
      ACE((short)3, "ace"),
      ASE((short)4, "ase"),
      AE((short)5, "ae");

      private static final Map<String, _Fields> byName = new HashMap<String, _Fields>();

      static {
        for (_Fields field : EnumSet.allOf(_Fields.class)) {
          byName.put(field.getFieldName(), field);
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, or null if its not found.
       */
      public static _Fields findByThriftId(int fieldId) {
        switch(fieldId) {
          case 1: // IRE
            return IRE;
          case 2: // ENF
            return ENF;
          case 3: // ACE
            return ACE;
          case 4: // ASE
            return ASE;
          case 5: // 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 IllegalArgumentException("Field " + fieldId + " doesn't exist!");
        return fields;
      }

      /**
       * Find the _Fields constant that matches name, or null if its not found.
       */
      public static _Fields findByName(String name) {
        return byName.get(name);
      }

      private final short _thriftId;
      private final String _fieldName;

      _Fields(short thriftId, String fieldName) {
        _thriftId = thriftId;
        _fieldName = fieldName;
      }

      public short getThriftFieldId() {
        return _thriftId;
      }

      public String getFieldName() {
        return _fieldName;
      }
    }

    // isset id assignments
    public static final Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
    static {
      Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new EnumMap<_Fields, org.apache.thrift.meta_data.FieldMetaData>(_Fields.class);
      tmpMap.put(_Fields.IRE, new org.apache.thrift.meta_data.FieldMetaData("ire", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRUCT)));
      tmpMap.put(_Fields.ENF, new org.apache.thrift.meta_data.FieldMetaData("enf", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRUCT)));
      tmpMap.put(_Fields.ACE, new org.apache.thrift.meta_data.FieldMetaData("ace", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRUCT)));
      tmpMap.put(_Fields.ASE, new org.apache.thrift.meta_data.FieldMetaData("ase", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRUCT)));
      tmpMap.put(_Fields.AE, new org.apache.thrift.meta_data.FieldMetaData("ae", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRUCT)));
      metaDataMap = Collections.unmodifiableMap(tmpMap);
      org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(launchExperiment_result.class, metaDataMap);
    }

    public launchExperiment_result() {
    }

    public launchExperiment_result(
      org.apache.airavata.model.error.InvalidRequestException ire,
      org.apache.airavata.model.error.ExperimentNotFoundException enf,
      org.apache.airavata.model.error.AiravataClientException ace,
      org.apache.airavata.model.error.AiravataSystemException ase,
      org.apache.airavata.model.error.AuthorizationException ae)
    {
      this();
      this.ire = ire;
      this.enf = enf;
      this.ace = ace;
      this.ase = ase;
      this.ae = ae;
    }

    /**
     * Performs a deep copy on <i>other</i>.
     */
    public launchExperiment_result(launchExperiment_result other) {
      if (other.isSetIre()) {
        this.ire = new org.apache.airavata.model.error.InvalidRequestException(other.ire);
      }
      if (other.isSetEnf()) {
        this.enf = new org.apache.airavata.model.error.ExperimentNotFoundException(other.enf);
      }
      if (other.isSetAce()) {
        this.ace = new org.apache.airavata.model.error.AiravataClientException(other.ace);
      }
      if (other.isSetAse()) {
        this.ase = new org.apache.airavata.model.error.AiravataSystemException(other.ase);
      }
      if (other.isSetAe()) {
        this.ae = new org.apache.airavata.model.error.AuthorizationException(other.ae);
      }
    }

    public launchExperiment_result deepCopy() {
      return new launchExperiment_result(this);
    }

    @Override
    public void clear() {
      this.ire = null;
      this.enf = null;
      this.ace = null;
      this.ase = null;
      this.ae = null;
    }

    public org.apache.airavata.model.error.InvalidRequestException getIre() {
      return this.ire;
    }

    public launchExperiment_result setIre(org.apache.airavata.model.error.InvalidRequestException ire) {
      this.ire = ire;
      return this;
    }

    public void unsetIre() {
      this.ire = null;
    }

    /** Returns true if field ire is set (has been assigned a value) and false otherwise */
    public boolean isSetIre() {
      return this.ire != null;
    }

    public void setIreIsSet(boolean value) {
      if (!value) {
        this.ire = null;
      }
    }

    public org.apache.airavata.model.error.ExperimentNotFoundException getEnf() {
      return this.enf;
    }

    public launchExperiment_result setEnf(org.apache.airavata.model.error.ExperimentNotFoundException enf) {
      this.enf = enf;
      return this;
    }

    public void unsetEnf() {
      this.enf = null;
    }

    /** Returns true if field enf is set (has been assigned a value) and false otherwise */
    public boolean isSetEnf() {
      return this.enf != null;
    }

    public void setEnfIsSet(boolean value) {
      if (!value) {
        this.enf = null;
      }
    }

    public org.apache.airavata.model.error.AiravataClientException getAce() {
      return this.ace;
    }

    public launchExperiment_result setAce(org.apache.airavata.model.error.AiravataClientException ace) {
      this.ace = ace;
      return this;
    }

    public void unsetAce() {
      this.ace = null;
    }

    /** Returns true if field ace is set (has been assigned a value) and false otherwise */
    public boolean isSetAce() {
      return this.ace != null;
    }

    public void setAceIsSet(boolean value) {
      if (!value) {
        this.ace = null;
      }
    }

    public org.apache.airavata.model.error.AiravataSystemException getAse() {
      return this.ase;
    }

    public launchExperiment_result setAse(org.apache.airavata.model.error.AiravataSystemException ase) {
      this.ase = ase;
      return this;
    }

    public void unsetAse() {
      this.ase = null;
    }

    /** Returns true if field ase is set (has been assigned a value) and false otherwise */
    public boolean isSetAse() {
      return this.ase != null;
    }

    public void setAseIsSet(boolean value) {
      if (!value) {
        this.ase = null;
      }
    }

    public org.apache.airavata.model.error.AuthorizationException getAe() {
      return this.ae;
    }

    public launchExperiment_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, Object value) {
      switch (field) {
      case IRE:
        if (value == null) {
          unsetIre();
        } else {
          setIre((org.apache.airavata.model.error.InvalidRequestException)value);
        }
        break;

      case ENF:
        if (value == null) {
          unsetEnf();
        } else {
          setEnf((org.apache.airavata.model.error.ExperimentNotFoundException)value);
        }
        break;

      case ACE:
        if (value == null) {
          unsetAce();
        } else {
          setAce((org.apache.airavata.model.error.AiravataClientException)value);
        }
        break;

      case ASE:
        if (value == null) {
          unsetAse();
        } else {
          setAse((org.apache.airavata.model.error.AiravataSystemException)value);
        }
        break;

      case AE:
        if (value == null) {
          unsetAe();
        } else {
          setAe((org.apache.airavata.model.error.AuthorizationException)value);
        }
        break;

      }
    }

    public Object getFieldValue(_Fields field) {
      switch (field) {
      case IRE:
        return getIre();

      case ENF:
        return getEnf();

      case ACE:
        return getAce();

      case ASE:
        return getAse();

      case AE:
        return getAe();

      }
      throw new IllegalStateException();
    }

    /** Returns true if field corresponding to fieldID is set (has been assigned a value) and false otherwise */
    public boolean isSet(_Fields field) {
      if (field == null) {
        throw new IllegalArgumentException();
      }

      switch (field) {
      case IRE:
        return isSetIre();
      case ENF:
        return isSetEnf();
      case ACE:
        return isSetAce();
      case ASE:
        return isSetAse();
      case AE:
        return isSetAe();
      }
      throw new IllegalStateException();
    }

    @Override
    public boolean equals(Object that) {
      if (that == null)
        return false;
      if (that instanceof launchExperiment_result)
        return this.equals((launchExperiment_result)that);
      return false;
    }

    public boolean equals(launchExperiment_result that) {
      if (that == null)
        return false;

      boolean this_present_ire = true && this.isSetIre();
      boolean that_present_ire = true && that.isSetIre();
      if (this_present_ire || that_present_ire) {
        if (!(this_present_ire && that_present_ire))
          return false;
        if (!this.ire.equals(that.ire))
          return false;
      }

      boolean this_present_enf = true && this.isSetEnf();
      boolean that_present_enf = true && that.isSetEnf();
      if (this_present_enf || that_present_enf) {
        if (!(this_present_enf && that_present_enf))
          return false;
        if (!this.enf.equals(that.enf))
          return false;
      }

      boolean this_present_ace = true && this.isSetAce();
      boolean that_present_ace = true && that.isSetAce();
      if (this_present_ace || that_present_ace) {
        if (!(this_present_ace && that_present_ace))
          return false;
        if (!this.ace.equals(that.ace))
          return false;
      }

      boolean this_present_ase = true && this.isSetAse();
      boolean that_present_ase = true && that.isSetAse();
      if (this_present_ase || that_present_ase) {
        if (!(this_present_ase && that_present_ase))
          return false;
        if (!this.ase.equals(that.ase))
          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() {
      List<Object> list = new ArrayList<Object>();

      boolean present_ire = true && (isSetIre());
      list.add(present_ire);
      if (present_ire)
        list.add(ire);

      boolean present_enf = true && (isSetEnf());
      list.add(present_enf);
      if (present_enf)
        list.add(enf);

      boolean present_ace = true && (isSetAce());
      list.add(present_ace);
      if (present_ace)
        list.add(ace);

      boolean present_ase = true && (isSetAse());
      list.add(present_ase);
      if (present_ase)
        list.add(ase);

      boolean present_ae = true && (isSetAe());
      list.add(present_ae);
      if (present_ae)
        list.add(ae);

      return list.hashCode();
    }

    @Override
    public int compareTo(launchExperiment_result other) {
      if (!getClass().equals(other.getClass())) {
        return getClass().getName().compareTo(other.getClass().getName());
      }

      int lastComparison = 0;

      lastComparison = Boolean.valueOf(isSetIre()).compareTo(other.isSetIre());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetIre()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.ire, other.ire);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = Boolean.valueOf(isSetEnf()).compareTo(other.isSetEnf());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetEnf()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.enf, other.enf);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = Boolean.valueOf(isSetAce()).compareTo(other.isSetAce());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetAce()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.ace, other.ace);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = Boolean.valueOf(isSetAse()).compareTo(other.isSetAse());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetAse()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.ase, other.ase);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = 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 {
      schemes.get(iprot.getScheme()).getScheme().read(iprot, this);
    }

    public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException {
      schemes.get(oprot.getScheme()).getScheme().write(oprot, this);
      }

    @Override
    public String toString() {
      StringBuilder sb = new StringBuilder("launchExperiment_result(");
      boolean first = true;

      sb.append("ire:");
      if (this.ire == null) {
        sb.append("null");
      } else {
        sb.append(this.ire);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("enf:");
      if (this.enf == null) {
        sb.append("null");
      } else {
        sb.append(this.enf);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("ace:");
      if (this.ace == null) {
        sb.append("null");
      } else {
        sb.append(this.ace);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("ase:");
      if (this.ase == null) {
        sb.append("null");
      } else {
        sb.append(this.ase);
      }
      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, 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 launchExperiment_resultStandardSchemeFactory implements SchemeFactory {
      public launchExperiment_resultStandardScheme getScheme() {
        return new launchExperiment_resultStandardScheme();
      }
    }

    private static class launchExperiment_resultStandardScheme extends StandardScheme<launchExperiment_result> {

      public void read(org.apache.thrift.protocol.TProtocol iprot, launchExperiment_result struct) throws org.apache.thrift.TException {
        org.apache.thrift.protocol.TField schemeField;
        iprot.readStructBegin();
        while (true)
        {
          schemeField = iprot.readFieldBegin();
          if (schemeField.type == org.apache.thrift.protocol.TType.STOP) { 
            break;
          }
          switch (schemeField.id) {
            case 1: // IRE
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.ire = new org.apache.airavata.model.error.InvalidRequestException();
                struct.ire.read(iprot);
                struct.setIreIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 2: // ENF
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.enf = new org.apache.airavata.model.error.ExperimentNotFoundException();
                struct.enf.read(iprot);
                struct.setEnfIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 3: // ACE
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.ace = new org.apache.airavata.model.error.AiravataClientException();
                struct.ace.read(iprot);
                struct.setAceIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 4: // ASE
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.ase = new org.apache.airavata.model.error.AiravataSystemException();
                struct.ase.read(iprot);
                struct.setAseIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 5: // 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, launchExperiment_result struct) throws org.apache.thrift.TException {
        struct.validate();

        oprot.writeStructBegin(STRUCT_DESC);
        if (struct.ire != null) {
          oprot.writeFieldBegin(IRE_FIELD_DESC);
          struct.ire.write(oprot);
          oprot.writeFieldEnd();
        }
        if (struct.enf != null) {
          oprot.writeFieldBegin(ENF_FIELD_DESC);
          struct.enf.write(oprot);
          oprot.writeFieldEnd();
        }
        if (struct.ace != null) {
          oprot.writeFieldBegin(ACE_FIELD_DESC);
          struct.ace.write(oprot);
          oprot.writeFieldEnd();
        }
        if (struct.ase != null) {
          oprot.writeFieldBegin(ASE_FIELD_DESC);
          struct.ase.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 launchExperiment_resultTupleSchemeFactory implements SchemeFactory {
      public launchExperiment_resultTupleScheme getScheme() {
        return new launchExperiment_resultTupleScheme();
      }
    }

    private static class launchExperiment_resultTupleScheme extends TupleScheme<launchExperiment_result> {

      @Override
      public void write(org.apache.thrift.protocol.TProtocol prot, launchExperiment_result struct) throws org.apache.thrift.TException {
        TTupleProtocol oprot = (TTupleProtocol) prot;
        BitSet optionals = new BitSet();
        if (struct.isSetIre()) {
          optionals.set(0);
        }
        if (struct.isSetEnf()) {
          optionals.set(1);
        }
        if (struct.isSetAce()) {
          optionals.set(2);
        }
        if (struct.isSetAse()) {
          optionals.set(3);
        }
        if (struct.isSetAe()) {
          optionals.set(4);
        }
        oprot.writeBitSet(optionals, 5);
        if (struct.isSetIre()) {
          struct.ire.write(oprot);
        }
        if (struct.isSetEnf()) {
          struct.enf.write(oprot);
        }
        if (struct.isSetAce()) {
          struct.ace.write(oprot);
        }
        if (struct.isSetAse()) {
          struct.ase.write(oprot);
        }
        if (struct.isSetAe()) {
          struct.ae.write(oprot);
        }
      }

      @Override
      public void read(org.apache.thrift.protocol.TProtocol prot, launchExperiment_result struct) throws org.apache.thrift.TException {
        TTupleProtocol iprot = (TTupleProtocol) prot;
        BitSet incoming = iprot.readBitSet(5);
        if (incoming.get(0)) {
          struct.ire = new org.apache.airavata.model.error.InvalidRequestException();
          struct.ire.read(iprot);
          struct.setIreIsSet(true);
        }
        if (incoming.get(1)) {
          struct.enf = new org.apache.airavata.model.error.ExperimentNotFoundException();
          struct.enf.read(iprot);
          struct.setEnfIsSet(true);
        }
        if (incoming.get(2)) {
          struct.ace = new org.apache.airavata.model.error.AiravataClientException();
          struct.ace.read(iprot);
          struct.setAceIsSet(true);
        }
        if (incoming.get(3)) {
          struct.ase = new org.apache.airavata.model.error.AiravataSystemException();
          struct.ase.read(iprot);
          struct.setAseIsSet(true);
        }
        if (incoming.get(4)) {
          struct.ae = new org.apache.airavata.model.error.AuthorizationException();
          struct.ae.read(iprot);
          struct.setAeIsSet(true);
        }
      }
    }

  }

  public static class getExperimentStatus_args implements org.apache.thrift.TBase<getExperimentStatus_args, getExperimentStatus_args._Fields>, java.io.Serializable, Cloneable, Comparable<getExperimentStatus_args>   {
    private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("getExperimentStatus_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_EXPERIMENT_ID_FIELD_DESC = new org.apache.thrift.protocol.TField("airavataExperimentId", org.apache.thrift.protocol.TType.STRING, (short)2);

    private static final Map<Class<? extends IScheme>, SchemeFactory> schemes = new HashMap<Class<? extends IScheme>, SchemeFactory>();
    static {
      schemes.put(StandardScheme.class, new getExperimentStatus_argsStandardSchemeFactory());
      schemes.put(TupleScheme.class, new getExperimentStatus_argsTupleSchemeFactory());
    }

    public org.apache.airavata.model.security.AuthzToken authzToken; // required
    public String airavataExperimentId; // required

    /** 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_EXPERIMENT_ID((short)2, "airavataExperimentId");

      private static final Map<String, _Fields> byName = new HashMap<String, _Fields>();

      static {
        for (_Fields field : EnumSet.allOf(_Fields.class)) {
          byName.put(field.getFieldName(), field);
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, or null if its not found.
       */
      public static _Fields findByThriftId(int fieldId) {
        switch(fieldId) {
          case 1: // AUTHZ_TOKEN
            return AUTHZ_TOKEN;
          case 2: // AIRAVATA_EXPERIMENT_ID
            return AIRAVATA_EXPERIMENT_ID;
          default:
            return null;
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, throwing an exception
       * if it is not found.
       */
      public static _Fields findByThriftIdOrThrow(int fieldId) {
        _Fields fields = findByThriftId(fieldId);
        if (fields == null) throw new IllegalArgumentException("Field " + fieldId + " doesn't exist!");
        return fields;
      }

      /**
       * Find the _Fields constant that matches name, or null if its not found.
       */
      public static _Fields findByName(String name) {
        return byName.get(name);
      }

      private final short _thriftId;
      private final String _fieldName;

      _Fields(short thriftId, String fieldName) {
        _thriftId = thriftId;
        _fieldName = fieldName;
      }

      public short getThriftFieldId() {
        return _thriftId;
      }

      public String getFieldName() {
        return _fieldName;
      }
    }

    // isset id assignments
    public static final Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
    static {
      Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new EnumMap<_Fields, org.apache.thrift.meta_data.FieldMetaData>(_Fields.class);
      tmpMap.put(_Fields.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_EXPERIMENT_ID, new org.apache.thrift.meta_data.FieldMetaData("airavataExperimentId", org.apache.thrift.TFieldRequirementType.REQUIRED, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING)));
      metaDataMap = Collections.unmodifiableMap(tmpMap);
      org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(getExperimentStatus_args.class, metaDataMap);
    }

    public getExperimentStatus_args() {
    }

    public getExperimentStatus_args(
      org.apache.airavata.model.security.AuthzToken authzToken,
      String airavataExperimentId)
    {
      this();
      this.authzToken = authzToken;
      this.airavataExperimentId = airavataExperimentId;
    }

    /**
     * Performs a deep copy on <i>other</i>.
     */
    public getExperimentStatus_args(getExperimentStatus_args other) {
      if (other.isSetAuthzToken()) {
        this.authzToken = new org.apache.airavata.model.security.AuthzToken(other.authzToken);
      }
      if (other.isSetAiravataExperimentId()) {
        this.airavataExperimentId = other.airavataExperimentId;
      }
    }

    public getExperimentStatus_args deepCopy() {
      return new getExperimentStatus_args(this);
    }

    @Override
    public void clear() {
      this.authzToken = null;
      this.airavataExperimentId = null;
    }

    public org.apache.airavata.model.security.AuthzToken getAuthzToken() {
      return this.authzToken;
    }

    public getExperimentStatus_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 String getAiravataExperimentId() {
      return this.airavataExperimentId;
    }

    public getExperimentStatus_args setAiravataExperimentId(String airavataExperimentId) {
      this.airavataExperimentId = airavataExperimentId;
      return this;
    }

    public void unsetAiravataExperimentId() {
      this.airavataExperimentId = null;
    }

    /** Returns true if field airavataExperimentId is set (has been assigned a value) and false otherwise */
    public boolean isSetAiravataExperimentId() {
      return this.airavataExperimentId != null;
    }

    public void setAiravataExperimentIdIsSet(boolean value) {
      if (!value) {
        this.airavataExperimentId = null;
      }
    }

    public void setFieldValue(_Fields field, Object value) {
      switch (field) {
      case AUTHZ_TOKEN:
        if (value == null) {
          unsetAuthzToken();
        } else {
          setAuthzToken((org.apache.airavata.model.security.AuthzToken)value);
        }
        break;

      case AIRAVATA_EXPERIMENT_ID:
        if (value == null) {
          unsetAiravataExperimentId();
        } else {
          setAiravataExperimentId((String)value);
        }
        break;

      }
    }

    public Object getFieldValue(_Fields field) {
      switch (field) {
      case AUTHZ_TOKEN:
        return getAuthzToken();

      case AIRAVATA_EXPERIMENT_ID:
        return getAiravataExperimentId();

      }
      throw new IllegalStateException();
    }

    /** Returns true if field corresponding to fieldID is set (has been assigned a value) and false otherwise */
    public boolean isSet(_Fields field) {
      if (field == null) {
        throw new IllegalArgumentException();
      }

      switch (field) {
      case AUTHZ_TOKEN:
        return isSetAuthzToken();
      case AIRAVATA_EXPERIMENT_ID:
        return isSetAiravataExperimentId();
      }
      throw new IllegalStateException();
    }

    @Override
    public boolean equals(Object that) {
      if (that == null)
        return false;
      if (that instanceof getExperimentStatus_args)
        return this.equals((getExperimentStatus_args)that);
      return false;
    }

    public boolean equals(getExperimentStatus_args that) {
      if (that == null)
        return false;

      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_airavataExperimentId = true && this.isSetAiravataExperimentId();
      boolean that_present_airavataExperimentId = true && that.isSetAiravataExperimentId();
      if (this_present_airavataExperimentId || that_present_airavataExperimentId) {
        if (!(this_present_airavataExperimentId && that_present_airavataExperimentId))
          return false;
        if (!this.airavataExperimentId.equals(that.airavataExperimentId))
          return false;
      }

      return true;
    }

    @Override
    public int hashCode() {
      List<Object> list = new ArrayList<Object>();

      boolean present_authzToken = true && (isSetAuthzToken());
      list.add(present_authzToken);
      if (present_authzToken)
        list.add(authzToken);

      boolean present_airavataExperimentId = true && (isSetAiravataExperimentId());
      list.add(present_airavataExperimentId);
      if (present_airavataExperimentId)
        list.add(airavataExperimentId);

      return list.hashCode();
    }

    @Override
    public int compareTo(getExperimentStatus_args other) {
      if (!getClass().equals(other.getClass())) {
        return getClass().getName().compareTo(other.getClass().getName());
      }

      int lastComparison = 0;

      lastComparison = 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 = Boolean.valueOf(isSetAiravataExperimentId()).compareTo(other.isSetAiravataExperimentId());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetAiravataExperimentId()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.airavataExperimentId, other.airavataExperimentId);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      return 0;
    }

    public _Fields fieldForId(int fieldId) {
      return _Fields.findByThriftId(fieldId);
    }

    public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
      schemes.get(iprot.getScheme()).getScheme().read(iprot, this);
    }

    public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException {
      schemes.get(oprot.getScheme()).getScheme().write(oprot, this);
    }

    @Override
    public String toString() {
      StringBuilder sb = new StringBuilder("getExperimentStatus_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("airavataExperimentId:");
      if (this.airavataExperimentId == null) {
        sb.append("null");
      } else {
        sb.append(this.airavataExperimentId);
      }
      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 (airavataExperimentId == null) {
        throw new org.apache.thrift.protocol.TProtocolException("Required field 'airavataExperimentId' 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, 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 getExperimentStatus_argsStandardSchemeFactory implements SchemeFactory {
      public getExperimentStatus_argsStandardScheme getScheme() {
        return new getExperimentStatus_argsStandardScheme();
      }
    }

    private static class getExperimentStatus_argsStandardScheme extends StandardScheme<getExperimentStatus_args> {

      public void read(org.apache.thrift.protocol.TProtocol iprot, getExperimentStatus_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_EXPERIMENT_ID
              if (schemeField.type == org.apache.thrift.protocol.TType.STRING) {
                struct.airavataExperimentId = iprot.readString();
                struct.setAiravataExperimentIdIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            default:
              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
          }
          iprot.readFieldEnd();
        }
        iprot.readStructEnd();

        // check for required fields of primitive type, which can't be checked in the validate method
        struct.validate();
      }

      public void write(org.apache.thrift.protocol.TProtocol oprot, getExperimentStatus_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.airavataExperimentId != null) {
          oprot.writeFieldBegin(AIRAVATA_EXPERIMENT_ID_FIELD_DESC);
          oprot.writeString(struct.airavataExperimentId);
          oprot.writeFieldEnd();
        }
        oprot.writeFieldStop();
        oprot.writeStructEnd();
      }

    }

    private static class getExperimentStatus_argsTupleSchemeFactory implements SchemeFactory {
      public getExperimentStatus_argsTupleScheme getScheme() {
        return new getExperimentStatus_argsTupleScheme();
      }
    }

    private static class getExperimentStatus_argsTupleScheme extends TupleScheme<getExperimentStatus_args> {

      @Override
      public void write(org.apache.thrift.protocol.TProtocol prot, getExperimentStatus_args struct) throws org.apache.thrift.TException {
        TTupleProtocol oprot = (TTupleProtocol) prot;
        struct.authzToken.write(oprot);
        oprot.writeString(struct.airavataExperimentId);
      }

      @Override
      public void read(org.apache.thrift.protocol.TProtocol prot, getExperimentStatus_args struct) throws org.apache.thrift.TException {
        TTupleProtocol iprot = (TTupleProtocol) prot;
        struct.authzToken = new org.apache.airavata.model.security.AuthzToken();
        struct.authzToken.read(iprot);
        struct.setAuthzTokenIsSet(true);
        struct.airavataExperimentId = iprot.readString();
        struct.setAiravataExperimentIdIsSet(true);
      }
    }

  }

  public static class getExperimentStatus_result implements org.apache.thrift.TBase<getExperimentStatus_result, getExperimentStatus_result._Fields>, java.io.Serializable, Cloneable, Comparable<getExperimentStatus_result>   {
    private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("getExperimentStatus_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 IRE_FIELD_DESC = new org.apache.thrift.protocol.TField("ire", org.apache.thrift.protocol.TType.STRUCT, (short)1);
    private static final org.apache.thrift.protocol.TField ENF_FIELD_DESC = new org.apache.thrift.protocol.TField("enf", org.apache.thrift.protocol.TType.STRUCT, (short)2);
    private static final org.apache.thrift.protocol.TField ACE_FIELD_DESC = new org.apache.thrift.protocol.TField("ace", org.apache.thrift.protocol.TType.STRUCT, (short)3);
    private static final org.apache.thrift.protocol.TField ASE_FIELD_DESC = new org.apache.thrift.protocol.TField("ase", org.apache.thrift.protocol.TType.STRUCT, (short)4);
    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)5);

    private static final Map<Class<? extends IScheme>, SchemeFactory> schemes = new HashMap<Class<? extends IScheme>, SchemeFactory>();
    static {
      schemes.put(StandardScheme.class, new getExperimentStatus_resultStandardSchemeFactory());
      schemes.put(TupleScheme.class, new getExperimentStatus_resultTupleSchemeFactory());
    }

    public org.apache.airavata.model.status.ExperimentStatus success; // required
    public org.apache.airavata.model.error.InvalidRequestException ire; // required
    public org.apache.airavata.model.error.ExperimentNotFoundException enf; // required
    public org.apache.airavata.model.error.AiravataClientException ace; // required
    public org.apache.airavata.model.error.AiravataSystemException ase; // 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"),
      IRE((short)1, "ire"),
      ENF((short)2, "enf"),
      ACE((short)3, "ace"),
      ASE((short)4, "ase"),
      AE((short)5, "ae");

      private static final Map<String, _Fields> byName = new HashMap<String, _Fields>();

      static {
        for (_Fields field : EnumSet.allOf(_Fields.class)) {
          byName.put(field.getFieldName(), field);
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, or null if its not found.
       */
      public static _Fields findByThriftId(int fieldId) {
        switch(fieldId) {
          case 0: // SUCCESS
            return SUCCESS;
          case 1: // IRE
            return IRE;
          case 2: // ENF
            return ENF;
          case 3: // ACE
            return ACE;
          case 4: // ASE
            return ASE;
          case 5: // 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 IllegalArgumentException("Field " + fieldId + " doesn't exist!");
        return fields;
      }

      /**
       * Find the _Fields constant that matches name, or null if its not found.
       */
      public static _Fields findByName(String name) {
        return byName.get(name);
      }

      private final short _thriftId;
      private final String _fieldName;

      _Fields(short thriftId, String fieldName) {
        _thriftId = thriftId;
        _fieldName = fieldName;
      }

      public short getThriftFieldId() {
        return _thriftId;
      }

      public String getFieldName() {
        return _fieldName;
      }
    }

    // isset id assignments
    public static final Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
    static {
      Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new EnumMap<_Fields, org.apache.thrift.meta_data.FieldMetaData>(_Fields.class);
      tmpMap.put(_Fields.SUCCESS, new org.apache.thrift.meta_data.FieldMetaData("success", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.StructMetaData(org.apache.thrift.protocol.TType.STRUCT, org.apache.airavata.model.status.ExperimentStatus.class)));
      tmpMap.put(_Fields.IRE, new org.apache.thrift.meta_data.FieldMetaData("ire", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRUCT)));
      tmpMap.put(_Fields.ENF, new org.apache.thrift.meta_data.FieldMetaData("enf", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRUCT)));
      tmpMap.put(_Fields.ACE, new org.apache.thrift.meta_data.FieldMetaData("ace", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRUCT)));
      tmpMap.put(_Fields.ASE, new org.apache.thrift.meta_data.FieldMetaData("ase", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRUCT)));
      tmpMap.put(_Fields.AE, new org.apache.thrift.meta_data.FieldMetaData("ae", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRUCT)));
      metaDataMap = Collections.unmodifiableMap(tmpMap);
      org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(getExperimentStatus_result.class, metaDataMap);
    }

    public getExperimentStatus_result() {
    }

    public getExperimentStatus_result(
      org.apache.airavata.model.status.ExperimentStatus success,
      org.apache.airavata.model.error.InvalidRequestException ire,
      org.apache.airavata.model.error.ExperimentNotFoundException enf,
      org.apache.airavata.model.error.AiravataClientException ace,
      org.apache.airavata.model.error.AiravataSystemException ase,
      org.apache.airavata.model.error.AuthorizationException ae)
    {
      this();
      this.success = success;
      this.ire = ire;
      this.enf = enf;
      this.ace = ace;
      this.ase = ase;
      this.ae = ae;
    }

    /**
     * Performs a deep copy on <i>other</i>.
     */
    public getExperimentStatus_result(getExperimentStatus_result other) {
      if (other.isSetSuccess()) {
        this.success = new org.apache.airavata.model.status.ExperimentStatus(other.success);
      }
      if (other.isSetIre()) {
        this.ire = new org.apache.airavata.model.error.InvalidRequestException(other.ire);
      }
      if (other.isSetEnf()) {
        this.enf = new org.apache.airavata.model.error.ExperimentNotFoundException(other.enf);
      }
      if (other.isSetAce()) {
        this.ace = new org.apache.airavata.model.error.AiravataClientException(other.ace);
      }
      if (other.isSetAse()) {
        this.ase = new org.apache.airavata.model.error.AiravataSystemException(other.ase);
      }
      if (other.isSetAe()) {
        this.ae = new org.apache.airavata.model.error.AuthorizationException(other.ae);
      }
    }

    public getExperimentStatus_result deepCopy() {
      return new getExperimentStatus_result(this);
    }

    @Override
    public void clear() {
      this.success = null;
      this.ire = null;
      this.enf = null;
      this.ace = null;
      this.ase = null;
      this.ae = null;
    }

    public org.apache.airavata.model.status.ExperimentStatus getSuccess() {
      return this.success;
    }

    public getExperimentStatus_result setSuccess(org.apache.airavata.model.status.ExperimentStatus 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.model.error.InvalidRequestException getIre() {
      return this.ire;
    }

    public getExperimentStatus_result setIre(org.apache.airavata.model.error.InvalidRequestException ire) {
      this.ire = ire;
      return this;
    }

    public void unsetIre() {
      this.ire = null;
    }

    /** Returns true if field ire is set (has been assigned a value) and false otherwise */
    public boolean isSetIre() {
      return this.ire != null;
    }

    public void setIreIsSet(boolean value) {
      if (!value) {
        this.ire = null;
      }
    }

    public org.apache.airavata.model.error.ExperimentNotFoundException getEnf() {
      return this.enf;
    }

    public getExperimentStatus_result setEnf(org.apache.airavata.model.error.ExperimentNotFoundException enf) {
      this.enf = enf;
      return this;
    }

    public void unsetEnf() {
      this.enf = null;
    }

    /** Returns true if field enf is set (has been assigned a value) and false otherwise */
    public boolean isSetEnf() {
      return this.enf != null;
    }

    public void setEnfIsSet(boolean value) {
      if (!value) {
        this.enf = null;
      }
    }

    public org.apache.airavata.model.error.AiravataClientException getAce() {
      return this.ace;
    }

    public getExperimentStatus_result setAce(org.apache.airavata.model.error.AiravataClientException ace) {
      this.ace = ace;
      return this;
    }

    public void unsetAce() {
      this.ace = null;
    }

    /** Returns true if field ace is set (has been assigned a value) and false otherwise */
    public boolean isSetAce() {
      return this.ace != null;
    }

    public void setAceIsSet(boolean value) {
      if (!value) {
        this.ace = null;
      }
    }

    public org.apache.airavata.model.error.AiravataSystemException getAse() {
      return this.ase;
    }

    public getExperimentStatus_result setAse(org.apache.airavata.model.error.AiravataSystemException ase) {
      this.ase = ase;
      return this;
    }

    public void unsetAse() {
      this.ase = null;
    }

    /** Returns true if field ase is set (has been assigned a value) and false otherwise */
    public boolean isSetAse() {
      return this.ase != null;
    }

    public void setAseIsSet(boolean value) {
      if (!value) {
        this.ase = null;
      }
    }

    public org.apache.airavata.model.error.AuthorizationException getAe() {
      return this.ae;
    }

    public getExperimentStatus_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, Object value) {
      switch (field) {
      case SUCCESS:
        if (value == null) {
          unsetSuccess();
        } else {
          setSuccess((org.apache.airavata.model.status.ExperimentStatus)value);
        }
        break;

      case IRE:
        if (value == null) {
          unsetIre();
        } else {
          setIre((org.apache.airavata.model.error.InvalidRequestException)value);
        }
        break;

      case ENF:
        if (value == null) {
          unsetEnf();
        } else {
          setEnf((org.apache.airavata.model.error.ExperimentNotFoundException)value);
        }
        break;

      case ACE:
        if (value == null) {
          unsetAce();
        } else {
          setAce((org.apache.airavata.model.error.AiravataClientException)value);
        }
        break;

      case ASE:
        if (value == null) {
          unsetAse();
        } else {
          setAse((org.apache.airavata.model.error.AiravataSystemException)value);
        }
        break;

      case AE:
        if (value == null) {
          unsetAe();
        } else {
          setAe((org.apache.airavata.model.error.AuthorizationException)value);
        }
        break;

      }
    }

    public Object getFieldValue(_Fields field) {
      switch (field) {
      case SUCCESS:
        return getSuccess();

      case IRE:
        return getIre();

      case ENF:
        return getEnf();

      case ACE:
        return getAce();

      case ASE:
        return getAse();

      case AE:
        return getAe();

      }
      throw new IllegalStateException();
    }

    /** Returns true if field corresponding to fieldID is set (has been assigned a value) and false otherwise */
    public boolean isSet(_Fields field) {
      if (field == null) {
        throw new IllegalArgumentException();
      }

      switch (field) {
      case SUCCESS:
        return isSetSuccess();
      case IRE:
        return isSetIre();
      case ENF:
        return isSetEnf();
      case ACE:
        return isSetAce();
      case ASE:
        return isSetAse();
      case AE:
        return isSetAe();
      }
      throw new IllegalStateException();
    }

    @Override
    public boolean equals(Object that) {
      if (that == null)
        return false;
      if (that instanceof getExperimentStatus_result)
        return this.equals((getExperimentStatus_result)that);
      return false;
    }

    public boolean equals(getExperimentStatus_result that) {
      if (that == null)
        return false;

      boolean this_present_success = true && this.isSetSuccess();
      boolean that_present_success = true && that.isSetSuccess();
      if (this_present_success || that_present_success) {
        if (!(this_present_success && that_present_success))
          return false;
        if (!this.success.equals(that.success))
          return false;
      }

      boolean this_present_ire = true && this.isSetIre();
      boolean that_present_ire = true && that.isSetIre();
      if (this_present_ire || that_present_ire) {
        if (!(this_present_ire && that_present_ire))
          return false;
        if (!this.ire.equals(that.ire))
          return false;
      }

      boolean this_present_enf = true && this.isSetEnf();
      boolean that_present_enf = true && that.isSetEnf();
      if (this_present_enf || that_present_enf) {
        if (!(this_present_enf && that_present_enf))
          return false;
        if (!this.enf.equals(that.enf))
          return false;
      }

      boolean this_present_ace = true && this.isSetAce();
      boolean that_present_ace = true && that.isSetAce();
      if (this_present_ace || that_present_ace) {
        if (!(this_present_ace && that_present_ace))
          return false;
        if (!this.ace.equals(that.ace))
          return false;
      }

      boolean this_present_ase = true && this.isSetAse();
      boolean that_present_ase = true && that.isSetAse();
      if (this_present_ase || that_present_ase) {
        if (!(this_present_ase && that_present_ase))
          return false;
        if (!this.ase.equals(that.ase))
          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() {
      List<Object> list = new ArrayList<Object>();

      boolean present_success = true && (isSetSuccess());
      list.add(present_success);
      if (present_success)
        list.add(success);

      boolean present_ire = true && (isSetIre());
      list.add(present_ire);
      if (present_ire)
        list.add(ire);

      boolean present_enf = true && (isSetEnf());
      list.add(present_enf);
      if (present_enf)
        list.add(enf);

      boolean present_ace = true && (isSetAce());
      list.add(present_ace);
      if (present_ace)
        list.add(ace);

      boolean present_ase = true && (isSetAse());
      list.add(present_ase);
      if (present_ase)
        list.add(ase);

      boolean present_ae = true && (isSetAe());
      list.add(present_ae);
      if (present_ae)
        list.add(ae);

      return list.hashCode();
    }

    @Override
    public int compareTo(getExperimentStatus_result other) {
      if (!getClass().equals(other.getClass())) {
        return getClass().getName().compareTo(other.getClass().getName());
      }

      int lastComparison = 0;

      lastComparison = Boolean.valueOf(isSetSuccess()).compareTo(other.isSetSuccess());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetSuccess()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.success, other.success);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = Boolean.valueOf(isSetIre()).compareTo(other.isSetIre());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetIre()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.ire, other.ire);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = Boolean.valueOf(isSetEnf()).compareTo(other.isSetEnf());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetEnf()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.enf, other.enf);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = Boolean.valueOf(isSetAce()).compareTo(other.isSetAce());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetAce()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.ace, other.ace);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = Boolean.valueOf(isSetAse()).compareTo(other.isSetAse());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetAse()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.ase, other.ase);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = 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 {
      schemes.get(iprot.getScheme()).getScheme().read(iprot, this);
    }

    public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException {
      schemes.get(oprot.getScheme()).getScheme().write(oprot, this);
      }

    @Override
    public String toString() {
      StringBuilder sb = new StringBuilder("getExperimentStatus_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("ire:");
      if (this.ire == null) {
        sb.append("null");
      } else {
        sb.append(this.ire);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("enf:");
      if (this.enf == null) {
        sb.append("null");
      } else {
        sb.append(this.enf);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("ace:");
      if (this.ace == null) {
        sb.append("null");
      } else {
        sb.append(this.ace);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("ase:");
      if (this.ase == null) {
        sb.append("null");
      } else {
        sb.append(this.ase);
      }
      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, 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 getExperimentStatus_resultStandardSchemeFactory implements SchemeFactory {
      public getExperimentStatus_resultStandardScheme getScheme() {
        return new getExperimentStatus_resultStandardScheme();
      }
    }

    private static class getExperimentStatus_resultStandardScheme extends StandardScheme<getExperimentStatus_result> {

      public void read(org.apache.thrift.protocol.TProtocol iprot, getExperimentStatus_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.status.ExperimentStatus();
                struct.success.read(iprot);
                struct.setSuccessIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 1: // IRE
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.ire = new org.apache.airavata.model.error.InvalidRequestException();
                struct.ire.read(iprot);
                struct.setIreIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 2: // ENF
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.enf = new org.apache.airavata.model.error.ExperimentNotFoundException();
                struct.enf.read(iprot);
                struct.setEnfIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 3: // ACE
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.ace = new org.apache.airavata.model.error.AiravataClientException();
                struct.ace.read(iprot);
                struct.setAceIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 4: // ASE
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.ase = new org.apache.airavata.model.error.AiravataSystemException();
                struct.ase.read(iprot);
                struct.setAseIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 5: // 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, getExperimentStatus_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.ire != null) {
          oprot.writeFieldBegin(IRE_FIELD_DESC);
          struct.ire.write(oprot);
          oprot.writeFieldEnd();
        }
        if (struct.enf != null) {
          oprot.writeFieldBegin(ENF_FIELD_DESC);
          struct.enf.write(oprot);
          oprot.writeFieldEnd();
        }
        if (struct.ace != null) {
          oprot.writeFieldBegin(ACE_FIELD_DESC);
          struct.ace.write(oprot);
          oprot.writeFieldEnd();
        }
        if (struct.ase != null) {
          oprot.writeFieldBegin(ASE_FIELD_DESC);
          struct.ase.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 getExperimentStatus_resultTupleSchemeFactory implements SchemeFactory {
      public getExperimentStatus_resultTupleScheme getScheme() {
        return new getExperimentStatus_resultTupleScheme();
      }
    }

    private static class getExperimentStatus_resultTupleScheme extends TupleScheme<getExperimentStatus_result> {

      @Override
      public void write(org.apache.thrift.protocol.TProtocol prot, getExperimentStatus_result struct) throws org.apache.thrift.TException {
        TTupleProtocol oprot = (TTupleProtocol) prot;
        BitSet optionals = new BitSet();
        if (struct.isSetSuccess()) {
          optionals.set(0);
        }
        if (struct.isSetIre()) {
          optionals.set(1);
        }
        if (struct.isSetEnf()) {
          optionals.set(2);
        }
        if (struct.isSetAce()) {
          optionals.set(3);
        }
        if (struct.isSetAse()) {
          optionals.set(4);
        }
        if (struct.isSetAe()) {
          optionals.set(5);
        }
        oprot.writeBitSet(optionals, 6);
        if (struct.isSetSuccess()) {
          struct.success.write(oprot);
        }
        if (struct.isSetIre()) {
          struct.ire.write(oprot);
        }
        if (struct.isSetEnf()) {
          struct.enf.write(oprot);
        }
        if (struct.isSetAce()) {
          struct.ace.write(oprot);
        }
        if (struct.isSetAse()) {
          struct.ase.write(oprot);
        }
        if (struct.isSetAe()) {
          struct.ae.write(oprot);
        }
      }

      @Override
      public void read(org.apache.thrift.protocol.TProtocol prot, getExperimentStatus_result struct) throws org.apache.thrift.TException {
        TTupleProtocol iprot = (TTupleProtocol) prot;
        BitSet incoming = iprot.readBitSet(6);
        if (incoming.get(0)) {
          struct.success = new org.apache.airavata.model.status.ExperimentStatus();
          struct.success.read(iprot);
          struct.setSuccessIsSet(true);
        }
        if (incoming.get(1)) {
          struct.ire = new org.apache.airavata.model.error.InvalidRequestException();
          struct.ire.read(iprot);
          struct.setIreIsSet(true);
        }
        if (incoming.get(2)) {
          struct.enf = new org.apache.airavata.model.error.ExperimentNotFoundException();
          struct.enf.read(iprot);
          struct.setEnfIsSet(true);
        }
        if (incoming.get(3)) {
          struct.ace = new org.apache.airavata.model.error.AiravataClientException();
          struct.ace.read(iprot);
          struct.setAceIsSet(true);
        }
        if (incoming.get(4)) {
          struct.ase = new org.apache.airavata.model.error.AiravataSystemException();
          struct.ase.read(iprot);
          struct.setAseIsSet(true);
        }
        if (incoming.get(5)) {
          struct.ae = new org.apache.airavata.model.error.AuthorizationException();
          struct.ae.read(iprot);
          struct.setAeIsSet(true);
        }
      }
    }

  }

  public static class getExperimentOutputs_args implements org.apache.thrift.TBase<getExperimentOutputs_args, getExperimentOutputs_args._Fields>, java.io.Serializable, Cloneable, Comparable<getExperimentOutputs_args>   {
    private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("getExperimentOutputs_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_EXPERIMENT_ID_FIELD_DESC = new org.apache.thrift.protocol.TField("airavataExperimentId", org.apache.thrift.protocol.TType.STRING, (short)2);

    private static final Map<Class<? extends IScheme>, SchemeFactory> schemes = new HashMap<Class<? extends IScheme>, SchemeFactory>();
    static {
      schemes.put(StandardScheme.class, new getExperimentOutputs_argsStandardSchemeFactory());
      schemes.put(TupleScheme.class, new getExperimentOutputs_argsTupleSchemeFactory());
    }

    public org.apache.airavata.model.security.AuthzToken authzToken; // required
    public String airavataExperimentId; // required

    /** 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_EXPERIMENT_ID((short)2, "airavataExperimentId");

      private static final Map<String, _Fields> byName = new HashMap<String, _Fields>();

      static {
        for (_Fields field : EnumSet.allOf(_Fields.class)) {
          byName.put(field.getFieldName(), field);
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, or null if its not found.
       */
      public static _Fields findByThriftId(int fieldId) {
        switch(fieldId) {
          case 1: // AUTHZ_TOKEN
            return AUTHZ_TOKEN;
          case 2: // AIRAVATA_EXPERIMENT_ID
            return AIRAVATA_EXPERIMENT_ID;
          default:
            return null;
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, throwing an exception
       * if it is not found.
       */
      public static _Fields findByThriftIdOrThrow(int fieldId) {
        _Fields fields = findByThriftId(fieldId);
        if (fields == null) throw new IllegalArgumentException("Field " + fieldId + " doesn't exist!");
        return fields;
      }

      /**
       * Find the _Fields constant that matches name, or null if its not found.
       */
      public static _Fields findByName(String name) {
        return byName.get(name);
      }

      private final short _thriftId;
      private final String _fieldName;

      _Fields(short thriftId, String fieldName) {
        _thriftId = thriftId;
        _fieldName = fieldName;
      }

      public short getThriftFieldId() {
        return _thriftId;
      }

      public String getFieldName() {
        return _fieldName;
      }
    }

    // isset id assignments
    public static final Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
    static {
      Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new EnumMap<_Fields, org.apache.thrift.meta_data.FieldMetaData>(_Fields.class);
      tmpMap.put(_Fields.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_EXPERIMENT_ID, new org.apache.thrift.meta_data.FieldMetaData("airavataExperimentId", org.apache.thrift.TFieldRequirementType.REQUIRED, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING)));
      metaDataMap = Collections.unmodifiableMap(tmpMap);
      org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(getExperimentOutputs_args.class, metaDataMap);
    }

    public getExperimentOutputs_args() {
    }

    public getExperimentOutputs_args(
      org.apache.airavata.model.security.AuthzToken authzToken,
      String airavataExperimentId)
    {
      this();
      this.authzToken = authzToken;
      this.airavataExperimentId = airavataExperimentId;
    }

    /**
     * Performs a deep copy on <i>other</i>.
     */
    public getExperimentOutputs_args(getExperimentOutputs_args other) {
      if (other.isSetAuthzToken()) {
        this.authzToken = new org.apache.airavata.model.security.AuthzToken(other.authzToken);
      }
      if (other.isSetAiravataExperimentId()) {
        this.airavataExperimentId = other.airavataExperimentId;
      }
    }

    public getExperimentOutputs_args deepCopy() {
      return new getExperimentOutputs_args(this);
    }

    @Override
    public void clear() {
      this.authzToken = null;
      this.airavataExperimentId = null;
    }

    public org.apache.airavata.model.security.AuthzToken getAuthzToken() {
      return this.authzToken;
    }

    public getExperimentOutputs_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 String getAiravataExperimentId() {
      return this.airavataExperimentId;
    }

    public getExperimentOutputs_args setAiravataExperimentId(String airavataExperimentId) {
      this.airavataExperimentId = airavataExperimentId;
      return this;
    }

    public void unsetAiravataExperimentId() {
      this.airavataExperimentId = null;
    }

    /** Returns true if field airavataExperimentId is set (has been assigned a value) and false otherwise */
    public boolean isSetAiravataExperimentId() {
      return this.airavataExperimentId != null;
    }

    public void setAiravataExperimentIdIsSet(boolean value) {
      if (!value) {
        this.airavataExperimentId = null;
      }
    }

    public void setFieldValue(_Fields field, Object value) {
      switch (field) {
      case AUTHZ_TOKEN:
        if (value == null) {
          unsetAuthzToken();
        } else {
          setAuthzToken((org.apache.airavata.model.security.AuthzToken)value);
        }
        break;

      case AIRAVATA_EXPERIMENT_ID:
        if (value == null) {
          unsetAiravataExperimentId();
        } else {
          setAiravataExperimentId((String)value);
        }
        break;

      }
    }

    public Object getFieldValue(_Fields field) {
      switch (field) {
      case AUTHZ_TOKEN:
        return getAuthzToken();

      case AIRAVATA_EXPERIMENT_ID:
        return getAiravataExperimentId();

      }
      throw new IllegalStateException();
    }

    /** Returns true if field corresponding to fieldID is set (has been assigned a value) and false otherwise */
    public boolean isSet(_Fields field) {
      if (field == null) {
        throw new IllegalArgumentException();
      }

      switch (field) {
      case AUTHZ_TOKEN:
        return isSetAuthzToken();
      case AIRAVATA_EXPERIMENT_ID:
        return isSetAiravataExperimentId();
      }
      throw new IllegalStateException();
    }

    @Override
    public boolean equals(Object that) {
      if (that == null)
        return false;
      if (that instanceof getExperimentOutputs_args)
        return this.equals((getExperimentOutputs_args)that);
      return false;
    }

    public boolean equals(getExperimentOutputs_args that) {
      if (that == null)
        return false;

      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_airavataExperimentId = true && this.isSetAiravataExperimentId();
      boolean that_present_airavataExperimentId = true && that.isSetAiravataExperimentId();
      if (this_present_airavataExperimentId || that_present_airavataExperimentId) {
        if (!(this_present_airavataExperimentId && that_present_airavataExperimentId))
          return false;
        if (!this.airavataExperimentId.equals(that.airavataExperimentId))
          return false;
      }

      return true;
    }

    @Override
    public int hashCode() {
      List<Object> list = new ArrayList<Object>();

      boolean present_authzToken = true && (isSetAuthzToken());
      list.add(present_authzToken);
      if (present_authzToken)
        list.add(authzToken);

      boolean present_airavataExperimentId = true && (isSetAiravataExperimentId());
      list.add(present_airavataExperimentId);
      if (present_airavataExperimentId)
        list.add(airavataExperimentId);

      return list.hashCode();
    }

    @Override
    public int compareTo(getExperimentOutputs_args other) {
      if (!getClass().equals(other.getClass())) {
        return getClass().getName().compareTo(other.getClass().getName());
      }

      int lastComparison = 0;

      lastComparison = 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 = Boolean.valueOf(isSetAiravataExperimentId()).compareTo(other.isSetAiravataExperimentId());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetAiravataExperimentId()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.airavataExperimentId, other.airavataExperimentId);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      return 0;
    }

    public _Fields fieldForId(int fieldId) {
      return _Fields.findByThriftId(fieldId);
    }

    public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
      schemes.get(iprot.getScheme()).getScheme().read(iprot, this);
    }

    public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException {
      schemes.get(oprot.getScheme()).getScheme().write(oprot, this);
    }

    @Override
    public String toString() {
      StringBuilder sb = new StringBuilder("getExperimentOutputs_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("airavataExperimentId:");
      if (this.airavataExperimentId == null) {
        sb.append("null");
      } else {
        sb.append(this.airavataExperimentId);
      }
      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 (airavataExperimentId == null) {
        throw new org.apache.thrift.protocol.TProtocolException("Required field 'airavataExperimentId' 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, 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 getExperimentOutputs_argsStandardSchemeFactory implements SchemeFactory {
      public getExperimentOutputs_argsStandardScheme getScheme() {
        return new getExperimentOutputs_argsStandardScheme();
      }
    }

    private static class getExperimentOutputs_argsStandardScheme extends StandardScheme<getExperimentOutputs_args> {

      public void read(org.apache.thrift.protocol.TProtocol iprot, getExperimentOutputs_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_EXPERIMENT_ID
              if (schemeField.type == org.apache.thrift.protocol.TType.STRING) {
                struct.airavataExperimentId = iprot.readString();
                struct.setAiravataExperimentIdIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            default:
              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
          }
          iprot.readFieldEnd();
        }
        iprot.readStructEnd();

        // check for required fields of primitive type, which can't be checked in the validate method
        struct.validate();
      }

      public void write(org.apache.thrift.protocol.TProtocol oprot, getExperimentOutputs_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.airavataExperimentId != null) {
          oprot.writeFieldBegin(AIRAVATA_EXPERIMENT_ID_FIELD_DESC);
          oprot.writeString(struct.airavataExperimentId);
          oprot.writeFieldEnd();
        }
        oprot.writeFieldStop();
        oprot.writeStructEnd();
      }

    }

    private static class getExperimentOutputs_argsTupleSchemeFactory implements SchemeFactory {
      public getExperimentOutputs_argsTupleScheme getScheme() {
        return new getExperimentOutputs_argsTupleScheme();
      }
    }

    private static class getExperimentOutputs_argsTupleScheme extends TupleScheme<getExperimentOutputs_args> {

      @Override
      public void write(org.apache.thrift.protocol.TProtocol prot, getExperimentOutputs_args struct) throws org.apache.thrift.TException {
        TTupleProtocol oprot = (TTupleProtocol) prot;
        struct.authzToken.write(oprot);
        oprot.writeString(struct.airavataExperimentId);
      }

      @Override
      public void read(org.apache.thrift.protocol.TProtocol prot, getExperimentOutputs_args struct) throws org.apache.thrift.TException {
        TTupleProtocol iprot = (TTupleProtocol) prot;
        struct.authzToken = new org.apache.airavata.model.security.AuthzToken();
        struct.authzToken.read(iprot);
        struct.setAuthzTokenIsSet(true);
        struct.airavataExperimentId = iprot.readString();
        struct.setAiravataExperimentIdIsSet(true);
      }
    }

  }

  public static class getExperimentOutputs_result implements org.apache.thrift.TBase<getExperimentOutputs_result, getExperimentOutputs_result._Fields>, java.io.Serializable, Cloneable, Comparable<getExperimentOutputs_result>   {
    private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("getExperimentOutputs_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 IRE_FIELD_DESC = new org.apache.thrift.protocol.TField("ire", org.apache.thrift.protocol.TType.STRUCT, (short)1);
    private static final org.apache.thrift.protocol.TField ENF_FIELD_DESC = new org.apache.thrift.protocol.TField("enf", org.apache.thrift.protocol.TType.STRUCT, (short)2);
    private static final org.apache.thrift.protocol.TField ACE_FIELD_DESC = new org.apache.thrift.protocol.TField("ace", org.apache.thrift.protocol.TType.STRUCT, (short)3);
    private static final org.apache.thrift.protocol.TField ASE_FIELD_DESC = new org.apache.thrift.protocol.TField("ase", org.apache.thrift.protocol.TType.STRUCT, (short)4);
    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)5);

    private static final Map<Class<? extends IScheme>, SchemeFactory> schemes = new HashMap<Class<? extends IScheme>, SchemeFactory>();
    static {
      schemes.put(StandardScheme.class, new getExperimentOutputs_resultStandardSchemeFactory());
      schemes.put(TupleScheme.class, new getExperimentOutputs_resultTupleSchemeFactory());
    }

    public List<org.apache.airavata.model.application.io.OutputDataObjectType> success; // required
    public org.apache.airavata.model.error.InvalidRequestException ire; // required
    public org.apache.airavata.model.error.ExperimentNotFoundException enf; // required
    public org.apache.airavata.model.error.AiravataClientException ace; // required
    public org.apache.airavata.model.error.AiravataSystemException ase; // 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"),
      IRE((short)1, "ire"),
      ENF((short)2, "enf"),
      ACE((short)3, "ace"),
      ASE((short)4, "ase"),
      AE((short)5, "ae");

      private static final Map<String, _Fields> byName = new HashMap<String, _Fields>();

      static {
        for (_Fields field : EnumSet.allOf(_Fields.class)) {
          byName.put(field.getFieldName(), field);
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, or null if its not found.
       */
      public static _Fields findByThriftId(int fieldId) {
        switch(fieldId) {
          case 0: // SUCCESS
            return SUCCESS;
          case 1: // IRE
            return IRE;
          case 2: // ENF
            return ENF;
          case 3: // ACE
            return ACE;
          case 4: // ASE
            return ASE;
          case 5: // 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 IllegalArgumentException("Field " + fieldId + " doesn't exist!");
        return fields;
      }

      /**
       * Find the _Fields constant that matches name, or null if its not found.
       */
      public static _Fields findByName(String name) {
        return byName.get(name);
      }

      private final short _thriftId;
      private final String _fieldName;

      _Fields(short thriftId, String fieldName) {
        _thriftId = thriftId;
        _fieldName = fieldName;
      }

      public short getThriftFieldId() {
        return _thriftId;
      }

      public String getFieldName() {
        return _fieldName;
      }
    }

    // isset id assignments
    public static final Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
    static {
      Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new EnumMap<_Fields, org.apache.thrift.meta_data.FieldMetaData>(_Fields.class);
      tmpMap.put(_Fields.SUCCESS, new org.apache.thrift.meta_data.FieldMetaData("success", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.ListMetaData(org.apache.thrift.protocol.TType.LIST, 
              new org.apache.thrift.meta_data.StructMetaData(org.apache.thrift.protocol.TType.STRUCT, org.apache.airavata.model.application.io.OutputDataObjectType.class))));
      tmpMap.put(_Fields.IRE, new org.apache.thrift.meta_data.FieldMetaData("ire", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRUCT)));
      tmpMap.put(_Fields.ENF, new org.apache.thrift.meta_data.FieldMetaData("enf", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRUCT)));
      tmpMap.put(_Fields.ACE, new org.apache.thrift.meta_data.FieldMetaData("ace", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRUCT)));
      tmpMap.put(_Fields.ASE, new org.apache.thrift.meta_data.FieldMetaData("ase", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRUCT)));
      tmpMap.put(_Fields.AE, new org.apache.thrift.meta_data.FieldMetaData("ae", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRUCT)));
      metaDataMap = Collections.unmodifiableMap(tmpMap);
      org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(getExperimentOutputs_result.class, metaDataMap);
    }

    public getExperimentOutputs_result() {
    }

    public getExperimentOutputs_result(
      List<org.apache.airavata.model.application.io.OutputDataObjectType> success,
      org.apache.airavata.model.error.InvalidRequestException ire,
      org.apache.airavata.model.error.ExperimentNotFoundException enf,
      org.apache.airavata.model.error.AiravataClientException ace,
      org.apache.airavata.model.error.AiravataSystemException ase,
      org.apache.airavata.model.error.AuthorizationException ae)
    {
      this();
      this.success = success;
      this.ire = ire;
      this.enf = enf;
      this.ace = ace;
      this.ase = ase;
      this.ae = ae;
    }

    /**
     * Performs a deep copy on <i>other</i>.
     */
    public getExperimentOutputs_result(getExperimentOutputs_result other) {
      if (other.isSetSuccess()) {
        List<org.apache.airavata.model.application.io.OutputDataObjectType> __this__success = new ArrayList<org.apache.airavata.model.application.io.OutputDataObjectType>(other.success.size());
        for (org.apache.airavata.model.application.io.OutputDataObjectType other_element : other.success) {
          __this__success.add(new org.apache.airavata.model.application.io.OutputDataObjectType(other_element));
        }
        this.success = __this__success;
      }
      if (other.isSetIre()) {
        this.ire = new org.apache.airavata.model.error.InvalidRequestException(other.ire);
      }
      if (other.isSetEnf()) {
        this.enf = new org.apache.airavata.model.error.ExperimentNotFoundException(other.enf);
      }
      if (other.isSetAce()) {
        this.ace = new org.apache.airavata.model.error.AiravataClientException(other.ace);
      }
      if (other.isSetAse()) {
        this.ase = new org.apache.airavata.model.error.AiravataSystemException(other.ase);
      }
      if (other.isSetAe()) {
        this.ae = new org.apache.airavata.model.error.AuthorizationException(other.ae);
      }
    }

    public getExperimentOutputs_result deepCopy() {
      return new getExperimentOutputs_result(this);
    }

    @Override
    public void clear() {
      this.success = null;
      this.ire = null;
      this.enf = null;
      this.ace = null;
      this.ase = null;
      this.ae = null;
    }

    public int getSuccessSize() {
      return (this.success == null) ? 0 : this.success.size();
    }

    public java.util.Iterator<org.apache.airavata.model.application.io.OutputDataObjectType> getSuccessIterator() {
      return (this.success == null) ? null : this.success.iterator();
    }

    public void addToSuccess(org.apache.airavata.model.application.io.OutputDataObjectType elem) {
      if (this.success == null) {
        this.success = new ArrayList<org.apache.airavata.model.application.io.OutputDataObjectType>();
      }
      this.success.add(elem);
    }

    public List<org.apache.airavata.model.application.io.OutputDataObjectType> getSuccess() {
      return this.success;
    }

    public getExperimentOutputs_result setSuccess(List<org.apache.airavata.model.application.io.OutputDataObjectType> 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.model.error.InvalidRequestException getIre() {
      return this.ire;
    }

    public getExperimentOutputs_result setIre(org.apache.airavata.model.error.InvalidRequestException ire) {
      this.ire = ire;
      return this;
    }

    public void unsetIre() {
      this.ire = null;
    }

    /** Returns true if field ire is set (has been assigned a value) and false otherwise */
    public boolean isSetIre() {
      return this.ire != null;
    }

    public void setIreIsSet(boolean value) {
      if (!value) {
        this.ire = null;
      }
    }

    public org.apache.airavata.model.error.ExperimentNotFoundException getEnf() {
      return this.enf;
    }

    public getExperimentOutputs_result setEnf(org.apache.airavata.model.error.ExperimentNotFoundException enf) {
      this.enf = enf;
      return this;
    }

    public void unsetEnf() {
      this.enf = null;
    }

    /** Returns true if field enf is set (has been assigned a value) and false otherwise */
    public boolean isSetEnf() {
      return this.enf != null;
    }

    public void setEnfIsSet(boolean value) {
      if (!value) {
        this.enf = null;
      }
    }

    public org.apache.airavata.model.error.AiravataClientException getAce() {
      return this.ace;
    }

    public getExperimentOutputs_result setAce(org.apache.airavata.model.error.AiravataClientException ace) {
      this.ace = ace;
      return this;
    }

    public void unsetAce() {
      this.ace = null;
    }

    /** Returns true if field ace is set (has been assigned a value) and false otherwise */
    public boolean isSetAce() {
      return this.ace != null;
    }

    public void setAceIsSet(boolean value) {
      if (!value) {
        this.ace = null;
      }
    }

    public org.apache.airavata.model.error.AiravataSystemException getAse() {
      return this.ase;
    }

    public getExperimentOutputs_result setAse(org.apache.airavata.model.error.AiravataSystemException ase) {
      this.ase = ase;
      return this;
    }

    public void unsetAse() {
      this.ase = null;
    }

    /** Returns true if field ase is set (has been assigned a value) and false otherwise */
    public boolean isSetAse() {
      return this.ase != null;
    }

    public void setAseIsSet(boolean value) {
      if (!value) {
        this.ase = null;
      }
    }

    public org.apache.airavata.model.error.AuthorizationException getAe() {
      return this.ae;
    }

    public getExperimentOutputs_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, Object value) {
      switch (field) {
      case SUCCESS:
        if (value == null) {
          unsetSuccess();
        } else {
          setSuccess((List<org.apache.airavata.model.application.io.OutputDataObjectType>)value);
        }
        break;

      case IRE:
        if (value == null) {
          unsetIre();
        } else {
          setIre((org.apache.airavata.model.error.InvalidRequestException)value);
        }
        break;

      case ENF:
        if (value == null) {
          unsetEnf();
        } else {
          setEnf((org.apache.airavata.model.error.ExperimentNotFoundException)value);
        }
        break;

      case ACE:
        if (value == null) {
          unsetAce();
        } else {
          setAce((org.apache.airavata.model.error.AiravataClientException)value);
        }
        break;

      case ASE:
        if (value == null) {
          unsetAse();
        } else {
          setAse((org.apache.airavata.model.error.AiravataSystemException)value);
        }
        break;

      case AE:
        if (value == null) {
          unsetAe();
        } else {
          setAe((org.apache.airavata.model.error.AuthorizationException)value);
        }
        break;

      }
    }

    public Object getFieldValue(_Fields field) {
      switch (field) {
      case SUCCESS:
        return getSuccess();

      case IRE:
        return getIre();

      case ENF:
        return getEnf();

      case ACE:
        return getAce();

      case ASE:
        return getAse();

      case AE:
        return getAe();

      }
      throw new IllegalStateException();
    }

    /** Returns true if field corresponding to fieldID is set (has been assigned a value) and false otherwise */
    public boolean isSet(_Fields field) {
      if (field == null) {
        throw new IllegalArgumentException();
      }

      switch (field) {
      case SUCCESS:
        return isSetSuccess();
      case IRE:
        return isSetIre();
      case ENF:
        return isSetEnf();
      case ACE:
        return isSetAce();
      case ASE:
        return isSetAse();
      case AE:
        return isSetAe();
      }
      throw new IllegalStateException();
    }

    @Override
    public boolean equals(Object that) {
      if (that == null)
        return false;
      if (that instanceof getExperimentOutputs_result)
        return this.equals((getExperimentOutputs_result)that);
      return false;
    }

    public boolean equals(getExperimentOutputs_result that) {
      if (that == null)
        return false;

      boolean this_present_success = true && this.isSetSuccess();
      boolean that_present_success = true && that.isSetSuccess();
      if (this_present_success || that_present_success) {
        if (!(this_present_success && that_present_success))
          return false;
        if (!this.success.equals(that.success))
          return false;
      }

      boolean this_present_ire = true && this.isSetIre();
      boolean that_present_ire = true && that.isSetIre();
      if (this_present_ire || that_present_ire) {
        if (!(this_present_ire && that_present_ire))
          return false;
        if (!this.ire.equals(that.ire))
          return false;
      }

      boolean this_present_enf = true && this.isSetEnf();
      boolean that_present_enf = true && that.isSetEnf();
      if (this_present_enf || that_present_enf) {
        if (!(this_present_enf && that_present_enf))
          return false;
        if (!this.enf.equals(that.enf))
          return false;
      }

      boolean this_present_ace = true && this.isSetAce();
      boolean that_present_ace = true && that.isSetAce();
      if (this_present_ace || that_present_ace) {
        if (!(this_present_ace && that_present_ace))
          return false;
        if (!this.ace.equals(that.ace))
          return false;
      }

      boolean this_present_ase = true && this.isSetAse();
      boolean that_present_ase = true && that.isSetAse();
      if (this_present_ase || that_present_ase) {
        if (!(this_present_ase && that_present_ase))
          return false;
        if (!this.ase.equals(that.ase))
          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() {
      List<Object> list = new ArrayList<Object>();

      boolean present_success = true && (isSetSuccess());
      list.add(present_success);
      if (present_success)
        list.add(success);

      boolean present_ire = true && (isSetIre());
      list.add(present_ire);
      if (present_ire)
        list.add(ire);

      boolean present_enf = true && (isSetEnf());
      list.add(present_enf);
      if (present_enf)
        list.add(enf);

      boolean present_ace = true && (isSetAce());
      list.add(present_ace);
      if (present_ace)
        list.add(ace);

      boolean present_ase = true && (isSetAse());
      list.add(present_ase);
      if (present_ase)
        list.add(ase);

      boolean present_ae = true && (isSetAe());
      list.add(present_ae);
      if (present_ae)
        list.add(ae);

      return list.hashCode();
    }

    @Override
    public int compareTo(getExperimentOutputs_result other) {
      if (!getClass().equals(other.getClass())) {
        return getClass().getName().compareTo(other.getClass().getName());
      }

      int lastComparison = 0;

      lastComparison = Boolean.valueOf(isSetSuccess()).compareTo(other.isSetSuccess());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetSuccess()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.success, other.success);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = Boolean.valueOf(isSetIre()).compareTo(other.isSetIre());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetIre()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.ire, other.ire);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = Boolean.valueOf(isSetEnf()).compareTo(other.isSetEnf());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetEnf()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.enf, other.enf);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = Boolean.valueOf(isSetAce()).compareTo(other.isSetAce());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetAce()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.ace, other.ace);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = Boolean.valueOf(isSetAse()).compareTo(other.isSetAse());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetAse()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.ase, other.ase);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = 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 {
      schemes.get(iprot.getScheme()).getScheme().read(iprot, this);
    }

    public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException {
      schemes.get(oprot.getScheme()).getScheme().write(oprot, this);
      }

    @Override
    public String toString() {
      StringBuilder sb = new StringBuilder("getExperimentOutputs_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("ire:");
      if (this.ire == null) {
        sb.append("null");
      } else {
        sb.append(this.ire);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("enf:");
      if (this.enf == null) {
        sb.append("null");
      } else {
        sb.append(this.enf);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("ace:");
      if (this.ace == null) {
        sb.append("null");
      } else {
        sb.append(this.ace);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("ase:");
      if (this.ase == null) {
        sb.append("null");
      } else {
        sb.append(this.ase);
      }
      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, 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 getExperimentOutputs_resultStandardSchemeFactory implements SchemeFactory {
      public getExperimentOutputs_resultStandardScheme getScheme() {
        return new getExperimentOutputs_resultStandardScheme();
      }
    }

    private static class getExperimentOutputs_resultStandardScheme extends StandardScheme<getExperimentOutputs_result> {

      public void read(org.apache.thrift.protocol.TProtocol iprot, getExperimentOutputs_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 _list116 = iprot.readListBegin();
                  struct.success = new ArrayList<org.apache.airavata.model.application.io.OutputDataObjectType>(_list116.size);
                  org.apache.airavata.model.application.io.OutputDataObjectType _elem117;
                  for (int _i118 = 0; _i118 < _list116.size; ++_i118)
                  {
                    _elem117 = new org.apache.airavata.model.application.io.OutputDataObjectType();
                    _elem117.read(iprot);
                    struct.success.add(_elem117);
                  }
                  iprot.readListEnd();
                }
                struct.setSuccessIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 1: // IRE
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.ire = new org.apache.airavata.model.error.InvalidRequestException();
                struct.ire.read(iprot);
                struct.setIreIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 2: // ENF
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.enf = new org.apache.airavata.model.error.ExperimentNotFoundException();
                struct.enf.read(iprot);
                struct.setEnfIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 3: // ACE
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.ace = new org.apache.airavata.model.error.AiravataClientException();
                struct.ace.read(iprot);
                struct.setAceIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 4: // ASE
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.ase = new org.apache.airavata.model.error.AiravataSystemException();
                struct.ase.read(iprot);
                struct.setAseIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 5: // 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, getExperimentOutputs_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.application.io.OutputDataObjectType _iter119 : struct.success)
            {
              _iter119.write(oprot);
            }
            oprot.writeListEnd();
          }
          oprot.writeFieldEnd();
        }
        if (struct.ire != null) {
          oprot.writeFieldBegin(IRE_FIELD_DESC);
          struct.ire.write(oprot);
          oprot.writeFieldEnd();
        }
        if (struct.enf != null) {
          oprot.writeFieldBegin(ENF_FIELD_DESC);
          struct.enf.write(oprot);
          oprot.writeFieldEnd();
        }
        if (struct.ace != null) {
          oprot.writeFieldBegin(ACE_FIELD_DESC);
          struct.ace.write(oprot);
          oprot.writeFieldEnd();
        }
        if (struct.ase != null) {
          oprot.writeFieldBegin(ASE_FIELD_DESC);
          struct.ase.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 getExperimentOutputs_resultTupleSchemeFactory implements SchemeFactory {
      public getExperimentOutputs_resultTupleScheme getScheme() {
        return new getExperimentOutputs_resultTupleScheme();
      }
    }

    private static class getExperimentOutputs_resultTupleScheme extends TupleScheme<getExperimentOutputs_result> {

      @Override
      public void write(org.apache.thrift.protocol.TProtocol prot, getExperimentOutputs_result struct) throws org.apache.thrift.TException {
        TTupleProtocol oprot = (TTupleProtocol) prot;
        BitSet optionals = new BitSet();
        if (struct.isSetSuccess()) {
          optionals.set(0);
        }
        if (struct.isSetIre()) {
          optionals.set(1);
        }
        if (struct.isSetEnf()) {
          optionals.set(2);
        }
        if (struct.isSetAce()) {
          optionals.set(3);
        }
        if (struct.isSetAse()) {
          optionals.set(4);
        }
        if (struct.isSetAe()) {
          optionals.set(5);
        }
        oprot.writeBitSet(optionals, 6);
        if (struct.isSetSuccess()) {
          {
            oprot.writeI32(struct.success.size());
            for (org.apache.airavata.model.application.io.OutputDataObjectType _iter120 : struct.success)
            {
              _iter120.write(oprot);
            }
          }
        }
        if (struct.isSetIre()) {
          struct.ire.write(oprot);
        }
        if (struct.isSetEnf()) {
          struct.enf.write(oprot);
        }
        if (struct.isSetAce()) {
          struct.ace.write(oprot);
        }
        if (struct.isSetAse()) {
          struct.ase.write(oprot);
        }
        if (struct.isSetAe()) {
          struct.ae.write(oprot);
        }
      }

      @Override
      public void read(org.apache.thrift.protocol.TProtocol prot, getExperimentOutputs_result struct) throws org.apache.thrift.TException {
        TTupleProtocol iprot = (TTupleProtocol) prot;
        BitSet incoming = iprot.readBitSet(6);
        if (incoming.get(0)) {
          {
            org.apache.thrift.protocol.TList _list121 = new org.apache.thrift.protocol.TList(org.apache.thrift.protocol.TType.STRUCT, iprot.readI32());
            struct.success = new ArrayList<org.apache.airavata.model.application.io.OutputDataObjectType>(_list121.size);
            org.apache.airavata.model.application.io.OutputDataObjectType _elem122;
            for (int _i123 = 0; _i123 < _list121.size; ++_i123)
            {
              _elem122 = new org.apache.airavata.model.application.io.OutputDataObjectType();
              _elem122.read(iprot);
              struct.success.add(_elem122);
            }
          }
          struct.setSuccessIsSet(true);
        }
        if (incoming.get(1)) {
          struct.ire = new org.apache.airavata.model.error.InvalidRequestException();
          struct.ire.read(iprot);
          struct.setIreIsSet(true);
        }
        if (incoming.get(2)) {
          struct.enf = new org.apache.airavata.model.error.ExperimentNotFoundException();
          struct.enf.read(iprot);
          struct.setEnfIsSet(true);
        }
        if (incoming.get(3)) {
          struct.ace = new org.apache.airavata.model.error.AiravataClientException();
          struct.ace.read(iprot);
          struct.setAceIsSet(true);
        }
        if (incoming.get(4)) {
          struct.ase = new org.apache.airavata.model.error.AiravataSystemException();
          struct.ase.read(iprot);
          struct.setAseIsSet(true);
        }
        if (incoming.get(5)) {
          struct.ae = new org.apache.airavata.model.error.AuthorizationException();
          struct.ae.read(iprot);
          struct.setAeIsSet(true);
        }
      }
    }

  }

  public static class getIntermediateOutputs_args implements org.apache.thrift.TBase<getIntermediateOutputs_args, getIntermediateOutputs_args._Fields>, java.io.Serializable, Cloneable, Comparable<getIntermediateOutputs_args>   {
    private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("getIntermediateOutputs_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_EXPERIMENT_ID_FIELD_DESC = new org.apache.thrift.protocol.TField("airavataExperimentId", org.apache.thrift.protocol.TType.STRING, (short)2);

    private static final Map<Class<? extends IScheme>, SchemeFactory> schemes = new HashMap<Class<? extends IScheme>, SchemeFactory>();
    static {
      schemes.put(StandardScheme.class, new getIntermediateOutputs_argsStandardSchemeFactory());
      schemes.put(TupleScheme.class, new getIntermediateOutputs_argsTupleSchemeFactory());
    }

    public org.apache.airavata.model.security.AuthzToken authzToken; // required
    public String airavataExperimentId; // required

    /** 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_EXPERIMENT_ID((short)2, "airavataExperimentId");

      private static final Map<String, _Fields> byName = new HashMap<String, _Fields>();

      static {
        for (_Fields field : EnumSet.allOf(_Fields.class)) {
          byName.put(field.getFieldName(), field);
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, or null if its not found.
       */
      public static _Fields findByThriftId(int fieldId) {
        switch(fieldId) {
          case 1: // AUTHZ_TOKEN
            return AUTHZ_TOKEN;
          case 2: // AIRAVATA_EXPERIMENT_ID
            return AIRAVATA_EXPERIMENT_ID;
          default:
            return null;
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, throwing an exception
       * if it is not found.
       */
      public static _Fields findByThriftIdOrThrow(int fieldId) {
        _Fields fields = findByThriftId(fieldId);
        if (fields == null) throw new IllegalArgumentException("Field " + fieldId + " doesn't exist!");
        return fields;
      }

      /**
       * Find the _Fields constant that matches name, or null if its not found.
       */
      public static _Fields findByName(String name) {
        return byName.get(name);
      }

      private final short _thriftId;
      private final String _fieldName;

      _Fields(short thriftId, String fieldName) {
        _thriftId = thriftId;
        _fieldName = fieldName;
      }

      public short getThriftFieldId() {
        return _thriftId;
      }

      public String getFieldName() {
        return _fieldName;
      }
    }

    // isset id assignments
    public static final Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
    static {
      Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new EnumMap<_Fields, org.apache.thrift.meta_data.FieldMetaData>(_Fields.class);
      tmpMap.put(_Fields.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_EXPERIMENT_ID, new org.apache.thrift.meta_data.FieldMetaData("airavataExperimentId", org.apache.thrift.TFieldRequirementType.REQUIRED, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING)));
      metaDataMap = Collections.unmodifiableMap(tmpMap);
      org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(getIntermediateOutputs_args.class, metaDataMap);
    }

    public getIntermediateOutputs_args() {
    }

    public getIntermediateOutputs_args(
      org.apache.airavata.model.security.AuthzToken authzToken,
      String airavataExperimentId)
    {
      this();
      this.authzToken = authzToken;
      this.airavataExperimentId = airavataExperimentId;
    }

    /**
     * Performs a deep copy on <i>other</i>.
     */
    public getIntermediateOutputs_args(getIntermediateOutputs_args other) {
      if (other.isSetAuthzToken()) {
        this.authzToken = new org.apache.airavata.model.security.AuthzToken(other.authzToken);
      }
      if (other.isSetAiravataExperimentId()) {
        this.airavataExperimentId = other.airavataExperimentId;
      }
    }

    public getIntermediateOutputs_args deepCopy() {
      return new getIntermediateOutputs_args(this);
    }

    @Override
    public void clear() {
      this.authzToken = null;
      this.airavataExperimentId = null;
    }

    public org.apache.airavata.model.security.AuthzToken getAuthzToken() {
      return this.authzToken;
    }

    public getIntermediateOutputs_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 String getAiravataExperimentId() {
      return this.airavataExperimentId;
    }

    public getIntermediateOutputs_args setAiravataExperimentId(String airavataExperimentId) {
      this.airavataExperimentId = airavataExperimentId;
      return this;
    }

    public void unsetAiravataExperimentId() {
      this.airavataExperimentId = null;
    }

    /** Returns true if field airavataExperimentId is set (has been assigned a value) and false otherwise */
    public boolean isSetAiravataExperimentId() {
      return this.airavataExperimentId != null;
    }

    public void setAiravataExperimentIdIsSet(boolean value) {
      if (!value) {
        this.airavataExperimentId = null;
      }
    }

    public void setFieldValue(_Fields field, Object value) {
      switch (field) {
      case AUTHZ_TOKEN:
        if (value == null) {
          unsetAuthzToken();
        } else {
          setAuthzToken((org.apache.airavata.model.security.AuthzToken)value);
        }
        break;

      case AIRAVATA_EXPERIMENT_ID:
        if (value == null) {
          unsetAiravataExperimentId();
        } else {
          setAiravataExperimentId((String)value);
        }
        break;

      }
    }

    public Object getFieldValue(_Fields field) {
      switch (field) {
      case AUTHZ_TOKEN:
        return getAuthzToken();

      case AIRAVATA_EXPERIMENT_ID:
        return getAiravataExperimentId();

      }
      throw new IllegalStateException();
    }

    /** Returns true if field corresponding to fieldID is set (has been assigned a value) and false otherwise */
    public boolean isSet(_Fields field) {
      if (field == null) {
        throw new IllegalArgumentException();
      }

      switch (field) {
      case AUTHZ_TOKEN:
        return isSetAuthzToken();
      case AIRAVATA_EXPERIMENT_ID:
        return isSetAiravataExperimentId();
      }
      throw new IllegalStateException();
    }

    @Override
    public boolean equals(Object that) {
      if (that == null)
        return false;
      if (that instanceof getIntermediateOutputs_args)
        return this.equals((getIntermediateOutputs_args)that);
      return false;
    }

    public boolean equals(getIntermediateOutputs_args that) {
      if (that == null)
        return false;

      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_airavataExperimentId = true && this.isSetAiravataExperimentId();
      boolean that_present_airavataExperimentId = true && that.isSetAiravataExperimentId();
      if (this_present_airavataExperimentId || that_present_airavataExperimentId) {
        if (!(this_present_airavataExperimentId && that_present_airavataExperimentId))
          return false;
        if (!this.airavataExperimentId.equals(that.airavataExperimentId))
          return false;
      }

      return true;
    }

    @Override
    public int hashCode() {
      List<Object> list = new ArrayList<Object>();

      boolean present_authzToken = true && (isSetAuthzToken());
      list.add(present_authzToken);
      if (present_authzToken)
        list.add(authzToken);

      boolean present_airavataExperimentId = true && (isSetAiravataExperimentId());
      list.add(present_airavataExperimentId);
      if (present_airavataExperimentId)
        list.add(airavataExperimentId);

      return list.hashCode();
    }

    @Override
    public int compareTo(getIntermediateOutputs_args other) {
      if (!getClass().equals(other.getClass())) {
        return getClass().getName().compareTo(other.getClass().getName());
      }

      int lastComparison = 0;

      lastComparison = 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 = Boolean.valueOf(isSetAiravataExperimentId()).compareTo(other.isSetAiravataExperimentId());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetAiravataExperimentId()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.airavataExperimentId, other.airavataExperimentId);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      return 0;
    }

    public _Fields fieldForId(int fieldId) {
      return _Fields.findByThriftId(fieldId);
    }

    public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
      schemes.get(iprot.getScheme()).getScheme().read(iprot, this);
    }

    public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException {
      schemes.get(oprot.getScheme()).getScheme().write(oprot, this);
    }

    @Override
    public String toString() {
      StringBuilder sb = new StringBuilder("getIntermediateOutputs_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("airavataExperimentId:");
      if (this.airavataExperimentId == null) {
        sb.append("null");
      } else {
        sb.append(this.airavataExperimentId);
      }
      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 (airavataExperimentId == null) {
        throw new org.apache.thrift.protocol.TProtocolException("Required field 'airavataExperimentId' 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, 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 getIntermediateOutputs_argsStandardSchemeFactory implements SchemeFactory {
      public getIntermediateOutputs_argsStandardScheme getScheme() {
        return new getIntermediateOutputs_argsStandardScheme();
      }
    }

    private static class getIntermediateOutputs_argsStandardScheme extends StandardScheme<getIntermediateOutputs_args> {

      public void read(org.apache.thrift.protocol.TProtocol iprot, getIntermediateOutputs_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_EXPERIMENT_ID
              if (schemeField.type == org.apache.thrift.protocol.TType.STRING) {
                struct.airavataExperimentId = iprot.readString();
                struct.setAiravataExperimentIdIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            default:
              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
          }
          iprot.readFieldEnd();
        }
        iprot.readStructEnd();

        // check for required fields of primitive type, which can't be checked in the validate method
        struct.validate();
      }

      public void write(org.apache.thrift.protocol.TProtocol oprot, getIntermediateOutputs_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.airavataExperimentId != null) {
          oprot.writeFieldBegin(AIRAVATA_EXPERIMENT_ID_FIELD_DESC);
          oprot.writeString(struct.airavataExperimentId);
          oprot.writeFieldEnd();
        }
        oprot.writeFieldStop();
        oprot.writeStructEnd();
      }

    }

    private static class getIntermediateOutputs_argsTupleSchemeFactory implements SchemeFactory {
      public getIntermediateOutputs_argsTupleScheme getScheme() {
        return new getIntermediateOutputs_argsTupleScheme();
      }
    }

    private static class getIntermediateOutputs_argsTupleScheme extends TupleScheme<getIntermediateOutputs_args> {

      @Override
      public void write(org.apache.thrift.protocol.TProtocol prot, getIntermediateOutputs_args struct) throws org.apache.thrift.TException {
        TTupleProtocol oprot = (TTupleProtocol) prot;
        struct.authzToken.write(oprot);
        oprot.writeString(struct.airavataExperimentId);
      }

      @Override
      public void read(org.apache.thrift.protocol.TProtocol prot, getIntermediateOutputs_args struct) throws org.apache.thrift.TException {
        TTupleProtocol iprot = (TTupleProtocol) prot;
        struct.authzToken = new org.apache.airavata.model.security.AuthzToken();
        struct.authzToken.read(iprot);
        struct.setAuthzTokenIsSet(true);
        struct.airavataExperimentId = iprot.readString();
        struct.setAiravataExperimentIdIsSet(true);
      }
    }

  }

  public static class getIntermediateOutputs_result implements org.apache.thrift.TBase<getIntermediateOutputs_result, getIntermediateOutputs_result._Fields>, java.io.Serializable, Cloneable, Comparable<getIntermediateOutputs_result>   {
    private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("getIntermediateOutputs_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 IRE_FIELD_DESC = new org.apache.thrift.protocol.TField("ire", org.apache.thrift.protocol.TType.STRUCT, (short)1);
    private static final org.apache.thrift.protocol.TField ENF_FIELD_DESC = new org.apache.thrift.protocol.TField("enf", org.apache.thrift.protocol.TType.STRUCT, (short)2);
    private static final org.apache.thrift.protocol.TField ACE_FIELD_DESC = new org.apache.thrift.protocol.TField("ace", org.apache.thrift.protocol.TType.STRUCT, (short)3);
    private static final org.apache.thrift.protocol.TField ASE_FIELD_DESC = new org.apache.thrift.protocol.TField("ase", org.apache.thrift.protocol.TType.STRUCT, (short)4);
    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)5);

    private static final Map<Class<? extends IScheme>, SchemeFactory> schemes = new HashMap<Class<? extends IScheme>, SchemeFactory>();
    static {
      schemes.put(StandardScheme.class, new getIntermediateOutputs_resultStandardSchemeFactory());
      schemes.put(TupleScheme.class, new getIntermediateOutputs_resultTupleSchemeFactory());
    }

    public List<org.apache.airavata.model.application.io.OutputDataObjectType> success; // required
    public org.apache.airavata.model.error.InvalidRequestException ire; // required
    public org.apache.airavata.model.error.ExperimentNotFoundException enf; // required
    public org.apache.airavata.model.error.AiravataClientException ace; // required
    public org.apache.airavata.model.error.AiravataSystemException ase; // 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"),
      IRE((short)1, "ire"),
      ENF((short)2, "enf"),
      ACE((short)3, "ace"),
      ASE((short)4, "ase"),
      AE((short)5, "ae");

      private static final Map<String, _Fields> byName = new HashMap<String, _Fields>();

      static {
        for (_Fields field : EnumSet.allOf(_Fields.class)) {
          byName.put(field.getFieldName(), field);
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, or null if its not found.
       */
      public static _Fields findByThriftId(int fieldId) {
        switch(fieldId) {
          case 0: // SUCCESS
            return SUCCESS;
          case 1: // IRE
            return IRE;
          case 2: // ENF
            return ENF;
          case 3: // ACE
            return ACE;
          case 4: // ASE
            return ASE;
          case 5: // 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 IllegalArgumentException("Field " + fieldId + " doesn't exist!");
        return fields;
      }

      /**
       * Find the _Fields constant that matches name, or null if its not found.
       */
      public static _Fields findByName(String name) {
        return byName.get(name);
      }

      private final short _thriftId;
      private final String _fieldName;

      _Fields(short thriftId, String fieldName) {
        _thriftId = thriftId;
        _fieldName = fieldName;
      }

      public short getThriftFieldId() {
        return _thriftId;
      }

      public String getFieldName() {
        return _fieldName;
      }
    }

    // isset id assignments
    public static final Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
    static {
      Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new EnumMap<_Fields, org.apache.thrift.meta_data.FieldMetaData>(_Fields.class);
      tmpMap.put(_Fields.SUCCESS, new org.apache.thrift.meta_data.FieldMetaData("success", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.ListMetaData(org.apache.thrift.protocol.TType.LIST, 
              new org.apache.thrift.meta_data.StructMetaData(org.apache.thrift.protocol.TType.STRUCT, org.apache.airavata.model.application.io.OutputDataObjectType.class))));
      tmpMap.put(_Fields.IRE, new org.apache.thrift.meta_data.FieldMetaData("ire", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRUCT)));
      tmpMap.put(_Fields.ENF, new org.apache.thrift.meta_data.FieldMetaData("enf", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRUCT)));
      tmpMap.put(_Fields.ACE, new org.apache.thrift.meta_data.FieldMetaData("ace", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRUCT)));
      tmpMap.put(_Fields.ASE, new org.apache.thrift.meta_data.FieldMetaData("ase", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRUCT)));
      tmpMap.put(_Fields.AE, new org.apache.thrift.meta_data.FieldMetaData("ae", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRUCT)));
      metaDataMap = Collections.unmodifiableMap(tmpMap);
      org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(getIntermediateOutputs_result.class, metaDataMap);
    }

    public getIntermediateOutputs_result() {
    }

    public getIntermediateOutputs_result(
      List<org.apache.airavata.model.application.io.OutputDataObjectType> success,
      org.apache.airavata.model.error.InvalidRequestException ire,
      org.apache.airavata.model.error.ExperimentNotFoundException enf,
      org.apache.airavata.model.error.AiravataClientException ace,
      org.apache.airavata.model.error.AiravataSystemException ase,
      org.apache.airavata.model.error.AuthorizationException ae)
    {
      this();
      this.success = success;
      this.ire = ire;
      this.enf = enf;
      this.ace = ace;
      this.ase = ase;
      this.ae = ae;
    }

    /**
     * Performs a deep copy on <i>other</i>.
     */
    public getIntermediateOutputs_result(getIntermediateOutputs_result other) {
      if (other.isSetSuccess()) {
        List<org.apache.airavata.model.application.io.OutputDataObjectType> __this__success = new ArrayList<org.apache.airavata.model.application.io.OutputDataObjectType>(other.success.size());
        for (org.apache.airavata.model.application.io.OutputDataObjectType other_element : other.success) {
          __this__success.add(new org.apache.airavata.model.application.io.OutputDataObjectType(other_element));
        }
        this.success = __this__success;
      }
      if (other.isSetIre()) {
        this.ire = new org.apache.airavata.model.error.InvalidRequestException(other.ire);
      }
      if (other.isSetEnf()) {
        this.enf = new org.apache.airavata.model.error.ExperimentNotFoundException(other.enf);
      }
      if (other.isSetAce()) {
        this.ace = new org.apache.airavata.model.error.AiravataClientException(other.ace);
      }
      if (other.isSetAse()) {
        this.ase = new org.apache.airavata.model.error.AiravataSystemException(other.ase);
      }
      if (other.isSetAe()) {
        this.ae = new org.apache.airavata.model.error.AuthorizationException(other.ae);
      }
    }

    public getIntermediateOutputs_result deepCopy() {
      return new getIntermediateOutputs_result(this);
    }

    @Override
    public void clear() {
      this.success = null;
      this.ire = null;
      this.enf = null;
      this.ace = null;
      this.ase = null;
      this.ae = null;
    }

    public int getSuccessSize() {
      return (this.success == null) ? 0 : this.success.size();
    }

    public java.util.Iterator<org.apache.airavata.model.application.io.OutputDataObjectType> getSuccessIterator() {
      return (this.success == null) ? null : this.success.iterator();
    }

    public void addToSuccess(org.apache.airavata.model.application.io.OutputDataObjectType elem) {
      if (this.success == null) {
        this.success = new ArrayList<org.apache.airavata.model.application.io.OutputDataObjectType>();
      }
      this.success.add(elem);
    }

    public List<org.apache.airavata.model.application.io.OutputDataObjectType> getSuccess() {
      return this.success;
    }

    public getIntermediateOutputs_result setSuccess(List<org.apache.airavata.model.application.io.OutputDataObjectType> 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.model.error.InvalidRequestException getIre() {
      return this.ire;
    }

    public getIntermediateOutputs_result setIre(org.apache.airavata.model.error.InvalidRequestException ire) {
      this.ire = ire;
      return this;
    }

    public void unsetIre() {
      this.ire = null;
    }

    /** Returns true if field ire is set (has been assigned a value) and false otherwise */
    public boolean isSetIre() {
      return this.ire != null;
    }

    public void setIreIsSet(boolean value) {
      if (!value) {
        this.ire = null;
      }
    }

    public org.apache.airavata.model.error.ExperimentNotFoundException getEnf() {
      return this.enf;
    }

    public getIntermediateOutputs_result setEnf(org.apache.airavata.model.error.ExperimentNotFoundException enf) {
      this.enf = enf;
      return this;
    }

    public void unsetEnf() {
      this.enf = null;
    }

    /** Returns true if field enf is set (has been assigned a value) and false otherwise */
    public boolean isSetEnf() {
      return this.enf != null;
    }

    public void setEnfIsSet(boolean value) {
      if (!value) {
        this.enf = null;
      }
    }

    public org.apache.airavata.model.error.AiravataClientException getAce() {
      return this.ace;
    }

    public getIntermediateOutputs_result setAce(org.apache.airavata.model.error.AiravataClientException ace) {
      this.ace = ace;
      return this;
    }

    public void unsetAce() {
      this.ace = null;
    }

    /** Returns true if field ace is set (has been assigned a value) and false otherwise */
    public boolean isSetAce() {
      return this.ace != null;
    }

    public void setAceIsSet(boolean value) {
      if (!value) {
        this.ace = null;
      }
    }

    public org.apache.airavata.model.error.AiravataSystemException getAse() {
      return this.ase;
    }

    public getIntermediateOutputs_result setAse(org.apache.airavata.model.error.AiravataSystemException ase) {
      this.ase = ase;
      return this;
    }

    public void unsetAse() {
      this.ase = null;
    }

    /** Returns true if field ase is set (has been assigned a value) and false otherwise */
    public boolean isSetAse() {
      return this.ase != null;
    }

    public void setAseIsSet(boolean value) {
      if (!value) {
        this.ase = null;
      }
    }

    public org.apache.airavata.model.error.AuthorizationException getAe() {
      return this.ae;
    }

    public getIntermediateOutputs_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, Object value) {
      switch (field) {
      case SUCCESS:
        if (value == null) {
          unsetSuccess();
        } else {
          setSuccess((List<org.apache.airavata.model.application.io.OutputDataObjectType>)value);
        }
        break;

      case IRE:
        if (value == null) {
          unsetIre();
        } else {
          setIre((org.apache.airavata.model.error.InvalidRequestException)value);
        }
        break;

      case ENF:
        if (value == null) {
          unsetEnf();
        } else {
          setEnf((org.apache.airavata.model.error.ExperimentNotFoundException)value);
        }
        break;

      case ACE:
        if (value == null) {
          unsetAce();
        } else {
          setAce((org.apache.airavata.model.error.AiravataClientException)value);
        }
        break;

      case ASE:
        if (value == null) {
          unsetAse();
        } else {
          setAse((org.apache.airavata.model.error.AiravataSystemException)value);
        }
        break;

      case AE:
        if (value == null) {
          unsetAe();
        } else {
          setAe((org.apache.airavata.model.error.AuthorizationException)value);
        }
        break;

      }
    }

    public Object getFieldValue(_Fields field) {
      switch (field) {
      case SUCCESS:
        return getSuccess();

      case IRE:
        return getIre();

      case ENF:
        return getEnf();

      case ACE:
        return getAce();

      case ASE:
        return getAse();

      case AE:
        return getAe();

      }
      throw new IllegalStateException();
    }

    /** Returns true if field corresponding to fieldID is set (has been assigned a value) and false otherwise */
    public boolean isSet(_Fields field) {
      if (field == null) {
        throw new IllegalArgumentException();
      }

      switch (field) {
      case SUCCESS:
        return isSetSuccess();
      case IRE:
        return isSetIre();
      case ENF:
        return isSetEnf();
      case ACE:
        return isSetAce();
      case ASE:
        return isSetAse();
      case AE:
        return isSetAe();
      }
      throw new IllegalStateException();
    }

    @Override
    public boolean equals(Object that) {
      if (that == null)
        return false;
      if (that instanceof getIntermediateOutputs_result)
        return this.equals((getIntermediateOutputs_result)that);
      return false;
    }

    public boolean equals(getIntermediateOutputs_result that) {
      if (that == null)
        return false;

      boolean this_present_success = true && this.isSetSuccess();
      boolean that_present_success = true && that.isSetSuccess();
      if (this_present_success || that_present_success) {
        if (!(this_present_success && that_present_success))
          return false;
        if (!this.success.equals(that.success))
          return false;
      }

      boolean this_present_ire = true && this.isSetIre();
      boolean that_present_ire = true && that.isSetIre();
      if (this_present_ire || that_present_ire) {
        if (!(this_present_ire && that_present_ire))
          return false;
        if (!this.ire.equals(that.ire))
          return false;
      }

      boolean this_present_enf = true && this.isSetEnf();
      boolean that_present_enf = true && that.isSetEnf();
      if (this_present_enf || that_present_enf) {
        if (!(this_present_enf && that_present_enf))
          return false;
        if (!this.enf.equals(that.enf))
          return false;
      }

      boolean this_present_ace = true && this.isSetAce();
      boolean that_present_ace = true && that.isSetAce();
      if (this_present_ace || that_present_ace) {
        if (!(this_present_ace && that_present_ace))
          return false;
        if (!this.ace.equals(that.ace))
          return false;
      }

      boolean this_present_ase = true && this.isSetAse();
      boolean that_present_ase = true && that.isSetAse();
      if (this_present_ase || that_present_ase) {
        if (!(this_present_ase && that_present_ase))
          return false;
        if (!this.ase.equals(that.ase))
          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() {
      List<Object> list = new ArrayList<Object>();

      boolean present_success = true && (isSetSuccess());
      list.add(present_success);
      if (present_success)
        list.add(success);

      boolean present_ire = true && (isSetIre());
      list.add(present_ire);
      if (present_ire)
        list.add(ire);

      boolean present_enf = true && (isSetEnf());
      list.add(present_enf);
      if (present_enf)
        list.add(enf);

      boolean present_ace = true && (isSetAce());
      list.add(present_ace);
      if (present_ace)
        list.add(ace);

      boolean present_ase = true && (isSetAse());
      list.add(present_ase);
      if (present_ase)
        list.add(ase);

      boolean present_ae = true && (isSetAe());
      list.add(present_ae);
      if (present_ae)
        list.add(ae);

      return list.hashCode();
    }

    @Override
    public int compareTo(getIntermediateOutputs_result other) {
      if (!getClass().equals(other.getClass())) {
        return getClass().getName().compareTo(other.getClass().getName());
      }

      int lastComparison = 0;

      lastComparison = Boolean.valueOf(isSetSuccess()).compareTo(other.isSetSuccess());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetSuccess()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.success, other.success);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = Boolean.valueOf(isSetIre()).compareTo(other.isSetIre());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetIre()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.ire, other.ire);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = Boolean.valueOf(isSetEnf()).compareTo(other.isSetEnf());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetEnf()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.enf, other.enf);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = Boolean.valueOf(isSetAce()).compareTo(other.isSetAce());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetAce()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.ace, other.ace);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = Boolean.valueOf(isSetAse()).compareTo(other.isSetAse());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetAse()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.ase, other.ase);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = 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 {
      schemes.get(iprot.getScheme()).getScheme().read(iprot, this);
    }

    public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException {
      schemes.get(oprot.getScheme()).getScheme().write(oprot, this);
      }

    @Override
    public String toString() {
      StringBuilder sb = new StringBuilder("getIntermediateOutputs_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("ire:");
      if (this.ire == null) {
        sb.append("null");
      } else {
        sb.append(this.ire);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("enf:");
      if (this.enf == null) {
        sb.append("null");
      } else {
        sb.append(this.enf);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("ace:");
      if (this.ace == null) {
        sb.append("null");
      } else {
        sb.append(this.ace);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("ase:");
      if (this.ase == null) {
        sb.append("null");
      } else {
        sb.append(this.ase);
      }
      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, 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 getIntermediateOutputs_resultStandardSchemeFactory implements SchemeFactory {
      public getIntermediateOutputs_resultStandardScheme getScheme() {
        return new getIntermediateOutputs_resultStandardScheme();
      }
    }

    private static class getIntermediateOutputs_resultStandardScheme extends StandardScheme<getIntermediateOutputs_result> {

      public void read(org.apache.thrift.protocol.TProtocol iprot, getIntermediateOutputs_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 _list124 = iprot.readListBegin();
                  struct.success = new ArrayList<org.apache.airavata.model.application.io.OutputDataObjectType>(_list124.size);
                  org.apache.airavata.model.application.io.OutputDataObjectType _elem125;
                  for (int _i126 = 0; _i126 < _list124.size; ++_i126)
                  {
                    _elem125 = new org.apache.airavata.model.application.io.OutputDataObjectType();
                    _elem125.read(iprot);
                    struct.success.add(_elem125);
                  }
                  iprot.readListEnd();
                }
                struct.setSuccessIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 1: // IRE
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.ire = new org.apache.airavata.model.error.InvalidRequestException();
                struct.ire.read(iprot);
                struct.setIreIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 2: // ENF
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.enf = new org.apache.airavata.model.error.ExperimentNotFoundException();
                struct.enf.read(iprot);
                struct.setEnfIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 3: // ACE
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.ace = new org.apache.airavata.model.error.AiravataClientException();
                struct.ace.read(iprot);
                struct.setAceIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 4: // ASE
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.ase = new org.apache.airavata.model.error.AiravataSystemException();
                struct.ase.read(iprot);
                struct.setAseIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 5: // 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, getIntermediateOutputs_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.application.io.OutputDataObjectType _iter127 : struct.success)
            {
              _iter127.write(oprot);
            }
            oprot.writeListEnd();
          }
          oprot.writeFieldEnd();
        }
        if (struct.ire != null) {
          oprot.writeFieldBegin(IRE_FIELD_DESC);
          struct.ire.write(oprot);
          oprot.writeFieldEnd();
        }
        if (struct.enf != null) {
          oprot.writeFieldBegin(ENF_FIELD_DESC);
          struct.enf.write(oprot);
          oprot.writeFieldEnd();
        }
        if (struct.ace != null) {
          oprot.writeFieldBegin(ACE_FIELD_DESC);
          struct.ace.write(oprot);
          oprot.writeFieldEnd();
        }
        if (struct.ase != null) {
          oprot.writeFieldBegin(ASE_FIELD_DESC);
          struct.ase.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 getIntermediateOutputs_resultTupleSchemeFactory implements SchemeFactory {
      public getIntermediateOutputs_resultTupleScheme getScheme() {
        return new getIntermediateOutputs_resultTupleScheme();
      }
    }

    private static class getIntermediateOutputs_resultTupleScheme extends TupleScheme<getIntermediateOutputs_result> {

      @Override
      public void write(org.apache.thrift.protocol.TProtocol prot, getIntermediateOutputs_result struct) throws org.apache.thrift.TException {
        TTupleProtocol oprot = (TTupleProtocol) prot;
        BitSet optionals = new BitSet();
        if (struct.isSetSuccess()) {
          optionals.set(0);
        }
        if (struct.isSetIre()) {
          optionals.set(1);
        }
        if (struct.isSetEnf()) {
          optionals.set(2);
        }
        if (struct.isSetAce()) {
          optionals.set(3);
        }
        if (struct.isSetAse()) {
          optionals.set(4);
        }
        if (struct.isSetAe()) {
          optionals.set(5);
        }
        oprot.writeBitSet(optionals, 6);
        if (struct.isSetSuccess()) {
          {
            oprot.writeI32(struct.success.size());
            for (org.apache.airavata.model.application.io.OutputDataObjectType _iter128 : struct.success)
            {
              _iter128.write(oprot);
            }
          }
        }
        if (struct.isSetIre()) {
          struct.ire.write(oprot);
        }
        if (struct.isSetEnf()) {
          struct.enf.write(oprot);
        }
        if (struct.isSetAce()) {
          struct.ace.write(oprot);
        }
        if (struct.isSetAse()) {
          struct.ase.write(oprot);
        }
        if (struct.isSetAe()) {
          struct.ae.write(oprot);
        }
      }

      @Override
      public void read(org.apache.thrift.protocol.TProtocol prot, getIntermediateOutputs_result struct) throws org.apache.thrift.TException {
        TTupleProtocol iprot = (TTupleProtocol) prot;
        BitSet incoming = iprot.readBitSet(6);
        if (incoming.get(0)) {
          {
            org.apache.thrift.protocol.TList _list129 = new org.apache.thrift.protocol.TList(org.apache.thrift.protocol.TType.STRUCT, iprot.readI32());
            struct.success = new ArrayList<org.apache.airavata.model.application.io.OutputDataObjectType>(_list129.size);
            org.apache.airavata.model.application.io.OutputDataObjectType _elem130;
            for (int _i131 = 0; _i131 < _list129.size; ++_i131)
            {
              _elem130 = new org.apache.airavata.model.application.io.OutputDataObjectType();
              _elem130.read(iprot);
              struct.success.add(_elem130);
            }
          }
          struct.setSuccessIsSet(true);
        }
        if (incoming.get(1)) {
          struct.ire = new org.apache.airavata.model.error.InvalidRequestException();
          struct.ire.read(iprot);
          struct.setIreIsSet(true);
        }
        if (incoming.get(2)) {
          struct.enf = new org.apache.airavata.model.error.ExperimentNotFoundException();
          struct.enf.read(iprot);
          struct.setEnfIsSet(true);
        }
        if (incoming.get(3)) {
          struct.ace = new org.apache.airavata.model.error.AiravataClientException();
          struct.ace.read(iprot);
          struct.setAceIsSet(true);
        }
        if (incoming.get(4)) {
          struct.ase = new org.apache.airavata.model.error.AiravataSystemException();
          struct.ase.read(iprot);
          struct.setAseIsSet(true);
        }
        if (incoming.get(5)) {
          struct.ae = new org.apache.airavata.model.error.AuthorizationException();
          struct.ae.read(iprot);
          struct.setAeIsSet(true);
        }
      }
    }

  }

  public static class getJobStatuses_args implements org.apache.thrift.TBase<getJobStatuses_args, getJobStatuses_args._Fields>, java.io.Serializable, Cloneable, Comparable<getJobStatuses_args>   {
    private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("getJobStatuses_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_EXPERIMENT_ID_FIELD_DESC = new org.apache.thrift.protocol.TField("airavataExperimentId", org.apache.thrift.protocol.TType.STRING, (short)2);

    private static final Map<Class<? extends IScheme>, SchemeFactory> schemes = new HashMap<Class<? extends IScheme>, SchemeFactory>();
    static {
      schemes.put(StandardScheme.class, new getJobStatuses_argsStandardSchemeFactory());
      schemes.put(TupleScheme.class, new getJobStatuses_argsTupleSchemeFactory());
    }

    public org.apache.airavata.model.security.AuthzToken authzToken; // required
    public String airavataExperimentId; // required

    /** 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_EXPERIMENT_ID((short)2, "airavataExperimentId");

      private static final Map<String, _Fields> byName = new HashMap<String, _Fields>();

      static {
        for (_Fields field : EnumSet.allOf(_Fields.class)) {
          byName.put(field.getFieldName(), field);
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, or null if its not found.
       */
      public static _Fields findByThriftId(int fieldId) {
        switch(fieldId) {
          case 1: // AUTHZ_TOKEN
            return AUTHZ_TOKEN;
          case 2: // AIRAVATA_EXPERIMENT_ID
            return AIRAVATA_EXPERIMENT_ID;
          default:
            return null;
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, throwing an exception
       * if it is not found.
       */
      public static _Fields findByThriftIdOrThrow(int fieldId) {
        _Fields fields = findByThriftId(fieldId);
        if (fields == null) throw new IllegalArgumentException("Field " + fieldId + " doesn't exist!");
        return fields;
      }

      /**
       * Find the _Fields constant that matches name, or null if its not found.
       */
      public static _Fields findByName(String name) {
        return byName.get(name);
      }

      private final short _thriftId;
      private final String _fieldName;

      _Fields(short thriftId, String fieldName) {
        _thriftId = thriftId;
        _fieldName = fieldName;
      }

      public short getThriftFieldId() {
        return _thriftId;
      }

      public String getFieldName() {
        return _fieldName;
      }
    }

    // isset id assignments
    public static final Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
    static {
      Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new EnumMap<_Fields, org.apache.thrift.meta_data.FieldMetaData>(_Fields.class);
      tmpMap.put(_Fields.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_EXPERIMENT_ID, new org.apache.thrift.meta_data.FieldMetaData("airavataExperimentId", org.apache.thrift.TFieldRequirementType.REQUIRED, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING)));
      metaDataMap = Collections.unmodifiableMap(tmpMap);
      org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(getJobStatuses_args.class, metaDataMap);
    }

    public getJobStatuses_args() {
    }

    public getJobStatuses_args(
      org.apache.airavata.model.security.AuthzToken authzToken,
      String airavataExperimentId)
    {
      this();
      this.authzToken = authzToken;
      this.airavataExperimentId = airavataExperimentId;
    }

    /**
     * Performs a deep copy on <i>other</i>.
     */
    public getJobStatuses_args(getJobStatuses_args other) {
      if (other.isSetAuthzToken()) {
        this.authzToken = new org.apache.airavata.model.security.AuthzToken(other.authzToken);
      }
      if (other.isSetAiravataExperimentId()) {
        this.airavataExperimentId = other.airavataExperimentId;
      }
    }

    public getJobStatuses_args deepCopy() {
      return new getJobStatuses_args(this);
    }

    @Override
    public void clear() {
      this.authzToken = null;
      this.airavataExperimentId = null;
    }

    public org.apache.airavata.model.security.AuthzToken getAuthzToken() {
      return this.authzToken;
    }

    public getJobStatuses_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 String getAiravataExperimentId() {
      return this.airavataExperimentId;
    }

    public getJobStatuses_args setAiravataExperimentId(String airavataExperimentId) {
      this.airavataExperimentId = airavataExperimentId;
      return this;
    }

    public void unsetAiravataExperimentId() {
      this.airavataExperimentId = null;
    }

    /** Returns true if field airavataExperimentId is set (has been assigned a value) and false otherwise */
    public boolean isSetAiravataExperimentId() {
      return this.airavataExperimentId != null;
    }

    public void setAiravataExperimentIdIsSet(boolean value) {
      if (!value) {
        this.airavataExperimentId = null;
      }
    }

    public void setFieldValue(_Fields field, Object value) {
      switch (field) {
      case AUTHZ_TOKEN:
        if (value == null) {
          unsetAuthzToken();
        } else {
          setAuthzToken((org.apache.airavata.model.security.AuthzToken)value);
        }
        break;

      case AIRAVATA_EXPERIMENT_ID:
        if (value == null) {
          unsetAiravataExperimentId();
        } else {
          setAiravataExperimentId((String)value);
        }
        break;

      }
    }

    public Object getFieldValue(_Fields field) {
      switch (field) {
      case AUTHZ_TOKEN:
        return getAuthzToken();

      case AIRAVATA_EXPERIMENT_ID:
        return getAiravataExperimentId();

      }
      throw new IllegalStateException();
    }

    /** Returns true if field corresponding to fieldID is set (has been assigned a value) and false otherwise */
    public boolean isSet(_Fields field) {
      if (field == null) {
        throw new IllegalArgumentException();
      }

      switch (field) {
      case AUTHZ_TOKEN:
        return isSetAuthzToken();
      case AIRAVATA_EXPERIMENT_ID:
        return isSetAiravataExperimentId();
      }
      throw new IllegalStateException();
    }

    @Override
    public boolean equals(Object that) {
      if (that == null)
        return false;
      if (that instanceof getJobStatuses_args)
        return this.equals((getJobStatuses_args)that);
      return false;
    }

    public boolean equals(getJobStatuses_args that) {
      if (that == null)
        return false;

      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_airavataExperimentId = true && this.isSetAiravataExperimentId();
      boolean that_present_airavataExperimentId = true && that.isSetAiravataExperimentId();
      if (this_present_airavataExperimentId || that_present_airavataExperimentId) {
        if (!(this_present_airavataExperimentId && that_present_airavataExperimentId))
          return false;
        if (!this.airavataExperimentId.equals(that.airavataExperimentId))
          return false;
      }

      return true;
    }

    @Override
    public int hashCode() {
      List<Object> list = new ArrayList<Object>();

      boolean present_authzToken = true && (isSetAuthzToken());
      list.add(present_authzToken);
      if (present_authzToken)
        list.add(authzToken);

      boolean present_airavataExperimentId = true && (isSetAiravataExperimentId());
      list.add(present_airavataExperimentId);
      if (present_airavataExperimentId)
        list.add(airavataExperimentId);

      return list.hashCode();
    }

    @Override
    public int compareTo(getJobStatuses_args other) {
      if (!getClass().equals(other.getClass())) {
        return getClass().getName().compareTo(other.getClass().getName());
      }

      int lastComparison = 0;

      lastComparison = 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 = Boolean.valueOf(isSetAiravataExperimentId()).compareTo(other.isSetAiravataExperimentId());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetAiravataExperimentId()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.airavataExperimentId, other.airavataExperimentId);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      return 0;
    }

    public _Fields fieldForId(int fieldId) {
      return _Fields.findByThriftId(fieldId);
    }

    public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
      schemes.get(iprot.getScheme()).getScheme().read(iprot, this);
    }

    public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException {
      schemes.get(oprot.getScheme()).getScheme().write(oprot, this);
    }

    @Override
    public String toString() {
      StringBuilder sb = new StringBuilder("getJobStatuses_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("airavataExperimentId:");
      if (this.airavataExperimentId == null) {
        sb.append("null");
      } else {
        sb.append(this.airavataExperimentId);
      }
      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 (airavataExperimentId == null) {
        throw new org.apache.thrift.protocol.TProtocolException("Required field 'airavataExperimentId' 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, 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 getJobStatuses_argsStandardSchemeFactory implements SchemeFactory {
      public getJobStatuses_argsStandardScheme getScheme() {
        return new getJobStatuses_argsStandardScheme();
      }
    }

    private static class getJobStatuses_argsStandardScheme extends StandardScheme<getJobStatuses_args> {

      public void read(org.apache.thrift.protocol.TProtocol iprot, getJobStatuses_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_EXPERIMENT_ID
              if (schemeField.type == org.apache.thrift.protocol.TType.STRING) {
                struct.airavataExperimentId = iprot.readString();
                struct.setAiravataExperimentIdIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            default:
              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
          }
          iprot.readFieldEnd();
        }
        iprot.readStructEnd();

        // check for required fields of primitive type, which can't be checked in the validate method
        struct.validate();
      }

      public void write(org.apache.thrift.protocol.TProtocol oprot, getJobStatuses_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.airavataExperimentId != null) {
          oprot.writeFieldBegin(AIRAVATA_EXPERIMENT_ID_FIELD_DESC);
          oprot.writeString(struct.airavataExperimentId);
          oprot.writeFieldEnd();
        }
        oprot.writeFieldStop();
        oprot.writeStructEnd();
      }

    }

    private static class getJobStatuses_argsTupleSchemeFactory implements SchemeFactory {
      public getJobStatuses_argsTupleScheme getScheme() {
        return new getJobStatuses_argsTupleScheme();
      }
    }

    private static class getJobStatuses_argsTupleScheme extends TupleScheme<getJobStatuses_args> {

      @Override
      public void write(org.apache.thrift.protocol.TProtocol prot, getJobStatuses_args struct) throws org.apache.thrift.TException {
        TTupleProtocol oprot = (TTupleProtocol) prot;
        struct.authzToken.write(oprot);
        oprot.writeString(struct.airavataExperimentId);
      }

      @Override
      public void read(org.apache.thrift.protocol.TProtocol prot, getJobStatuses_args struct) throws org.apache.thrift.TException {
        TTupleProtocol iprot = (TTupleProtocol) prot;
        struct.authzToken = new org.apache.airavata.model.security.AuthzToken();
        struct.authzToken.read(iprot);
        struct.setAuthzTokenIsSet(true);
        struct.airavataExperimentId = iprot.readString();
        struct.setAiravataExperimentIdIsSet(true);
      }
    }

  }

  public static class getJobStatuses_result implements org.apache.thrift.TBase<getJobStatuses_result, getJobStatuses_result._Fields>, java.io.Serializable, Cloneable, Comparable<getJobStatuses_result>   {
    private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("getJobStatuses_result");

    private static final org.apache.thrift.protocol.TField SUCCESS_FIELD_DESC = new org.apache.thrift.protocol.TField("success", org.apache.thrift.protocol.TType.MAP, (short)0);
    private static final org.apache.thrift.protocol.TField IRE_FIELD_DESC = new org.apache.thrift.protocol.TField("ire", org.apache.thrift.protocol.TType.STRUCT, (short)1);
    private static final org.apache.thrift.protocol.TField ENF_FIELD_DESC = new org.apache.thrift.protocol.TField("enf", org.apache.thrift.protocol.TType.STRUCT, (short)2);
    private static final org.apache.thrift.protocol.TField ACE_FIELD_DESC = new org.apache.thrift.protocol.TField("ace", org.apache.thrift.protocol.TType.STRUCT, (short)3);
    private static final org.apache.thrift.protocol.TField ASE_FIELD_DESC = new org.apache.thrift.protocol.TField("ase", org.apache.thrift.protocol.TType.STRUCT, (short)4);
    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)5);

    private static final Map<Class<? extends IScheme>, SchemeFactory> schemes = new HashMap<Class<? extends IScheme>, SchemeFactory>();
    static {
      schemes.put(StandardScheme.class, new getJobStatuses_resultStandardSchemeFactory());
      schemes.put(TupleScheme.class, new getJobStatuses_resultTupleSchemeFactory());
    }

    public Map<String,org.apache.airavata.model.status.JobStatus> success; // required
    public org.apache.airavata.model.error.InvalidRequestException ire; // required
    public org.apache.airavata.model.error.ExperimentNotFoundException enf; // required
    public org.apache.airavata.model.error.AiravataClientException ace; // required
    public org.apache.airavata.model.error.AiravataSystemException ase; // 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"),
      IRE((short)1, "ire"),
      ENF((short)2, "enf"),
      ACE((short)3, "ace"),
      ASE((short)4, "ase"),
      AE((short)5, "ae");

      private static final Map<String, _Fields> byName = new HashMap<String, _Fields>();

      static {
        for (_Fields field : EnumSet.allOf(_Fields.class)) {
          byName.put(field.getFieldName(), field);
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, or null if its not found.
       */
      public static _Fields findByThriftId(int fieldId) {
        switch(fieldId) {
          case 0: // SUCCESS
            return SUCCESS;
          case 1: // IRE
            return IRE;
          case 2: // ENF
            return ENF;
          case 3: // ACE
            return ACE;
          case 4: // ASE
            return ASE;
          case 5: // 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 IllegalArgumentException("Field " + fieldId + " doesn't exist!");
        return fields;
      }

      /**
       * Find the _Fields constant that matches name, or null if its not found.
       */
      public static _Fields findByName(String name) {
        return byName.get(name);
      }

      private final short _thriftId;
      private final String _fieldName;

      _Fields(short thriftId, String fieldName) {
        _thriftId = thriftId;
        _fieldName = fieldName;
      }

      public short getThriftFieldId() {
        return _thriftId;
      }

      public String getFieldName() {
        return _fieldName;
      }
    }

    // isset id assignments
    public static final Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
    static {
      Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new EnumMap<_Fields, org.apache.thrift.meta_data.FieldMetaData>(_Fields.class);
      tmpMap.put(_Fields.SUCCESS, new org.apache.thrift.meta_data.FieldMetaData("success", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.MapMetaData(org.apache.thrift.protocol.TType.MAP, 
              new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING), 
              new org.apache.thrift.meta_data.StructMetaData(org.apache.thrift.protocol.TType.STRUCT, org.apache.airavata.model.status.JobStatus.class))));
      tmpMap.put(_Fields.IRE, new org.apache.thrift.meta_data.FieldMetaData("ire", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRUCT)));
      tmpMap.put(_Fields.ENF, new org.apache.thrift.meta_data.FieldMetaData("enf", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRUCT)));
      tmpMap.put(_Fields.ACE, new org.apache.thrift.meta_data.FieldMetaData("ace", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRUCT)));
      tmpMap.put(_Fields.ASE, new org.apache.thrift.meta_data.FieldMetaData("ase", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRUCT)));
      tmpMap.put(_Fields.AE, new org.apache.thrift.meta_data.FieldMetaData("ae", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRUCT)));
      metaDataMap = Collections.unmodifiableMap(tmpMap);
      org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(getJobStatuses_result.class, metaDataMap);
    }

    public getJobStatuses_result() {
    }

    public getJobStatuses_result(
      Map<String,org.apache.airavata.model.status.JobStatus> success,
      org.apache.airavata.model.error.InvalidRequestException ire,
      org.apache.airavata.model.error.ExperimentNotFoundException enf,
      org.apache.airavata.model.error.AiravataClientException ace,
      org.apache.airavata.model.error.AiravataSystemException ase,
      org.apache.airavata.model.error.AuthorizationException ae)
    {
      this();
      this.success = success;
      this.ire = ire;
      this.enf = enf;
      this.ace = ace;
      this.ase = ase;
      this.ae = ae;
    }

    /**
     * Performs a deep copy on <i>other</i>.
     */
    public getJobStatuses_result(getJobStatuses_result other) {
      if (other.isSetSuccess()) {
        Map<String,org.apache.airavata.model.status.JobStatus> __this__success = new HashMap<String,org.apache.airavata.model.status.JobStatus>(other.success.size());
        for (Map.Entry<String, org.apache.airavata.model.status.JobStatus> other_element : other.success.entrySet()) {

          String other_element_key = other_element.getKey();
          org.apache.airavata.model.status.JobStatus other_element_value = other_element.getValue();

          String __this__success_copy_key = other_element_key;

          org.apache.airavata.model.status.JobStatus __this__success_copy_value = new org.apache.airavata.model.status.JobStatus(other_element_value);

          __this__success.put(__this__success_copy_key, __this__success_copy_value);
        }
        this.success = __this__success;
      }
      if (other.isSetIre()) {
        this.ire = new org.apache.airavata.model.error.InvalidRequestException(other.ire);
      }
      if (other.isSetEnf()) {
        this.enf = new org.apache.airavata.model.error.ExperimentNotFoundException(other.enf);
      }
      if (other.isSetAce()) {
        this.ace = new org.apache.airavata.model.error.AiravataClientException(other.ace);
      }
      if (other.isSetAse()) {
        this.ase = new org.apache.airavata.model.error.AiravataSystemException(other.ase);
      }
      if (other.isSetAe()) {
        this.ae = new org.apache.airavata.model.error.AuthorizationException(other.ae);
      }
    }

    public getJobStatuses_result deepCopy() {
      return new getJobStatuses_result(this);
    }

    @Override
    public void clear() {
      this.success = null;
      this.ire = null;
      this.enf = null;
      this.ace = null;
      this.ase = null;
      this.ae = null;
    }

    public int getSuccessSize() {
      return (this.success == null) ? 0 : this.success.size();
    }

    public void putToSuccess(String key, org.apache.airavata.model.status.JobStatus val) {
      if (this.success == null) {
        this.success = new HashMap<String,org.apache.airavata.model.status.JobStatus>();
      }
      this.success.put(key, val);
    }

    public Map<String,org.apache.airavata.model.status.JobStatus> getSuccess() {
      return this.success;
    }

    public getJobStatuses_result setSuccess(Map<String,org.apache.airavata.model.status.JobStatus> 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.model.error.InvalidRequestException getIre() {
      return this.ire;
    }

    public getJobStatuses_result setIre(org.apache.airavata.model.error.InvalidRequestException ire) {
      this.ire = ire;
      return this;
    }

    public void unsetIre() {
      this.ire = null;
    }

    /** Returns true if field ire is set (has been assigned a value) and false otherwise */
    public boolean isSetIre() {
      return this.ire != null;
    }

    public void setIreIsSet(boolean value) {
      if (!value) {
        this.ire = null;
      }
    }

    public org.apache.airavata.model.error.ExperimentNotFoundException getEnf() {
      return this.enf;
    }

    public getJobStatuses_result setEnf(org.apache.airavata.model.error.ExperimentNotFoundException enf) {
      this.enf = enf;
      return this;
    }

    public void unsetEnf() {
      this.enf = null;
    }

    /** Returns true if field enf is set (has been assigned a value) and false otherwise */
    public boolean isSetEnf() {
      return this.enf != null;
    }

    public void setEnfIsSet(boolean value) {
      if (!value) {
        this.enf = null;
      }
    }

    public org.apache.airavata.model.error.AiravataClientException getAce() {
      return this.ace;
    }

    public getJobStatuses_result setAce(org.apache.airavata.model.error.AiravataClientException ace) {
      this.ace = ace;
      return this;
    }

    public void unsetAce() {
      this.ace = null;
    }

    /** Returns true if field ace is set (has been assigned a value) and false otherwise */
    public boolean isSetAce() {
      return this.ace != null;
    }

    public void setAceIsSet(boolean value) {
      if (!value) {
        this.ace = null;
      }
    }

    public org.apache.airavata.model.error.AiravataSystemException getAse() {
      return this.ase;
    }

    public getJobStatuses_result setAse(org.apache.airavata.model.error.AiravataSystemException ase) {
      this.ase = ase;
      return this;
    }

    public void unsetAse() {
      this.ase = null;
    }

    /** Returns true if field ase is set (has been assigned a value) and false otherwise */
    public boolean isSetAse() {
      return this.ase != null;
    }

    public void setAseIsSet(boolean value) {
      if (!value) {
        this.ase = null;
      }
    }

    public org.apache.airavata.model.error.AuthorizationException getAe() {
      return this.ae;
    }

    public getJobStatuses_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, Object value) {
      switch (field) {
      case SUCCESS:
        if (value == null) {
          unsetSuccess();
        } else {
          setSuccess((Map<String,org.apache.airavata.model.status.JobStatus>)value);
        }
        break;

      case IRE:
        if (value == null) {
          unsetIre();
        } else {
          setIre((org.apache.airavata.model.error.InvalidRequestException)value);
        }
        break;

      case ENF:
        if (value == null) {
          unsetEnf();
        } else {
          setEnf((org.apache.airavata.model.error.ExperimentNotFoundException)value);
        }
        break;

      case ACE:
        if (value == null) {
          unsetAce();
        } else {
          setAce((org.apache.airavata.model.error.AiravataClientException)value);
        }
        break;

      case ASE:
        if (value == null) {
          unsetAse();
        } else {
          setAse((org.apache.airavata.model.error.AiravataSystemException)value);
        }
        break;

      case AE:
        if (value == null) {
          unsetAe();
        } else {
          setAe((org.apache.airavata.model.error.AuthorizationException)value);
        }
        break;

      }
    }

    public Object getFieldValue(_Fields field) {
      switch (field) {
      case SUCCESS:
        return getSuccess();

      case IRE:
        return getIre();

      case ENF:
        return getEnf();

      case ACE:
        return getAce();

      case ASE:
        return getAse();

      case AE:
        return getAe();

      }
      throw new IllegalStateException();
    }

    /** Returns true if field corresponding to fieldID is set (has been assigned a value) and false otherwise */
    public boolean isSet(_Fields field) {
      if (field == null) {
        throw new IllegalArgumentException();
      }

      switch (field) {
      case SUCCESS:
        return isSetSuccess();
      case IRE:
        return isSetIre();
      case ENF:
        return isSetEnf();
      case ACE:
        return isSetAce();
      case ASE:
        return isSetAse();
      case AE:
        return isSetAe();
      }
      throw new IllegalStateException();
    }

    @Override
    public boolean equals(Object that) {
      if (that == null)
        return false;
      if (that instanceof getJobStatuses_result)
        return this.equals((getJobStatuses_result)that);
      return false;
    }

    public boolean equals(getJobStatuses_result that) {
      if (that == null)
        return false;

      boolean this_present_success = true && this.isSetSuccess();
      boolean that_present_success = true && that.isSetSuccess();
      if (this_present_success || that_present_success) {
        if (!(this_present_success && that_present_success))
          return false;
        if (!this.success.equals(that.success))
          return false;
      }

      boolean this_present_ire = true && this.isSetIre();
      boolean that_present_ire = true && that.isSetIre();
      if (this_present_ire || that_present_ire) {
        if (!(this_present_ire && that_present_ire))
          return false;
        if (!this.ire.equals(that.ire))
          return false;
      }

      boolean this_present_enf = true && this.isSetEnf();
      boolean that_present_enf = true && that.isSetEnf();
      if (this_present_enf || that_present_enf) {
        if (!(this_present_enf && that_present_enf))
          return false;
        if (!this.enf.equals(that.enf))
          return false;
      }

      boolean this_present_ace = true && this.isSetAce();
      boolean that_present_ace = true && that.isSetAce();
      if (this_present_ace || that_present_ace) {
        if (!(this_present_ace && that_present_ace))
          return false;
        if (!this.ace.equals(that.ace))
          return false;
      }

      boolean this_present_ase = true && this.isSetAse();
      boolean that_present_ase = true && that.isSetAse();
      if (this_present_ase || that_present_ase) {
        if (!(this_present_ase && that_present_ase))
          return false;
        if (!this.ase.equals(that.ase))
          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() {
      List<Object> list = new ArrayList<Object>();

      boolean present_success = true && (isSetSuccess());
      list.add(present_success);
      if (present_success)
        list.add(success);

      boolean present_ire = true && (isSetIre());
      list.add(present_ire);
      if (present_ire)
        list.add(ire);

      boolean present_enf = true && (isSetEnf());
      list.add(present_enf);
      if (present_enf)
        list.add(enf);

      boolean present_ace = true && (isSetAce());
      list.add(present_ace);
      if (present_ace)
        list.add(ace);

      boolean present_ase = true && (isSetAse());
      list.add(present_ase);
      if (present_ase)
        list.add(ase);

      boolean present_ae = true && (isSetAe());
      list.add(present_ae);
      if (present_ae)
        list.add(ae);

      return list.hashCode();
    }

    @Override
    public int compareTo(getJobStatuses_result other) {
      if (!getClass().equals(other.getClass())) {
        return getClass().getName().compareTo(other.getClass().getName());
      }

      int lastComparison = 0;

      lastComparison = Boolean.valueOf(isSetSuccess()).compareTo(other.isSetSuccess());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetSuccess()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.success, other.success);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = Boolean.valueOf(isSetIre()).compareTo(other.isSetIre());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetIre()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.ire, other.ire);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = Boolean.valueOf(isSetEnf()).compareTo(other.isSetEnf());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetEnf()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.enf, other.enf);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = Boolean.valueOf(isSetAce()).compareTo(other.isSetAce());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetAce()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.ace, other.ace);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = Boolean.valueOf(isSetAse()).compareTo(other.isSetAse());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetAse()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.ase, other.ase);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = 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 {
      schemes.get(iprot.getScheme()).getScheme().read(iprot, this);
    }

    public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException {
      schemes.get(oprot.getScheme()).getScheme().write(oprot, this);
      }

    @Override
    public String toString() {
      StringBuilder sb = new StringBuilder("getJobStatuses_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("ire:");
      if (this.ire == null) {
        sb.append("null");
      } else {
        sb.append(this.ire);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("enf:");
      if (this.enf == null) {
        sb.append("null");
      } else {
        sb.append(this.enf);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("ace:");
      if (this.ace == null) {
        sb.append("null");
      } else {
        sb.append(this.ace);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("ase:");
      if (this.ase == null) {
        sb.append("null");
      } else {
        sb.append(this.ase);
      }
      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, 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 getJobStatuses_resultStandardSchemeFactory implements SchemeFactory {
      public getJobStatuses_resultStandardScheme getScheme() {
        return new getJobStatuses_resultStandardScheme();
      }
    }

    private static class getJobStatuses_resultStandardScheme extends StandardScheme<getJobStatuses_result> {

      public void read(org.apache.thrift.protocol.TProtocol iprot, getJobStatuses_result struct) throws org.apache.thrift.TException {
        org.apache.thrift.protocol.TField schemeField;
        iprot.readStructBegin();
        while (true)
        {
          schemeField = iprot.readFieldBegin();
          if (schemeField.type == org.apache.thrift.protocol.TType.STOP) { 
            break;
          }
          switch (schemeField.id) {
            case 0: // SUCCESS
              if (schemeField.type == org.apache.thrift.protocol.TType.MAP) {
                {
                  org.apache.thrift.protocol.TMap _map132 = iprot.readMapBegin();
                  struct.success = new HashMap<String,org.apache.airavata.model.status.JobStatus>(2*_map132.size);
                  String _key133;
                  org.apache.airavata.model.status.JobStatus _val134;
                  for (int _i135 = 0; _i135 < _map132.size; ++_i135)
                  {
                    _key133 = iprot.readString();
                    _val134 = new org.apache.airavata.model.status.JobStatus();
                    _val134.read(iprot);
                    struct.success.put(_key133, _val134);
                  }
                  iprot.readMapEnd();
                }
                struct.setSuccessIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 1: // IRE
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.ire = new org.apache.airavata.model.error.InvalidRequestException();
                struct.ire.read(iprot);
                struct.setIreIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 2: // ENF
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.enf = new org.apache.airavata.model.error.ExperimentNotFoundException();
                struct.enf.read(iprot);
                struct.setEnfIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 3: // ACE
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.ace = new org.apache.airavata.model.error.AiravataClientException();
                struct.ace.read(iprot);
                struct.setAceIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 4: // ASE
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.ase = new org.apache.airavata.model.error.AiravataSystemException();
                struct.ase.read(iprot);
                struct.setAseIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 5: // 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, getJobStatuses_result struct) throws org.apache.thrift.TException {
        struct.validate();

        oprot.writeStructBegin(STRUCT_DESC);
        if (struct.success != null) {
          oprot.writeFieldBegin(SUCCESS_FIELD_DESC);
          {
            oprot.writeMapBegin(new org.apache.thrift.protocol.TMap(org.apache.thrift.protocol.TType.STRING, org.apache.thrift.protocol.TType.STRUCT, struct.success.size()));
            for (Map.Entry<String, org.apache.airavata.model.status.JobStatus> _iter136 : struct.success.entrySet())
            {
              oprot.writeString(_iter136.getKey());
              _iter136.getValue().write(oprot);
            }
            oprot.writeMapEnd();
          }
          oprot.writeFieldEnd();
        }
        if (struct.ire != null) {
          oprot.writeFieldBegin(IRE_FIELD_DESC);
          struct.ire.write(oprot);
          oprot.writeFieldEnd();
        }
        if (struct.enf != null) {
          oprot.writeFieldBegin(ENF_FIELD_DESC);
          struct.enf.write(oprot);
          oprot.writeFieldEnd();
        }
        if (struct.ace != null) {
          oprot.writeFieldBegin(ACE_FIELD_DESC);
          struct.ace.write(oprot);
          oprot.writeFieldEnd();
        }
        if (struct.ase != null) {
          oprot.writeFieldBegin(ASE_FIELD_DESC);
          struct.ase.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 getJobStatuses_resultTupleSchemeFactory implements SchemeFactory {
      public getJobStatuses_resultTupleScheme getScheme() {
        return new getJobStatuses_resultTupleScheme();
      }
    }

    private static class getJobStatuses_resultTupleScheme extends TupleScheme<getJobStatuses_result> {

      @Override
      public void write(org.apache.thrift.protocol.TProtocol prot, getJobStatuses_result struct) throws org.apache.thrift.TException {
        TTupleProtocol oprot = (TTupleProtocol) prot;
        BitSet optionals = new BitSet();
        if (struct.isSetSuccess()) {
          optionals.set(0);
        }
        if (struct.isSetIre()) {
          optionals.set(1);
        }
        if (struct.isSetEnf()) {
          optionals.set(2);
        }
        if (struct.isSetAce()) {
          optionals.set(3);
        }
        if (struct.isSetAse()) {
          optionals.set(4);
        }
        if (struct.isSetAe()) {
          optionals.set(5);
        }
        oprot.writeBitSet(optionals, 6);
        if (struct.isSetSuccess()) {
          {
            oprot.writeI32(struct.success.size());
            for (Map.Entry<String, org.apache.airavata.model.status.JobStatus> _iter137 : struct.success.entrySet())
            {
              oprot.writeString(_iter137.getKey());
              _iter137.getValue().write(oprot);
            }
          }
        }
        if (struct.isSetIre()) {
          struct.ire.write(oprot);
        }
        if (struct.isSetEnf()) {
          struct.enf.write(oprot);
        }
        if (struct.isSetAce()) {
          struct.ace.write(oprot);
        }
        if (struct.isSetAse()) {
          struct.ase.write(oprot);
        }
        if (struct.isSetAe()) {
          struct.ae.write(oprot);
        }
      }

      @Override
      public void read(org.apache.thrift.protocol.TProtocol prot, getJobStatuses_result struct) throws org.apache.thrift.TException {
        TTupleProtocol iprot = (TTupleProtocol) prot;
        BitSet incoming = iprot.readBitSet(6);
        if (incoming.get(0)) {
          {
            org.apache.thrift.protocol.TMap _map138 = new org.apache.thrift.protocol.TMap(org.apache.thrift.protocol.TType.STRING, org.apache.thrift.protocol.TType.STRUCT, iprot.readI32());
            struct.success = new HashMap<String,org.apache.airavata.model.status.JobStatus>(2*_map138.size);
            String _key139;
            org.apache.airavata.model.status.JobStatus _val140;
            for (int _i141 = 0; _i141 < _map138.size; ++_i141)
            {
              _key139 = iprot.readString();
              _val140 = new org.apache.airavata.model.status.JobStatus();
              _val140.read(iprot);
              struct.success.put(_key139, _val140);
            }
          }
          struct.setSuccessIsSet(true);
        }
        if (incoming.get(1)) {
          struct.ire = new org.apache.airavata.model.error.InvalidRequestException();
          struct.ire.read(iprot);
          struct.setIreIsSet(true);
        }
        if (incoming.get(2)) {
          struct.enf = new org.apache.airavata.model.error.ExperimentNotFoundException();
          struct.enf.read(iprot);
          struct.setEnfIsSet(true);
        }
        if (incoming.get(3)) {
          struct.ace = new org.apache.airavata.model.error.AiravataClientException();
          struct.ace.read(iprot);
          struct.setAceIsSet(true);
        }
        if (incoming.get(4)) {
          struct.ase = new org.apache.airavata.model.error.AiravataSystemException();
          struct.ase.read(iprot);
          struct.setAseIsSet(true);
        }
        if (incoming.get(5)) {
          struct.ae = new org.apache.airavata.model.error.AuthorizationException();
          struct.ae.read(iprot);
          struct.setAeIsSet(true);
        }
      }
    }

  }

  public static class getJobDetails_args implements org.apache.thrift.TBase<getJobDetails_args, getJobDetails_args._Fields>, java.io.Serializable, Cloneable, Comparable<getJobDetails_args>   {
    private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("getJobDetails_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_EXPERIMENT_ID_FIELD_DESC = new org.apache.thrift.protocol.TField("airavataExperimentId", org.apache.thrift.protocol.TType.STRING, (short)2);

    private static final Map<Class<? extends IScheme>, SchemeFactory> schemes = new HashMap<Class<? extends IScheme>, SchemeFactory>();
    static {
      schemes.put(StandardScheme.class, new getJobDetails_argsStandardSchemeFactory());
      schemes.put(TupleScheme.class, new getJobDetails_argsTupleSchemeFactory());
    }

    public org.apache.airavata.model.security.AuthzToken authzToken; // required
    public String airavataExperimentId; // required

    /** 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_EXPERIMENT_ID((short)2, "airavataExperimentId");

      private static final Map<String, _Fields> byName = new HashMap<String, _Fields>();

      static {
        for (_Fields field : EnumSet.allOf(_Fields.class)) {
          byName.put(field.getFieldName(), field);
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, or null if its not found.
       */
      public static _Fields findByThriftId(int fieldId) {
        switch(fieldId) {
          case 1: // AUTHZ_TOKEN
            return AUTHZ_TOKEN;
          case 2: // AIRAVATA_EXPERIMENT_ID
            return AIRAVATA_EXPERIMENT_ID;
          default:
            return null;
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, throwing an exception
       * if it is not found.
       */
      public static _Fields findByThriftIdOrThrow(int fieldId) {
        _Fields fields = findByThriftId(fieldId);
        if (fields == null) throw new IllegalArgumentException("Field " + fieldId + " doesn't exist!");
        return fields;
      }

      /**
       * Find the _Fields constant that matches name, or null if its not found.
       */
      public static _Fields findByName(String name) {
        return byName.get(name);
      }

      private final short _thriftId;
      private final String _fieldName;

      _Fields(short thriftId, String fieldName) {
        _thriftId = thriftId;
        _fieldName = fieldName;
      }

      public short getThriftFieldId() {
        return _thriftId;
      }

      public String getFieldName() {
        return _fieldName;
      }
    }

    // isset id assignments
    public static final Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
    static {
      Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new EnumMap<_Fields, org.apache.thrift.meta_data.FieldMetaData>(_Fields.class);
      tmpMap.put(_Fields.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_EXPERIMENT_ID, new org.apache.thrift.meta_data.FieldMetaData("airavataExperimentId", org.apache.thrift.TFieldRequirementType.REQUIRED, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING)));
      metaDataMap = Collections.unmodifiableMap(tmpMap);
      org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(getJobDetails_args.class, metaDataMap);
    }

    public getJobDetails_args() {
    }

    public getJobDetails_args(
      org.apache.airavata.model.security.AuthzToken authzToken,
      String airavataExperimentId)
    {
      this();
      this.authzToken = authzToken;
      this.airavataExperimentId = airavataExperimentId;
    }

    /**
     * Performs a deep copy on <i>other</i>.
     */
    public getJobDetails_args(getJobDetails_args other) {
      if (other.isSetAuthzToken()) {
        this.authzToken = new org.apache.airavata.model.security.AuthzToken(other.authzToken);
      }
      if (other.isSetAiravataExperimentId()) {
        this.airavataExperimentId = other.airavataExperimentId;
      }
    }

    public getJobDetails_args deepCopy() {
      return new getJobDetails_args(this);
    }

    @Override
    public void clear() {
      this.authzToken = null;
      this.airavataExperimentId = null;
    }

    public org.apache.airavata.model.security.AuthzToken getAuthzToken() {
      return this.authzToken;
    }

    public getJobDetails_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 String getAiravataExperimentId() {
      return this.airavataExperimentId;
    }

    public getJobDetails_args setAiravataExperimentId(String airavataExperimentId) {
      this.airavataExperimentId = airavataExperimentId;
      return this;
    }

    public void unsetAiravataExperimentId() {
      this.airavataExperimentId = null;
    }

    /** Returns true if field airavataExperimentId is set (has been assigned a value) and false otherwise */
    public boolean isSetAiravataExperimentId() {
      return this.airavataExperimentId != null;
    }

    public void setAiravataExperimentIdIsSet(boolean value) {
      if (!value) {
        this.airavataExperimentId = null;
      }
    }

    public void setFieldValue(_Fields field, Object value) {
      switch (field) {
      case AUTHZ_TOKEN:
        if (value == null) {
          unsetAuthzToken();
        } else {
          setAuthzToken((org.apache.airavata.model.security.AuthzToken)value);
        }
        break;

      case AIRAVATA_EXPERIMENT_ID:
        if (value == null) {
          unsetAiravataExperimentId();
        } else {
          setAiravataExperimentId((String)value);
        }
        break;

      }
    }

    public Object getFieldValue(_Fields field) {
      switch (field) {
      case AUTHZ_TOKEN:
        return getAuthzToken();

      case AIRAVATA_EXPERIMENT_ID:
        return getAiravataExperimentId();

      }
      throw new IllegalStateException();
    }

    /** Returns true if field corresponding to fieldID is set (has been assigned a value) and false otherwise */
    public boolean isSet(_Fields field) {
      if (field == null) {
        throw new IllegalArgumentException();
      }

      switch (field) {
      case AUTHZ_TOKEN:
        return isSetAuthzToken();
      case AIRAVATA_EXPERIMENT_ID:
        return isSetAiravataExperimentId();
      }
      throw new IllegalStateException();
    }

    @Override
    public boolean equals(Object that) {
      if (that == null)
        return false;
      if (that instanceof getJobDetails_args)
        return this.equals((getJobDetails_args)that);
      return false;
    }

    public boolean equals(getJobDetails_args that) {
      if (that == null)
        return false;

      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_airavataExperimentId = true && this.isSetAiravataExperimentId();
      boolean that_present_airavataExperimentId = true && that.isSetAiravataExperimentId();
      if (this_present_airavataExperimentId || that_present_airavataExperimentId) {
        if (!(this_present_airavataExperimentId && that_present_airavataExperimentId))
          return false;
        if (!this.airavataExperimentId.equals(that.airavataExperimentId))
          return false;
      }

      return true;
    }

    @Override
    public int hashCode() {
      List<Object> list = new ArrayList<Object>();

      boolean present_authzToken = true && (isSetAuthzToken());
      list.add(present_authzToken);
      if (present_authzToken)
        list.add(authzToken);

      boolean present_airavataExperimentId = true && (isSetAiravataExperimentId());
      list.add(present_airavataExperimentId);
      if (present_airavataExperimentId)
        list.add(airavataExperimentId);

      return list.hashCode();
    }

    @Override
    public int compareTo(getJobDetails_args other) {
      if (!getClass().equals(other.getClass())) {
        return getClass().getName().compareTo(other.getClass().getName());
      }

      int lastComparison = 0;

      lastComparison = 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 = Boolean.valueOf(isSetAiravataExperimentId()).compareTo(other.isSetAiravataExperimentId());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetAiravataExperimentId()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.airavataExperimentId, other.airavataExperimentId);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      return 0;
    }

    public _Fields fieldForId(int fieldId) {
      return _Fields.findByThriftId(fieldId);
    }

    public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
      schemes.get(iprot.getScheme()).getScheme().read(iprot, this);
    }

    public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException {
      schemes.get(oprot.getScheme()).getScheme().write(oprot, this);
    }

    @Override
    public String toString() {
      StringBuilder sb = new StringBuilder("getJobDetails_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("airavataExperimentId:");
      if (this.airavataExperimentId == null) {
        sb.append("null");
      } else {
        sb.append(this.airavataExperimentId);
      }
      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 (airavataExperimentId == null) {
        throw new org.apache.thrift.protocol.TProtocolException("Required field 'airavataExperimentId' 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, 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 getJobDetails_argsStandardSchemeFactory implements SchemeFactory {
      public getJobDetails_argsStandardScheme getScheme() {
        return new getJobDetails_argsStandardScheme();
      }
    }

    private static class getJobDetails_argsStandardScheme extends StandardScheme<getJobDetails_args> {

      public void read(org.apache.thrift.protocol.TProtocol iprot, getJobDetails_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_EXPERIMENT_ID
              if (schemeField.type == org.apache.thrift.protocol.TType.STRING) {
                struct.airavataExperimentId = iprot.readString();
                struct.setAiravataExperimentIdIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            default:
              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
          }
          iprot.readFieldEnd();
        }
        iprot.readStructEnd();

        // check for required fields of primitive type, which can't be checked in the validate method
        struct.validate();
      }

      public void write(org.apache.thrift.protocol.TProtocol oprot, getJobDetails_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.airavataExperimentId != null) {
          oprot.writeFieldBegin(AIRAVATA_EXPERIMENT_ID_FIELD_DESC);
          oprot.writeString(struct.airavataExperimentId);
          oprot.writeFieldEnd();
        }
        oprot.writeFieldStop();
        oprot.writeStructEnd();
      }

    }

    private static class getJobDetails_argsTupleSchemeFactory implements SchemeFactory {
      public getJobDetails_argsTupleScheme getScheme() {
        return new getJobDetails_argsTupleScheme();
      }
    }

    private static class getJobDetails_argsTupleScheme extends TupleScheme<getJobDetails_args> {

      @Override
      public void write(org.apache.thrift.protocol.TProtocol prot, getJobDetails_args struct) throws org.apache.thrift.TException {
        TTupleProtocol oprot = (TTupleProtocol) prot;
        struct.authzToken.write(oprot);
        oprot.writeString(struct.airavataExperimentId);
      }

      @Override
      public void read(org.apache.thrift.protocol.TProtocol prot, getJobDetails_args struct) throws org.apache.thrift.TException {
        TTupleProtocol iprot = (TTupleProtocol) prot;
        struct.authzToken = new org.apache.airavata.model.security.AuthzToken();
        struct.authzToken.read(iprot);
        struct.setAuthzTokenIsSet(true);
        struct.airavataExperimentId = iprot.readString();
        struct.setAiravataExperimentIdIsSet(true);
      }
    }

  }

  public static class getJobDetails_result implements org.apache.thrift.TBase<getJobDetails_result, getJobDetails_result._Fields>, java.io.Serializable, Cloneable, Comparable<getJobDetails_result>   {
    private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("getJobDetails_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 IRE_FIELD_DESC = new org.apache.thrift.protocol.TField("ire", org.apache.thrift.protocol.TType.STRUCT, (short)1);
    private static final org.apache.thrift.protocol.TField ENF_FIELD_DESC = new org.apache.thrift.protocol.TField("enf", org.apache.thrift.protocol.TType.STRUCT, (short)2);
    private static final org.apache.thrift.protocol.TField ACE_FIELD_DESC = new org.apache.thrift.protocol.TField("ace", org.apache.thrift.protocol.TType.STRUCT, (short)3);
    private static final org.apache.thrift.protocol.TField ASE_FIELD_DESC = new org.apache.thrift.protocol.TField("ase", org.apache.thrift.protocol.TType.STRUCT, (short)4);
    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)5);

    private static final Map<Class<? extends IScheme>, SchemeFactory> schemes = new HashMap<Class<? extends IScheme>, SchemeFactory>();
    static {
      schemes.put(StandardScheme.class, new getJobDetails_resultStandardSchemeFactory());
      schemes.put(TupleScheme.class, new getJobDetails_resultTupleSchemeFactory());
    }

    public List<org.apache.airavata.model.job.JobModel> success; // required
    public org.apache.airavata.model.error.InvalidRequestException ire; // required
    public org.apache.airavata.model.error.ExperimentNotFoundException enf; // required
    public org.apache.airavata.model.error.AiravataClientException ace; // required
    public org.apache.airavata.model.error.AiravataSystemException ase; // 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"),
      IRE((short)1, "ire"),
      ENF((short)2, "enf"),
      ACE((short)3, "ace"),
      ASE((short)4, "ase"),
      AE((short)5, "ae");

      private static final Map<String, _Fields> byName = new HashMap<String, _Fields>();

      static {
        for (_Fields field : EnumSet.allOf(_Fields.class)) {
          byName.put(field.getFieldName(), field);
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, or null if its not found.
       */
      public static _Fields findByThriftId(int fieldId) {
        switch(fieldId) {
          case 0: // SUCCESS
            return SUCCESS;
          case 1: // IRE
            return IRE;
          case 2: // ENF
            return ENF;
          case 3: // ACE
            return ACE;
          case 4: // ASE
            return ASE;
          case 5: // 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 IllegalArgumentException("Field " + fieldId + " doesn't exist!");
        return fields;
      }

      /**
       * Find the _Fields constant that matches name, or null if its not found.
       */
      public static _Fields findByName(String name) {
        return byName.get(name);
      }

      private final short _thriftId;
      private final String _fieldName;

      _Fields(short thriftId, String fieldName) {
        _thriftId = thriftId;
        _fieldName = fieldName;
      }

      public short getThriftFieldId() {
        return _thriftId;
      }

      public String getFieldName() {
        return _fieldName;
      }
    }

    // isset id assignments
    public static final Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
    static {
      Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new EnumMap<_Fields, org.apache.thrift.meta_data.FieldMetaData>(_Fields.class);
      tmpMap.put(_Fields.SUCCESS, new org.apache.thrift.meta_data.FieldMetaData("success", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.ListMetaData(org.apache.thrift.protocol.TType.LIST, 
              new org.apache.thrift.meta_data.StructMetaData(org.apache.thrift.protocol.TType.STRUCT, org.apache.airavata.model.job.JobModel.class))));
      tmpMap.put(_Fields.IRE, new org.apache.thrift.meta_data.FieldMetaData("ire", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRUCT)));
      tmpMap.put(_Fields.ENF, new org.apache.thrift.meta_data.FieldMetaData("enf", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRUCT)));
      tmpMap.put(_Fields.ACE, new org.apache.thrift.meta_data.FieldMetaData("ace", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRUCT)));
      tmpMap.put(_Fields.ASE, new org.apache.thrift.meta_data.FieldMetaData("ase", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRUCT)));
      tmpMap.put(_Fields.AE, new org.apache.thrift.meta_data.FieldMetaData("ae", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRUCT)));
      metaDataMap = Collections.unmodifiableMap(tmpMap);
      org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(getJobDetails_result.class, metaDataMap);
    }

    public getJobDetails_result() {
    }

    public getJobDetails_result(
      List<org.apache.airavata.model.job.JobModel> success,
      org.apache.airavata.model.error.InvalidRequestException ire,
      org.apache.airavata.model.error.ExperimentNotFoundException enf,
      org.apache.airavata.model.error.AiravataClientException ace,
      org.apache.airavata.model.error.AiravataSystemException ase,
      org.apache.airavata.model.error.AuthorizationException ae)
    {
      this();
      this.success = success;
      this.ire = ire;
      this.enf = enf;
      this.ace = ace;
      this.ase = ase;
      this.ae = ae;
    }

    /**
     * Performs a deep copy on <i>other</i>.
     */
    public getJobDetails_result(getJobDetails_result other) {
      if (other.isSetSuccess()) {
        List<org.apache.airavata.model.job.JobModel> __this__success = new ArrayList<org.apache.airavata.model.job.JobModel>(other.success.size());
        for (org.apache.airavata.model.job.JobModel other_element : other.success) {
          __this__success.add(new org.apache.airavata.model.job.JobModel(other_element));
        }
        this.success = __this__success;
      }
      if (other.isSetIre()) {
        this.ire = new org.apache.airavata.model.error.InvalidRequestException(other.ire);
      }
      if (other.isSetEnf()) {
        this.enf = new org.apache.airavata.model.error.ExperimentNotFoundException(other.enf);
      }
      if (other.isSetAce()) {
        this.ace = new org.apache.airavata.model.error.AiravataClientException(other.ace);
      }
      if (other.isSetAse()) {
        this.ase = new org.apache.airavata.model.error.AiravataSystemException(other.ase);
      }
      if (other.isSetAe()) {
        this.ae = new org.apache.airavata.model.error.AuthorizationException(other.ae);
      }
    }

    public getJobDetails_result deepCopy() {
      return new getJobDetails_result(this);
    }

    @Override
    public void clear() {
      this.success = null;
      this.ire = null;
      this.enf = null;
      this.ace = null;
      this.ase = null;
      this.ae = null;
    }

    public int getSuccessSize() {
      return (this.success == null) ? 0 : this.success.size();
    }

    public java.util.Iterator<org.apache.airavata.model.job.JobModel> getSuccessIterator() {
      return (this.success == null) ? null : this.success.iterator();
    }

    public void addToSuccess(org.apache.airavata.model.job.JobModel elem) {
      if (this.success == null) {
        this.success = new ArrayList<org.apache.airavata.model.job.JobModel>();
      }
      this.success.add(elem);
    }

    public List<org.apache.airavata.model.job.JobModel> getSuccess() {
      return this.success;
    }

    public getJobDetails_result setSuccess(List<org.apache.airavata.model.job.JobModel> 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.model.error.InvalidRequestException getIre() {
      return this.ire;
    }

    public getJobDetails_result setIre(org.apache.airavata.model.error.InvalidRequestException ire) {
      this.ire = ire;
      return this;
    }

    public void unsetIre() {
      this.ire = null;
    }

    /** Returns true if field ire is set (has been assigned a value) and false otherwise */
    public boolean isSetIre() {
      return this.ire != null;
    }

    public void setIreIsSet(boolean value) {
      if (!value) {
        this.ire = null;
      }
    }

    public org.apache.airavata.model.error.ExperimentNotFoundException getEnf() {
      return this.enf;
    }

    public getJobDetails_result setEnf(org.apache.airavata.model.error.ExperimentNotFoundException enf) {
      this.enf = enf;
      return this;
    }

    public void unsetEnf() {
      this.enf = null;
    }

    /** Returns true if field enf is set (has been assigned a value) and false otherwise */
    public boolean isSetEnf() {
      return this.enf != null;
    }

    public void setEnfIsSet(boolean value) {
      if (!value) {
        this.enf = null;
      }
    }

    public org.apache.airavata.model.error.AiravataClientException getAce() {
      return this.ace;
    }

    public getJobDetails_result setAce(org.apache.airavata.model.error.AiravataClientException ace) {
      this.ace = ace;
      return this;
    }

    public void unsetAce() {
      this.ace = null;
    }

    /** Returns true if field ace is set (has been assigned a value) and false otherwise */
    public boolean isSetAce() {
      return this.ace != null;
    }

    public void setAceIsSet(boolean value) {
      if (!value) {
        this.ace = null;
      }
    }

    public org.apache.airavata.model.error.AiravataSystemException getAse() {
      return this.ase;
    }

    public getJobDetails_result setAse(org.apache.airavata.model.error.AiravataSystemException ase) {
      this.ase = ase;
      return this;
    }

    public void unsetAse() {
      this.ase = null;
    }

    /** Returns true if field ase is set (has been assigned a value) and false otherwise */
    public boolean isSetAse() {
      return this.ase != null;
    }

    public void setAseIsSet(boolean value) {
      if (!value) {
        this.ase = null;
      }
    }

    public org.apache.airavata.model.error.AuthorizationException getAe() {
      return this.ae;
    }

    public getJobDetails_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, Object value) {
      switch (field) {
      case SUCCESS:
        if (value == null) {
          unsetSuccess();
        } else {
          setSuccess((List<org.apache.airavata.model.job.JobModel>)value);
        }
        break;

      case IRE:
        if (value == null) {
          unsetIre();
        } else {
          setIre((org.apache.airavata.model.error.InvalidRequestException)value);
        }
        break;

      case ENF:
        if (value == null) {
          unsetEnf();
        } else {
          setEnf((org.apache.airavata.model.error.ExperimentNotFoundException)value);
        }
        break;

      case ACE:
        if (value == null) {
          unsetAce();
        } else {
          setAce((org.apache.airavata.model.error.AiravataClientException)value);
        }
        break;

      case ASE:
        if (value == null) {
          unsetAse();
        } else {
          setAse((org.apache.airavata.model.error.AiravataSystemException)value);
        }
        break;

      case AE:
        if (value == null) {
          unsetAe();
        } else {
          setAe((org.apache.airavata.model.error.AuthorizationException)value);
        }
        break;

      }
    }

    public Object getFieldValue(_Fields field) {
      switch (field) {
      case SUCCESS:
        return getSuccess();

      case IRE:
        return getIre();

      case ENF:
        return getEnf();

      case ACE:
        return getAce();

      case ASE:
        return getAse();

      case AE:
        return getAe();

      }
      throw new IllegalStateException();
    }

    /** Returns true if field corresponding to fieldID is set (has been assigned a value) and false otherwise */
    public boolean isSet(_Fields field) {
      if (field == null) {
        throw new IllegalArgumentException();
      }

      switch (field) {
      case SUCCESS:
        return isSetSuccess();
      case IRE:
        return isSetIre();
      case ENF:
        return isSetEnf();
      case ACE:
        return isSetAce();
      case ASE:
        return isSetAse();
      case AE:
        return isSetAe();
      }
      throw new IllegalStateException();
    }

    @Override
    public boolean equals(Object that) {
      if (that == null)
        return false;
      if (that instanceof getJobDetails_result)
        return this.equals((getJobDetails_result)that);
      return false;
    }

    public boolean equals(getJobDetails_result that) {
      if (that == null)
        return false;

      boolean this_present_success = true && this.isSetSuccess();
      boolean that_present_success = true && that.isSetSuccess();
      if (this_present_success || that_present_success) {
        if (!(this_present_success && that_present_success))
          return false;
        if (!this.success.equals(that.success))
          return false;
      }

      boolean this_present_ire = true && this.isSetIre();
      boolean that_present_ire = true && that.isSetIre();
      if (this_present_ire || that_present_ire) {
        if (!(this_present_ire && that_present_ire))
          return false;
        if (!this.ire.equals(that.ire))
          return false;
      }

      boolean this_present_enf = true && this.isSetEnf();
      boolean that_present_enf = true && that.isSetEnf();
      if (this_present_enf || that_present_enf) {
        if (!(this_present_enf && that_present_enf))
          return false;
        if (!this.enf.equals(that.enf))
          return false;
      }

      boolean this_present_ace = true && this.isSetAce();
      boolean that_present_ace = true && that.isSetAce();
      if (this_present_ace || that_present_ace) {
        if (!(this_present_ace && that_present_ace))
          return false;
        if (!this.ace.equals(that.ace))
          return false;
      }

      boolean this_present_ase = true && this.isSetAse();
      boolean that_present_ase = true && that.isSetAse();
      if (this_present_ase || that_present_ase) {
        if (!(this_present_ase && that_present_ase))
          return false;
        if (!this.ase.equals(that.ase))
          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() {
      List<Object> list = new ArrayList<Object>();

      boolean present_success = true && (isSetSuccess());
      list.add(present_success);
      if (present_success)
        list.add(success);

      boolean present_ire = true && (isSetIre());
      list.add(present_ire);
      if (present_ire)
        list.add(ire);

      boolean present_enf = true && (isSetEnf());
      list.add(present_enf);
      if (present_enf)
        list.add(enf);

      boolean present_ace = true && (isSetAce());
      list.add(present_ace);
      if (present_ace)
        list.add(ace);

      boolean present_ase = true && (isSetAse());
      list.add(present_ase);
      if (present_ase)
        list.add(ase);

      boolean present_ae = true && (isSetAe());
      list.add(present_ae);
      if (present_ae)
        list.add(ae);

      return list.hashCode();
    }

    @Override
    public int compareTo(getJobDetails_result other) {
      if (!getClass().equals(other.getClass())) {
        return getClass().getName().compareTo(other.getClass().getName());
      }

      int lastComparison = 0;

      lastComparison = Boolean.valueOf(isSetSuccess()).compareTo(other.isSetSuccess());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetSuccess()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.success, other.success);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = Boolean.valueOf(isSetIre()).compareTo(other.isSetIre());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetIre()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.ire, other.ire);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = Boolean.valueOf(isSetEnf()).compareTo(other.isSetEnf());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetEnf()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.enf, other.enf);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = Boolean.valueOf(isSetAce()).compareTo(other.isSetAce());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetAce()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.ace, other.ace);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = Boolean.valueOf(isSetAse()).compareTo(other.isSetAse());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetAse()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.ase, other.ase);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = 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 {
      schemes.get(iprot.getScheme()).getScheme().read(iprot, this);
    }

    public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException {
      schemes.get(oprot.getScheme()).getScheme().write(oprot, this);
      }

    @Override
    public String toString() {
      StringBuilder sb = new StringBuilder("getJobDetails_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("ire:");
      if (this.ire == null) {
        sb.append("null");
      } else {
        sb.append(this.ire);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("enf:");
      if (this.enf == null) {
        sb.append("null");
      } else {
        sb.append(this.enf);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("ace:");
      if (this.ace == null) {
        sb.append("null");
      } else {
        sb.append(this.ace);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("ase:");
      if (this.ase == null) {
        sb.append("null");
      } else {
        sb.append(this.ase);
      }
      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, 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 getJobDetails_resultStandardSchemeFactory implements SchemeFactory {
      public getJobDetails_resultStandardScheme getScheme() {
        return new getJobDetails_resultStandardScheme();
      }
    }

    private static class getJobDetails_resultStandardScheme extends StandardScheme<getJobDetails_result> {

      public void read(org.apache.thrift.protocol.TProtocol iprot, getJobDetails_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 _list142 = iprot.readListBegin();
                  struct.success = new ArrayList<org.apache.airavata.model.job.JobModel>(_list142.size);
                  org.apache.airavata.model.job.JobModel _elem143;
                  for (int _i144 = 0; _i144 < _list142.size; ++_i144)
                  {
                    _elem143 = new org.apache.airavata.model.job.JobModel();
                    _elem143.read(iprot);
                    struct.success.add(_elem143);
                  }
                  iprot.readListEnd();
                }
                struct.setSuccessIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 1: // IRE
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.ire = new org.apache.airavata.model.error.InvalidRequestException();
                struct.ire.read(iprot);
                struct.setIreIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 2: // ENF
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.enf = new org.apache.airavata.model.error.ExperimentNotFoundException();
                struct.enf.read(iprot);
                struct.setEnfIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 3: // ACE
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.ace = new org.apache.airavata.model.error.AiravataClientException();
                struct.ace.read(iprot);
                struct.setAceIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 4: // ASE
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.ase = new org.apache.airavata.model.error.AiravataSystemException();
                struct.ase.read(iprot);
                struct.setAseIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 5: // 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, getJobDetails_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.job.JobModel _iter145 : struct.success)
            {
              _iter145.write(oprot);
            }
            oprot.writeListEnd();
          }
          oprot.writeFieldEnd();
        }
        if (struct.ire != null) {
          oprot.writeFieldBegin(IRE_FIELD_DESC);
          struct.ire.write(oprot);
          oprot.writeFieldEnd();
        }
        if (struct.enf != null) {
          oprot.writeFieldBegin(ENF_FIELD_DESC);
          struct.enf.write(oprot);
          oprot.writeFieldEnd();
        }
        if (struct.ace != null) {
          oprot.writeFieldBegin(ACE_FIELD_DESC);
          struct.ace.write(oprot);
          oprot.writeFieldEnd();
        }
        if (struct.ase != null) {
          oprot.writeFieldBegin(ASE_FIELD_DESC);
          struct.ase.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 getJobDetails_resultTupleSchemeFactory implements SchemeFactory {
      public getJobDetails_resultTupleScheme getScheme() {
        return new getJobDetails_resultTupleScheme();
      }
    }

    private static class getJobDetails_resultTupleScheme extends TupleScheme<getJobDetails_result> {

      @Override
      public void write(org.apache.thrift.protocol.TProtocol prot, getJobDetails_result struct) throws org.apache.thrift.TException {
        TTupleProtocol oprot = (TTupleProtocol) prot;
        BitSet optionals = new BitSet();
        if (struct.isSetSuccess()) {
          optionals.set(0);
        }
        if (struct.isSetIre()) {
          optionals.set(1);
        }
        if (struct.isSetEnf()) {
          optionals.set(2);
        }
        if (struct.isSetAce()) {
          optionals.set(3);
        }
        if (struct.isSetAse()) {
          optionals.set(4);
        }
        if (struct.isSetAe()) {
          optionals.set(5);
        }
        oprot.writeBitSet(optionals, 6);
        if (struct.isSetSuccess()) {
          {
            oprot.writeI32(struct.success.size());
            for (org.apache.airavata.model.job.JobModel _iter146 : struct.success)
            {
              _iter146.write(oprot);
            }
          }
        }
        if (struct.isSetIre()) {
          struct.ire.write(oprot);
        }
        if (struct.isSetEnf()) {
          struct.enf.write(oprot);
        }
        if (struct.isSetAce()) {
          struct.ace.write(oprot);
        }
        if (struct.isSetAse()) {
          struct.ase.write(oprot);
        }
        if (struct.isSetAe()) {
          struct.ae.write(oprot);
        }
      }

      @Override
      public void read(org.apache.thrift.protocol.TProtocol prot, getJobDetails_result struct) throws org.apache.thrift.TException {
        TTupleProtocol iprot = (TTupleProtocol) prot;
        BitSet incoming = iprot.readBitSet(6);
        if (incoming.get(0)) {
          {
            org.apache.thrift.protocol.TList _list147 = new org.apache.thrift.protocol.TList(org.apache.thrift.protocol.TType.STRUCT, iprot.readI32());
            struct.success = new ArrayList<org.apache.airavata.model.job.JobModel>(_list147.size);
            org.apache.airavata.model.job.JobModel _elem148;
            for (int _i149 = 0; _i149 < _list147.size; ++_i149)
            {
              _elem148 = new org.apache.airavata.model.job.JobModel();
              _elem148.read(iprot);
              struct.success.add(_elem148);
            }
          }
          struct.setSuccessIsSet(true);
        }
        if (incoming.get(1)) {
          struct.ire = new org.apache.airavata.model.error.InvalidRequestException();
          struct.ire.read(iprot);
          struct.setIreIsSet(true);
        }
        if (incoming.get(2)) {
          struct.enf = new org.apache.airavata.model.error.ExperimentNotFoundException();
          struct.enf.read(iprot);
          struct.setEnfIsSet(true);
        }
        if (incoming.get(3)) {
          struct.ace = new org.apache.airavata.model.error.AiravataClientException();
          struct.ace.read(iprot);
          struct.setAceIsSet(true);
        }
        if (incoming.get(4)) {
          struct.ase = new org.apache.airavata.model.error.AiravataSystemException();
          struct.ase.read(iprot);
          struct.setAseIsSet(true);
        }
        if (incoming.get(5)) {
          struct.ae = new org.apache.airavata.model.error.AuthorizationException();
          struct.ae.read(iprot);
          struct.setAeIsSet(true);
        }
      }
    }

  }

  public static class cloneExperiment_args implements org.apache.thrift.TBase<cloneExperiment_args, cloneExperiment_args._Fields>, java.io.Serializable, Cloneable, Comparable<cloneExperiment_args>   {
    private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("cloneExperiment_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 EXISTING_EXPERIMENT_ID_FIELD_DESC = new org.apache.thrift.protocol.TField("existingExperimentID", org.apache.thrift.protocol.TType.STRING, (short)2);
    private static final org.apache.thrift.protocol.TField NEW_EXPERIMENT_NAME_FIELD_DESC = new org.apache.thrift.protocol.TField("newExperimentName", org.apache.thrift.protocol.TType.STRING, (short)3);

    private static final Map<Class<? extends IScheme>, SchemeFactory> schemes = new HashMap<Class<? extends IScheme>, SchemeFactory>();
    static {
      schemes.put(StandardScheme.class, new cloneExperiment_argsStandardSchemeFactory());
      schemes.put(TupleScheme.class, new cloneExperiment_argsTupleSchemeFactory());
    }

    public org.apache.airavata.model.security.AuthzToken authzToken; // required
    public String existingExperimentID; // required
    public String newExperimentName; // required

    /** 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"),
      EXISTING_EXPERIMENT_ID((short)2, "existingExperimentID"),
      NEW_EXPERIMENT_NAME((short)3, "newExperimentName");

      private static final Map<String, _Fields> byName = new HashMap<String, _Fields>();

      static {
        for (_Fields field : EnumSet.allOf(_Fields.class)) {
          byName.put(field.getFieldName(), field);
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, or null if its not found.
       */
      public static _Fields findByThriftId(int fieldId) {
        switch(fieldId) {
          case 1: // AUTHZ_TOKEN
            return AUTHZ_TOKEN;
          case 2: // EXISTING_EXPERIMENT_ID
            return EXISTING_EXPERIMENT_ID;
          case 3: // NEW_EXPERIMENT_NAME
            return NEW_EXPERIMENT_NAME;
          default:
            return null;
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, throwing an exception
       * if it is not found.
       */
      public static _Fields findByThriftIdOrThrow(int fieldId) {
        _Fields fields = findByThriftId(fieldId);
        if (fields == null) throw new IllegalArgumentException("Field " + fieldId + " doesn't exist!");
        return fields;
      }

      /**
       * Find the _Fields constant that matches name, or null if its not found.
       */
      public static _Fields findByName(String name) {
        return byName.get(name);
      }

      private final short _thriftId;
      private final String _fieldName;

      _Fields(short thriftId, String fieldName) {
        _thriftId = thriftId;
        _fieldName = fieldName;
      }

      public short getThriftFieldId() {
        return _thriftId;
      }

      public String getFieldName() {
        return _fieldName;
      }
    }

    // isset id assignments
    public static final Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
    static {
      Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new EnumMap<_Fields, org.apache.thrift.meta_data.FieldMetaData>(_Fields.class);
      tmpMap.put(_Fields.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.EXISTING_EXPERIMENT_ID, new org.apache.thrift.meta_data.FieldMetaData("existingExperimentID", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING)));
      tmpMap.put(_Fields.NEW_EXPERIMENT_NAME, new org.apache.thrift.meta_data.FieldMetaData("newExperimentName", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING)));
      metaDataMap = Collections.unmodifiableMap(tmpMap);
      org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(cloneExperiment_args.class, metaDataMap);
    }

    public cloneExperiment_args() {
    }

    public cloneExperiment_args(
      org.apache.airavata.model.security.AuthzToken authzToken,
      String existingExperimentID,
      String newExperimentName)
    {
      this();
      this.authzToken = authzToken;
      this.existingExperimentID = existingExperimentID;
      this.newExperimentName = newExperimentName;
    }

    /**
     * Performs a deep copy on <i>other</i>.
     */
    public cloneExperiment_args(cloneExperiment_args other) {
      if (other.isSetAuthzToken()) {
        this.authzToken = new org.apache.airavata.model.security.AuthzToken(other.authzToken);
      }
      if (other.isSetExistingExperimentID()) {
        this.existingExperimentID = other.existingExperimentID;
      }
      if (other.isSetNewExperimentName()) {
        this.newExperimentName = other.newExperimentName;
      }
    }

    public cloneExperiment_args deepCopy() {
      return new cloneExperiment_args(this);
    }

    @Override
    public void clear() {
      this.authzToken = null;
      this.existingExperimentID = null;
      this.newExperimentName = null;
    }

    public org.apache.airavata.model.security.AuthzToken getAuthzToken() {
      return this.authzToken;
    }

    public cloneExperiment_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 String getExistingExperimentID() {
      return this.existingExperimentID;
    }

    public cloneExperiment_args setExistingExperimentID(String existingExperimentID) {
      this.existingExperimentID = existingExperimentID;
      return this;
    }

    public void unsetExistingExperimentID() {
      this.existingExperimentID = null;
    }

    /** Returns true if field existingExperimentID is set (has been assigned a value) and false otherwise */
    public boolean isSetExistingExperimentID() {
      return this.existingExperimentID != null;
    }

    public void setExistingExperimentIDIsSet(boolean value) {
      if (!value) {
        this.existingExperimentID = null;
      }
    }

    public String getNewExperimentName() {
      return this.newExperimentName;
    }

    public cloneExperiment_args setNewExperimentName(String newExperimentName) {
      this.newExperimentName = newExperimentName;
      return this;
    }

    public void unsetNewExperimentName() {
      this.newExperimentName = null;
    }

    /** Returns true if field newExperimentName is set (has been assigned a value) and false otherwise */
    public boolean isSetNewExperimentName() {
      return this.newExperimentName != null;
    }

    public void setNewExperimentNameIsSet(boolean value) {
      if (!value) {
        this.newExperimentName = null;
      }
    }

    public void setFieldValue(_Fields field, Object value) {
      switch (field) {
      case AUTHZ_TOKEN:
        if (value == null) {
          unsetAuthzToken();
        } else {
          setAuthzToken((org.apache.airavata.model.security.AuthzToken)value);
        }
        break;

      case EXISTING_EXPERIMENT_ID:
        if (value == null) {
          unsetExistingExperimentID();
        } else {
          setExistingExperimentID((String)value);
        }
        break;

      case NEW_EXPERIMENT_NAME:
        if (value == null) {
          unsetNewExperimentName();
        } else {
          setNewExperimentName((String)value);
        }
        break;

      }
    }

    public Object getFieldValue(_Fields field) {
      switch (field) {
      case AUTHZ_TOKEN:
        return getAuthzToken();

      case EXISTING_EXPERIMENT_ID:
        return getExistingExperimentID();

      case NEW_EXPERIMENT_NAME:
        return getNewExperimentName();

      }
      throw new IllegalStateException();
    }

    /** Returns true if field corresponding to fieldID is set (has been assigned a value) and false otherwise */
    public boolean isSet(_Fields field) {
      if (field == null) {
        throw new IllegalArgumentException();
      }

      switch (field) {
      case AUTHZ_TOKEN:
        return isSetAuthzToken();
      case EXISTING_EXPERIMENT_ID:
        return isSetExistingExperimentID();
      case NEW_EXPERIMENT_NAME:
        return isSetNewExperimentName();
      }
      throw new IllegalStateException();
    }

    @Override
    public boolean equals(Object that) {
      if (that == null)
        return false;
      if (that instanceof cloneExperiment_args)
        return this.equals((cloneExperiment_args)that);
      return false;
    }

    public boolean equals(cloneExperiment_args that) {
      if (that == null)
        return false;

      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_existingExperimentID = true && this.isSetExistingExperimentID();
      boolean that_present_existingExperimentID = true && that.isSetExistingExperimentID();
      if (this_present_existingExperimentID || that_present_existingExperimentID) {
        if (!(this_present_existingExperimentID && that_present_existingExperimentID))
          return false;
        if (!this.existingExperimentID.equals(that.existingExperimentID))
          return false;
      }

      boolean this_present_newExperimentName = true && this.isSetNewExperimentName();
      boolean that_present_newExperimentName = true && that.isSetNewExperimentName();
      if (this_present_newExperimentName || that_present_newExperimentName) {
        if (!(this_present_newExperimentName && that_present_newExperimentName))
          return false;
        if (!this.newExperimentName.equals(that.newExperimentName))
          return false;
      }

      return true;
    }

    @Override
    public int hashCode() {
      List<Object> list = new ArrayList<Object>();

      boolean present_authzToken = true && (isSetAuthzToken());
      list.add(present_authzToken);
      if (present_authzToken)
        list.add(authzToken);

      boolean present_existingExperimentID = true && (isSetExistingExperimentID());
      list.add(present_existingExperimentID);
      if (present_existingExperimentID)
        list.add(existingExperimentID);

      boolean present_newExperimentName = true && (isSetNewExperimentName());
      list.add(present_newExperimentName);
      if (present_newExperimentName)
        list.add(newExperimentName);

      return list.hashCode();
    }

    @Override
    public int compareTo(cloneExperiment_args other) {
      if (!getClass().equals(other.getClass())) {
        return getClass().getName().compareTo(other.getClass().getName());
      }

      int lastComparison = 0;

      lastComparison = 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 = Boolean.valueOf(isSetExistingExperimentID()).compareTo(other.isSetExistingExperimentID());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetExistingExperimentID()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.existingExperimentID, other.existingExperimentID);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = Boolean.valueOf(isSetNewExperimentName()).compareTo(other.isSetNewExperimentName());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetNewExperimentName()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.newExperimentName, other.newExperimentName);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      return 0;
    }

    public _Fields fieldForId(int fieldId) {
      return _Fields.findByThriftId(fieldId);
    }

    public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
      schemes.get(iprot.getScheme()).getScheme().read(iprot, this);
    }

    public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException {
      schemes.get(oprot.getScheme()).getScheme().write(oprot, this);
    }

    @Override
    public String toString() {
      StringBuilder sb = new StringBuilder("cloneExperiment_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("existingExperimentID:");
      if (this.existingExperimentID == null) {
        sb.append("null");
      } else {
        sb.append(this.existingExperimentID);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("newExperimentName:");
      if (this.newExperimentName == null) {
        sb.append("null");
      } else {
        sb.append(this.newExperimentName);
      }
      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, 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 cloneExperiment_argsStandardSchemeFactory implements SchemeFactory {
      public cloneExperiment_argsStandardScheme getScheme() {
        return new cloneExperiment_argsStandardScheme();
      }
    }

    private static class cloneExperiment_argsStandardScheme extends StandardScheme<cloneExperiment_args> {

      public void read(org.apache.thrift.protocol.TProtocol iprot, cloneExperiment_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: // EXISTING_EXPERIMENT_ID
              if (schemeField.type == org.apache.thrift.protocol.TType.STRING) {
                struct.existingExperimentID = iprot.readString();
                struct.setExistingExperimentIDIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 3: // NEW_EXPERIMENT_NAME
              if (schemeField.type == org.apache.thrift.protocol.TType.STRING) {
                struct.newExperimentName = iprot.readString();
                struct.setNewExperimentNameIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            default:
              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
          }
          iprot.readFieldEnd();
        }
        iprot.readStructEnd();

        // check for required fields of primitive type, which can't be checked in the validate method
        struct.validate();
      }

      public void write(org.apache.thrift.protocol.TProtocol oprot, cloneExperiment_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.existingExperimentID != null) {
          oprot.writeFieldBegin(EXISTING_EXPERIMENT_ID_FIELD_DESC);
          oprot.writeString(struct.existingExperimentID);
          oprot.writeFieldEnd();
        }
        if (struct.newExperimentName != null) {
          oprot.writeFieldBegin(NEW_EXPERIMENT_NAME_FIELD_DESC);
          oprot.writeString(struct.newExperimentName);
          oprot.writeFieldEnd();
        }
        oprot.writeFieldStop();
        oprot.writeStructEnd();
      }

    }

    private static class cloneExperiment_argsTupleSchemeFactory implements SchemeFactory {
      public cloneExperiment_argsTupleScheme getScheme() {
        return new cloneExperiment_argsTupleScheme();
      }
    }

    private static class cloneExperiment_argsTupleScheme extends TupleScheme<cloneExperiment_args> {

      @Override
      public void write(org.apache.thrift.protocol.TProtocol prot, cloneExperiment_args struct) throws org.apache.thrift.TException {
        TTupleProtocol oprot = (TTupleProtocol) prot;
        struct.authzToken.write(oprot);
        BitSet optionals = new BitSet();
        if (struct.isSetExistingExperimentID()) {
          optionals.set(0);
        }
        if (struct.isSetNewExperimentName()) {
          optionals.set(1);
        }
        oprot.writeBitSet(optionals, 2);
        if (struct.isSetExistingExperimentID()) {
          oprot.writeString(struct.existingExperimentID);
        }
        if (struct.isSetNewExperimentName()) {
          oprot.writeString(struct.newExperimentName);
        }
      }

      @Override
      public void read(org.apache.thrift.protocol.TProtocol prot, cloneExperiment_args struct) throws org.apache.thrift.TException {
        TTupleProtocol iprot = (TTupleProtocol) prot;
        struct.authzToken = new org.apache.airavata.model.security.AuthzToken();
        struct.authzToken.read(iprot);
        struct.setAuthzTokenIsSet(true);
        BitSet incoming = iprot.readBitSet(2);
        if (incoming.get(0)) {
          struct.existingExperimentID = iprot.readString();
          struct.setExistingExperimentIDIsSet(true);
        }
        if (incoming.get(1)) {
          struct.newExperimentName = iprot.readString();
          struct.setNewExperimentNameIsSet(true);
        }
      }
    }

  }

  public static class cloneExperiment_result implements org.apache.thrift.TBase<cloneExperiment_result, cloneExperiment_result._Fields>, java.io.Serializable, Cloneable, Comparable<cloneExperiment_result>   {
    private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("cloneExperiment_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 IRE_FIELD_DESC = new org.apache.thrift.protocol.TField("ire", org.apache.thrift.protocol.TType.STRUCT, (short)1);
    private static final org.apache.thrift.protocol.TField ENF_FIELD_DESC = new org.apache.thrift.protocol.TField("enf", org.apache.thrift.protocol.TType.STRUCT, (short)2);
    private static final org.apache.thrift.protocol.TField ACE_FIELD_DESC = new org.apache.thrift.protocol.TField("ace", org.apache.thrift.protocol.TType.STRUCT, (short)3);
    private static final org.apache.thrift.protocol.TField ASE_FIELD_DESC = new org.apache.thrift.protocol.TField("ase", org.apache.thrift.protocol.TType.STRUCT, (short)4);
    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)5);

    private static final Map<Class<? extends IScheme>, SchemeFactory> schemes = new HashMap<Class<? extends IScheme>, SchemeFactory>();
    static {
      schemes.put(StandardScheme.class, new cloneExperiment_resultStandardSchemeFactory());
      schemes.put(TupleScheme.class, new cloneExperiment_resultTupleSchemeFactory());
    }

    public String success; // required
    public org.apache.airavata.model.error.InvalidRequestException ire; // required
    public org.apache.airavata.model.error.ExperimentNotFoundException enf; // required
    public org.apache.airavata.model.error.AiravataClientException ace; // required
    public org.apache.airavata.model.error.AiravataSystemException ase; // 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"),
      IRE((short)1, "ire"),
      ENF((short)2, "enf"),
      ACE((short)3, "ace"),
      ASE((short)4, "ase"),
      AE((short)5, "ae");

      private static final Map<String, _Fields> byName = new HashMap<String, _Fields>();

      static {
        for (_Fields field : EnumSet.allOf(_Fields.class)) {
          byName.put(field.getFieldName(), field);
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, or null if its not found.
       */
      public static _Fields findByThriftId(int fieldId) {
        switch(fieldId) {
          case 0: // SUCCESS
            return SUCCESS;
          case 1: // IRE
            return IRE;
          case 2: // ENF
            return ENF;
          case 3: // ACE
            return ACE;
          case 4: // ASE
            return ASE;
          case 5: // 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 IllegalArgumentException("Field " + fieldId + " doesn't exist!");
        return fields;
      }

      /**
       * Find the _Fields constant that matches name, or null if its not found.
       */
      public static _Fields findByName(String name) {
        return byName.get(name);
      }

      private final short _thriftId;
      private final String _fieldName;

      _Fields(short thriftId, String fieldName) {
        _thriftId = thriftId;
        _fieldName = fieldName;
      }

      public short getThriftFieldId() {
        return _thriftId;
      }

      public String getFieldName() {
        return _fieldName;
      }
    }

    // isset id assignments
    public static final Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
    static {
      Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new EnumMap<_Fields, org.apache.thrift.meta_data.FieldMetaData>(_Fields.class);
      tmpMap.put(_Fields.SUCCESS, new org.apache.thrift.meta_data.FieldMetaData("success", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING)));
      tmpMap.put(_Fields.IRE, new org.apache.thrift.meta_data.FieldMetaData("ire", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRUCT)));
      tmpMap.put(_Fields.ENF, new org.apache.thrift.meta_data.FieldMetaData("enf", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRUCT)));
      tmpMap.put(_Fields.ACE, new org.apache.thrift.meta_data.FieldMetaData("ace", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRUCT)));
      tmpMap.put(_Fields.ASE, new org.apache.thrift.meta_data.FieldMetaData("ase", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRUCT)));
      tmpMap.put(_Fields.AE, new org.apache.thrift.meta_data.FieldMetaData("ae", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRUCT)));
      metaDataMap = Collections.unmodifiableMap(tmpMap);
      org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(cloneExperiment_result.class, metaDataMap);
    }

    public cloneExperiment_result() {
    }

    public cloneExperiment_result(
      String success,
      org.apache.airavata.model.error.InvalidRequestException ire,
      org.apache.airavata.model.error.ExperimentNotFoundException enf,
      org.apache.airavata.model.error.AiravataClientException ace,
      org.apache.airavata.model.error.AiravataSystemException ase,
      org.apache.airavata.model.error.AuthorizationException ae)
    {
      this();
      this.success = success;
      this.ire = ire;
      this.enf = enf;
      this.ace = ace;
      this.ase = ase;
      this.ae = ae;
    }

    /**
     * Performs a deep copy on <i>other</i>.
     */
    public cloneExperiment_result(cloneExperiment_result other) {
      if (other.isSetSuccess()) {
        this.success = other.success;
      }
      if (other.isSetIre()) {
        this.ire = new org.apache.airavata.model.error.InvalidRequestException(other.ire);
      }
      if (other.isSetEnf()) {
        this.enf = new org.apache.airavata.model.error.ExperimentNotFoundException(other.enf);
      }
      if (other.isSetAce()) {
        this.ace = new org.apache.airavata.model.error.AiravataClientException(other.ace);
      }
      if (other.isSetAse()) {
        this.ase = new org.apache.airavata.model.error.AiravataSystemException(other.ase);
      }
      if (other.isSetAe()) {
        this.ae = new org.apache.airavata.model.error.AuthorizationException(other.ae);
      }
    }

    public cloneExperiment_result deepCopy() {
      return new cloneExperiment_result(this);
    }

    @Override
    public void clear() {
      this.success = null;
      this.ire = null;
      this.enf = null;
      this.ace = null;
      this.ase = null;
      this.ae = null;
    }

    public String getSuccess() {
      return this.success;
    }

    public cloneExperiment_result setSuccess(String success) {
      this.success = success;
      return this;
    }

    public void unsetSuccess() {
      this.success = null;
    }

    /** Returns true if field success is set (has been assigned a value) and false otherwise */
    public boolean isSetSuccess() {
      return this.success != null;
    }

    public void setSuccessIsSet(boolean value) {
      if (!value) {
        this.success = null;
      }
    }

    public org.apache.airavata.model.error.InvalidRequestException getIre() {
      return this.ire;
    }

    public cloneExperiment_result setIre(org.apache.airavata.model.error.InvalidRequestException ire) {
      this.ire = ire;
      return this;
    }

    public void unsetIre() {
      this.ire = null;
    }

    /** Returns true if field ire is set (has been assigned a value) and false otherwise */
    public boolean isSetIre() {
      return this.ire != null;
    }

    public void setIreIsSet(boolean value) {
      if (!value) {
        this.ire = null;
      }
    }

    public org.apache.airavata.model.error.ExperimentNotFoundException getEnf() {
      return this.enf;
    }

    public cloneExperiment_result setEnf(org.apache.airavata.model.error.ExperimentNotFoundException enf) {
      this.enf = enf;
      return this;
    }

    public void unsetEnf() {
      this.enf = null;
    }

    /** Returns true if field enf is set (has been assigned a value) and false otherwise */
    public boolean isSetEnf() {
      return this.enf != null;
    }

    public void setEnfIsSet(boolean value) {
      if (!value) {
        this.enf = null;
      }
    }

    public org.apache.airavata.model.error.AiravataClientException getAce() {
      return this.ace;
    }

    public cloneExperiment_result setAce(org.apache.airavata.model.error.AiravataClientException ace) {
      this.ace = ace;
      return this;
    }

    public void unsetAce() {
      this.ace = null;
    }

    /** Returns true if field ace is set (has been assigned a value) and false otherwise */
    public boolean isSetAce() {
      return this.ace != null;
    }

    public void setAceIsSet(boolean value) {
      if (!value) {
        this.ace = null;
      }
    }

    public org.apache.airavata.model.error.AiravataSystemException getAse() {
      return this.ase;
    }

    public cloneExperiment_result setAse(org.apache.airavata.model.error.AiravataSystemException ase) {
      this.ase = ase;
      return this;
    }

    public void unsetAse() {
      this.ase = null;
    }

    /** Returns true if field ase is set (has been assigned a value) and false otherwise */
    public boolean isSetAse() {
      return this.ase != null;
    }

    public void setAseIsSet(boolean value) {
      if (!value) {
        this.ase = null;
      }
    }

    public org.apache.airavata.model.error.AuthorizationException getAe() {
      return this.ae;
    }

    public cloneExperiment_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, Object value) {
      switch (field) {
      case SUCCESS:
        if (value == null) {
          unsetSuccess();
        } else {
          setSuccess((String)value);
        }
        break;

      case IRE:
        if (value == null) {
          unsetIre();
        } else {
          setIre((org.apache.airavata.model.error.InvalidRequestException)value);
        }
        break;

      case ENF:
        if (value == null) {
          unsetEnf();
        } else {
          setEnf((org.apache.airavata.model.error.ExperimentNotFoundException)value);
        }
        break;

      case ACE:
        if (value == null) {
          unsetAce();
        } else {
          setAce((org.apache.airavata.model.error.AiravataClientException)value);
        }
        break;

      case ASE:
        if (value == null) {
          unsetAse();
        } else {
          setAse((org.apache.airavata.model.error.AiravataSystemException)value);
        }
        break;

      case AE:
        if (value == null) {
          unsetAe();
        } else {
          setAe((org.apache.airavata.model.error.AuthorizationException)value);
        }
        break;

      }
    }

    public Object getFieldValue(_Fields field) {
      switch (field) {
      case SUCCESS:
        return getSuccess();

      case IRE:
        return getIre();

      case ENF:
        return getEnf();

      case ACE:
        return getAce();

      case ASE:
        return getAse();

      case AE:
        return getAe();

      }
      throw new IllegalStateException();
    }

    /** Returns true if field corresponding to fieldID is set (has been assigned a value) and false otherwise */
    public boolean isSet(_Fields field) {
      if (field == null) {
        throw new IllegalArgumentException();
      }

      switch (field) {
      case SUCCESS:
        return isSetSuccess();
      case IRE:
        return isSetIre();
      case ENF:
        return isSetEnf();
      case ACE:
        return isSetAce();
      case ASE:
        return isSetAse();
      case AE:
        return isSetAe();
      }
      throw new IllegalStateException();
    }

    @Override
    public boolean equals(Object that) {
      if (that == null)
        return false;
      if (that instanceof cloneExperiment_result)
        return this.equals((cloneExperiment_result)that);
      return false;
    }

    public boolean equals(cloneExperiment_result that) {
      if (that == null)
        return false;

      boolean this_present_success = true && this.isSetSuccess();
      boolean that_present_success = true && that.isSetSuccess();
      if (this_present_success || that_present_success) {
        if (!(this_present_success && that_present_success))
          return false;
        if (!this.success.equals(that.success))
          return false;
      }

      boolean this_present_ire = true && this.isSetIre();
      boolean that_present_ire = true && that.isSetIre();
      if (this_present_ire || that_present_ire) {
        if (!(this_present_ire && that_present_ire))
          return false;
        if (!this.ire.equals(that.ire))
          return false;
      }

      boolean this_present_enf = true && this.isSetEnf();
      boolean that_present_enf = true && that.isSetEnf();
      if (this_present_enf || that_present_enf) {
        if (!(this_present_enf && that_present_enf))
          return false;
        if (!this.enf.equals(that.enf))
          return false;
      }

      boolean this_present_ace = true && this.isSetAce();
      boolean that_present_ace = true && that.isSetAce();
      if (this_present_ace || that_present_ace) {
        if (!(this_present_ace && that_present_ace))
          return false;
        if (!this.ace.equals(that.ace))
          return false;
      }

      boolean this_present_ase = true && this.isSetAse();
      boolean that_present_ase = true && that.isSetAse();
      if (this_present_ase || that_present_ase) {
        if (!(this_present_ase && that_present_ase))
          return false;
        if (!this.ase.equals(that.ase))
          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() {
      List<Object> list = new ArrayList<Object>();

      boolean present_success = true && (isSetSuccess());
      list.add(present_success);
      if (present_success)
        list.add(success);

      boolean present_ire = true && (isSetIre());
      list.add(present_ire);
      if (present_ire)
        list.add(ire);

      boolean present_enf = true && (isSetEnf());
      list.add(present_enf);
      if (present_enf)
        list.add(enf);

      boolean present_ace = true && (isSetAce());
      list.add(present_ace);
      if (present_ace)
        list.add(ace);

      boolean present_ase = true && (isSetAse());
      list.add(present_ase);
      if (present_ase)
        list.add(ase);

      boolean present_ae = true && (isSetAe());
      list.add(present_ae);
      if (present_ae)
        list.add(ae);

      return list.hashCode();
    }

    @Override
    public int compareTo(cloneExperiment_result other) {
      if (!getClass().equals(other.getClass())) {
        return getClass().getName().compareTo(other.getClass().getName());
      }

      int lastComparison = 0;

      lastComparison = Boolean.valueOf(isSetSuccess()).compareTo(other.isSetSuccess());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetSuccess()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.success, other.success);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = Boolean.valueOf(isSetIre()).compareTo(other.isSetIre());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetIre()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.ire, other.ire);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = Boolean.valueOf(isSetEnf()).compareTo(other.isSetEnf());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetEnf()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.enf, other.enf);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = Boolean.valueOf(isSetAce()).compareTo(other.isSetAce());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetAce()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.ace, other.ace);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = Boolean.valueOf(isSetAse()).compareTo(other.isSetAse());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetAse()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.ase, other.ase);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = 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 {
      schemes.get(iprot.getScheme()).getScheme().read(iprot, this);
    }

    public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException {
      schemes.get(oprot.getScheme()).getScheme().write(oprot, this);
      }

    @Override
    public String toString() {
      StringBuilder sb = new StringBuilder("cloneExperiment_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("ire:");
      if (this.ire == null) {
        sb.append("null");
      } else {
        sb.append(this.ire);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("enf:");
      if (this.enf == null) {
        sb.append("null");
      } else {
        sb.append(this.enf);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("ace:");
      if (this.ace == null) {
        sb.append("null");
      } else {
        sb.append(this.ace);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("ase:");
      if (this.ase == null) {
        sb.append("null");
      } else {
        sb.append(this.ase);
      }
      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, 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 cloneExperiment_resultStandardSchemeFactory implements SchemeFactory {
      public cloneExperiment_resultStandardScheme getScheme() {
        return new cloneExperiment_resultStandardScheme();
      }
    }

    private static class cloneExperiment_resultStandardScheme extends StandardScheme<cloneExperiment_result> {

      public void read(org.apache.thrift.protocol.TProtocol iprot, cloneExperiment_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: // IRE
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.ire = new org.apache.airavata.model.error.InvalidRequestException();
                struct.ire.read(iprot);
                struct.setIreIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 2: // ENF
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.enf = new org.apache.airavata.model.error.ExperimentNotFoundException();
                struct.enf.read(iprot);
                struct.setEnfIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 3: // ACE
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.ace = new org.apache.airavata.model.error.AiravataClientException();
                struct.ace.read(iprot);
                struct.setAceIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 4: // ASE
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.ase = new org.apache.airavata.model.error.AiravataSystemException();
                struct.ase.read(iprot);
                struct.setAseIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 5: // 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, cloneExperiment_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.ire != null) {
          oprot.writeFieldBegin(IRE_FIELD_DESC);
          struct.ire.write(oprot);
          oprot.writeFieldEnd();
        }
        if (struct.enf != null) {
          oprot.writeFieldBegin(ENF_FIELD_DESC);
          struct.enf.write(oprot);
          oprot.writeFieldEnd();
        }
        if (struct.ace != null) {
          oprot.writeFieldBegin(ACE_FIELD_DESC);
          struct.ace.write(oprot);
          oprot.writeFieldEnd();
        }
        if (struct.ase != null) {
          oprot.writeFieldBegin(ASE_FIELD_DESC);
          struct.ase.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 cloneExperiment_resultTupleSchemeFactory implements SchemeFactory {
      public cloneExperiment_resultTupleScheme getScheme() {
        return new cloneExperiment_resultTupleScheme();
      }
    }

    private static class cloneExperiment_resultTupleScheme extends TupleScheme<cloneExperiment_result> {

      @Override
      public void write(org.apache.thrift.protocol.TProtocol prot, cloneExperiment_result struct) throws org.apache.thrift.TException {
        TTupleProtocol oprot = (TTupleProtocol) prot;
        BitSet optionals = new BitSet();
        if (struct.isSetSuccess()) {
          optionals.set(0);
        }
        if (struct.isSetIre()) {
          optionals.set(1);
        }
        if (struct.isSetEnf()) {
          optionals.set(2);
        }
        if (struct.isSetAce()) {
          optionals.set(3);
        }
        if (struct.isSetAse()) {
          optionals.set(4);
        }
        if (struct.isSetAe()) {
          optionals.set(5);
        }
        oprot.writeBitSet(optionals, 6);
        if (struct.isSetSuccess()) {
          oprot.writeString(struct.success);
        }
        if (struct.isSetIre()) {
          struct.ire.write(oprot);
        }
        if (struct.isSetEnf()) {
          struct.enf.write(oprot);
        }
        if (struct.isSetAce()) {
          struct.ace.write(oprot);
        }
        if (struct.isSetAse()) {
          struct.ase.write(oprot);
        }
        if (struct.isSetAe()) {
          struct.ae.write(oprot);
        }
      }

      @Override
      public void read(org.apache.thrift.protocol.TProtocol prot, cloneExperiment_result struct) throws org.apache.thrift.TException {
        TTupleProtocol iprot = (TTupleProtocol) prot;
        BitSet incoming = iprot.readBitSet(6);
        if (incoming.get(0)) {
          struct.success = iprot.readString();
          struct.setSuccessIsSet(true);
        }
        if (incoming.get(1)) {
          struct.ire = new org.apache.airavata.model.error.InvalidRequestException();
          struct.ire.read(iprot);
          struct.setIreIsSet(true);
        }
        if (incoming.get(2)) {
          struct.enf = new org.apache.airavata.model.error.ExperimentNotFoundException();
          struct.enf.read(iprot);
          struct.setEnfIsSet(true);
        }
        if (incoming.get(3)) {
          struct.ace = new org.apache.airavata.model.error.AiravataClientException();
          struct.ace.read(iprot);
          struct.setAceIsSet(true);
        }
        if (incoming.get(4)) {
          struct.ase = new org.apache.airavata.model.error.AiravataSystemException();
          struct.ase.read(iprot);
          struct.setAseIsSet(true);
        }
        if (incoming.get(5)) {
          struct.ae = new org.apache.airavata.model.error.AuthorizationException();
          struct.ae.read(iprot);
          struct.setAeIsSet(true);
        }
      }
    }

  }

  public static class terminateExperiment_args implements org.apache.thrift.TBase<terminateExperiment_args, terminateExperiment_args._Fields>, java.io.Serializable, Cloneable, Comparable<terminateExperiment_args>   {
    private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("terminateExperiment_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_EXPERIMENT_ID_FIELD_DESC = new org.apache.thrift.protocol.TField("airavataExperimentId", 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 Map<Class<? extends IScheme>, SchemeFactory> schemes = new HashMap<Class<? extends IScheme>, SchemeFactory>();
    static {
      schemes.put(StandardScheme.class, new terminateExperiment_argsStandardSchemeFactory());
      schemes.put(TupleScheme.class, new terminateExperiment_argsTupleSchemeFactory());
    }

    public org.apache.airavata.model.security.AuthzToken authzToken; // required
    public String airavataExperimentId; // required
    public 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_EXPERIMENT_ID((short)2, "airavataExperimentId"),
      GATEWAY_ID((short)3, "gatewayId");

      private static final Map<String, _Fields> byName = new HashMap<String, _Fields>();

      static {
        for (_Fields field : EnumSet.allOf(_Fields.class)) {
          byName.put(field.getFieldName(), field);
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, or null if its not found.
       */
      public static _Fields findByThriftId(int fieldId) {
        switch(fieldId) {
          case 1: // AUTHZ_TOKEN
            return AUTHZ_TOKEN;
          case 2: // AIRAVATA_EXPERIMENT_ID
            return AIRAVATA_EXPERIMENT_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 IllegalArgumentException("Field " + fieldId + " doesn't exist!");
        return fields;
      }

      /**
       * Find the _Fields constant that matches name, or null if its not found.
       */
      public static _Fields findByName(String name) {
        return byName.get(name);
      }

      private final short _thriftId;
      private final String _fieldName;

      _Fields(short thriftId, String fieldName) {
        _thriftId = thriftId;
        _fieldName = fieldName;
      }

      public short getThriftFieldId() {
        return _thriftId;
      }

      public String getFieldName() {
        return _fieldName;
      }
    }

    // isset id assignments
    public static final Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
    static {
      Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new EnumMap<_Fields, org.apache.thrift.meta_data.FieldMetaData>(_Fields.class);
      tmpMap.put(_Fields.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_EXPERIMENT_ID, new org.apache.thrift.meta_data.FieldMetaData("airavataExperimentId", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          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.DEFAULT, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING)));
      metaDataMap = Collections.unmodifiableMap(tmpMap);
      org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(terminateExperiment_args.class, metaDataMap);
    }

    public terminateExperiment_args() {
    }

    public terminateExperiment_args(
      org.apache.airavata.model.security.AuthzToken authzToken,
      String airavataExperimentId,
      String gatewayId)
    {
      this();
      this.authzToken = authzToken;
      this.airavataExperimentId = airavataExperimentId;
      this.gatewayId = gatewayId;
    }

    /**
     * Performs a deep copy on <i>other</i>.
     */
    public terminateExperiment_args(terminateExperiment_args other) {
      if (other.isSetAuthzToken()) {
        this.authzToken = new org.apache.airavata.model.security.AuthzToken(other.authzToken);
      }
      if (other.isSetAiravataExperimentId()) {
        this.airavataExperimentId = other.airavataExperimentId;
      }
      if (other.isSetGatewayId()) {
        this.gatewayId = other.gatewayId;
      }
    }

    public terminateExperiment_args deepCopy() {
      return new terminateExperiment_args(this);
    }

    @Override
    public void clear() {
      this.authzToken = null;
      this.airavataExperimentId = null;
      this.gatewayId = null;
    }

    public org.apache.airavata.model.security.AuthzToken getAuthzToken() {
      return this.authzToken;
    }

    public terminateExperiment_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 String getAiravataExperimentId() {
      return this.airavataExperimentId;
    }

    public terminateExperiment_args setAiravataExperimentId(String airavataExperimentId) {
      this.airavataExperimentId = airavataExperimentId;
      return this;
    }

    public void unsetAiravataExperimentId() {
      this.airavataExperimentId = null;
    }

    /** Returns true if field airavataExperimentId is set (has been assigned a value) and false otherwise */
    public boolean isSetAiravataExperimentId() {
      return this.airavataExperimentId != null;
    }

    public void setAiravataExperimentIdIsSet(boolean value) {
      if (!value) {
        this.airavataExperimentId = null;
      }
    }

    public String getGatewayId() {
      return this.gatewayId;
    }

    public terminateExperiment_args setGatewayId(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, Object value) {
      switch (field) {
      case AUTHZ_TOKEN:
        if (value == null) {
          unsetAuthzToken();
        } else {
          setAuthzToken((org.apache.airavata.model.security.AuthzToken)value);
        }
        break;

      case AIRAVATA_EXPERIMENT_ID:
        if (value == null) {
          unsetAiravataExperimentId();
        } else {
          setAiravataExperimentId((String)value);
        }
        break;

      case GATEWAY_ID:
        if (value == null) {
          unsetGatewayId();
        } else {
          setGatewayId((String)value);
        }
        break;

      }
    }

    public Object getFieldValue(_Fields field) {
      switch (field) {
      case AUTHZ_TOKEN:
        return getAuthzToken();

      case AIRAVATA_EXPERIMENT_ID:
        return getAiravataExperimentId();

      case GATEWAY_ID:
        return getGatewayId();

      }
      throw new IllegalStateException();
    }

    /** Returns true if field corresponding to fieldID is set (has been assigned a value) and false otherwise */
    public boolean isSet(_Fields field) {
      if (field == null) {
        throw new IllegalArgumentException();
      }

      switch (field) {
      case AUTHZ_TOKEN:
        return isSetAuthzToken();
      case AIRAVATA_EXPERIMENT_ID:
        return isSetAiravataExperimentId();
      case GATEWAY_ID:
        return isSetGatewayId();
      }
      throw new IllegalStateException();
    }

    @Override
    public boolean equals(Object that) {
      if (that == null)
        return false;
      if (that instanceof terminateExperiment_args)
        return this.equals((terminateExperiment_args)that);
      return false;
    }

    public boolean equals(terminateExperiment_args that) {
      if (that == null)
        return false;

      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_airavataExperimentId = true && this.isSetAiravataExperimentId();
      boolean that_present_airavataExperimentId = true && that.isSetAiravataExperimentId();
      if (this_present_airavataExperimentId || that_present_airavataExperimentId) {
        if (!(this_present_airavataExperimentId && that_present_airavataExperimentId))
          return false;
        if (!this.airavataExperimentId.equals(that.airavataExperimentId))
          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() {
      List<Object> list = new ArrayList<Object>();

      boolean present_authzToken = true && (isSetAuthzToken());
      list.add(present_authzToken);
      if (present_authzToken)
        list.add(authzToken);

      boolean present_airavataExperimentId = true && (isSetAiravataExperimentId());
      list.add(present_airavataExperimentId);
      if (present_airavataExperimentId)
        list.add(airavataExperimentId);

      boolean present_gatewayId = true && (isSetGatewayId());
      list.add(present_gatewayId);
      if (present_gatewayId)
        list.add(gatewayId);

      return list.hashCode();
    }

    @Override
    public int compareTo(terminateExperiment_args other) {
      if (!getClass().equals(other.getClass())) {
        return getClass().getName().compareTo(other.getClass().getName());
      }

      int lastComparison = 0;

      lastComparison = 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 = Boolean.valueOf(isSetAiravataExperimentId()).compareTo(other.isSetAiravataExperimentId());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetAiravataExperimentId()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.airavataExperimentId, other.airavataExperimentId);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = 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 {
      schemes.get(iprot.getScheme()).getScheme().read(iprot, this);
    }

    public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException {
      schemes.get(oprot.getScheme()).getScheme().write(oprot, this);
    }

    @Override
    public String toString() {
      StringBuilder sb = new StringBuilder("terminateExperiment_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("airavataExperimentId:");
      if (this.airavataExperimentId == null) {
        sb.append("null");
      } else {
        sb.append(this.airavataExperimentId);
      }
      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());
      }
      // 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, 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 terminateExperiment_argsStandardSchemeFactory implements SchemeFactory {
      public terminateExperiment_argsStandardScheme getScheme() {
        return new terminateExperiment_argsStandardScheme();
      }
    }

    private static class terminateExperiment_argsStandardScheme extends StandardScheme<terminateExperiment_args> {

      public void read(org.apache.thrift.protocol.TProtocol iprot, terminateExperiment_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_EXPERIMENT_ID
              if (schemeField.type == org.apache.thrift.protocol.TType.STRING) {
                struct.airavataExperimentId = iprot.readString();
                struct.setAiravataExperimentIdIsSet(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, terminateExperiment_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.airavataExperimentId != null) {
          oprot.writeFieldBegin(AIRAVATA_EXPERIMENT_ID_FIELD_DESC);
          oprot.writeString(struct.airavataExperimentId);
          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 terminateExperiment_argsTupleSchemeFactory implements SchemeFactory {
      public terminateExperiment_argsTupleScheme getScheme() {
        return new terminateExperiment_argsTupleScheme();
      }
    }

    private static class terminateExperiment_argsTupleScheme extends TupleScheme<terminateExperiment_args> {

      @Override
      public void write(org.apache.thrift.protocol.TProtocol prot, terminateExperiment_args struct) throws org.apache.thrift.TException {
        TTupleProtocol oprot = (TTupleProtocol) prot;
        struct.authzToken.write(oprot);
        BitSet optionals = new BitSet();
        if (struct.isSetAiravataExperimentId()) {
          optionals.set(0);
        }
        if (struct.isSetGatewayId()) {
          optionals.set(1);
        }
        oprot.writeBitSet(optionals, 2);
        if (struct.isSetAiravataExperimentId()) {
          oprot.writeString(struct.airavataExperimentId);
        }
        if (struct.isSetGatewayId()) {
          oprot.writeString(struct.gatewayId);
        }
      }

      @Override
      public void read(org.apache.thrift.protocol.TProtocol prot, terminateExperiment_args struct) throws org.apache.thrift.TException {
        TTupleProtocol iprot = (TTupleProtocol) prot;
        struct.authzToken = new org.apache.airavata.model.security.AuthzToken();
        struct.authzToken.read(iprot);
        struct.setAuthzTokenIsSet(true);
        BitSet incoming = iprot.readBitSet(2);
        if (incoming.get(0)) {
          struct.airavataExperimentId = iprot.readString();
          struct.setAiravataExperimentIdIsSet(true);
        }
        if (incoming.get(1)) {
          struct.gatewayId = iprot.readString();
          struct.setGatewayIdIsSet(true);
        }
      }
    }

  }

  public static class terminateExperiment_result implements org.apache.thrift.TBase<terminateExperiment_result, terminateExperiment_result._Fields>, java.io.Serializable, Cloneable, Comparable<terminateExperiment_result>   {
    private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("terminateExperiment_result");

    private static final org.apache.thrift.protocol.TField IRE_FIELD_DESC = new org.apache.thrift.protocol.TField("ire", org.apache.thrift.protocol.TType.STRUCT, (short)1);
    private static final org.apache.thrift.protocol.TField ENF_FIELD_DESC = new org.apache.thrift.protocol.TField("enf", org.apache.thrift.protocol.TType.STRUCT, (short)2);
    private static final org.apache.thrift.protocol.TField ACE_FIELD_DESC = new org.apache.thrift.protocol.TField("ace", org.apache.thrift.protocol.TType.STRUCT, (short)3);
    private static final org.apache.thrift.protocol.TField ASE_FIELD_DESC = new org.apache.thrift.protocol.TField("ase", org.apache.thrift.protocol.TType.STRUCT, (short)4);
    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)5);

    private static final Map<Class<? extends IScheme>, SchemeFactory> schemes = new HashMap<Class<? extends IScheme>, SchemeFactory>();
    static {
      schemes.put(StandardScheme.class, new terminateExperiment_resultStandardSchemeFactory());
      schemes.put(TupleScheme.class, new terminateExperiment_resultTupleSchemeFactory());
    }

    public org.apache.airavata.model.error.InvalidRequestException ire; // required
    public org.apache.airavata.model.error.ExperimentNotFoundException enf; // required
    public org.apache.airavata.model.error.AiravataClientException ace; // required
    public org.apache.airavata.model.error.AiravataSystemException ase; // 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 {
      IRE((short)1, "ire"),
      ENF((short)2, "enf"),
      ACE((short)3, "ace"),
      ASE((short)4, "ase"),
      AE((short)5, "ae");

      private static final Map<String, _Fields> byName = new HashMap<String, _Fields>();

      static {
        for (_Fields field : EnumSet.allOf(_Fields.class)) {
          byName.put(field.getFieldName(), field);
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, or null if its not found.
       */
      public static _Fields findByThriftId(int fieldId) {
        switch(fieldId) {
          case 1: // IRE
            return IRE;
          case 2: // ENF
            return ENF;
          case 3: // ACE
            return ACE;
          case 4: // ASE
            return ASE;
          case 5: // 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 IllegalArgumentException("Field " + fieldId + " doesn't exist!");
        return fields;
      }

      /**
       * Find the _Fields constant that matches name, or null if its not found.
       */
      public static _Fields findByName(String name) {
        return byName.get(name);
      }

      private final short _thriftId;
      private final String _fieldName;

      _Fields(short thriftId, String fieldName) {
        _thriftId = thriftId;
        _fieldName = fieldName;
      }

      public short getThriftFieldId() {
        return _thriftId;
      }

      public String getFieldName() {
        return _fieldName;
      }
    }

    // isset id assignments
    public static final Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
    static {
      Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new EnumMap<_Fields, org.apache.thrift.meta_data.FieldMetaData>(_Fields.class);
      tmpMap.put(_Fields.IRE, new org.apache.thrift.meta_data.FieldMetaData("ire", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRUCT)));
      tmpMap.put(_Fields.ENF, new org.apache.thrift.meta_data.FieldMetaData("enf", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRUCT)));
      tmpMap.put(_Fields.ACE, new org.apache.thrift.meta_data.FieldMetaData("ace", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRUCT)));
      tmpMap.put(_Fields.ASE, new org.apache.thrift.meta_data.FieldMetaData("ase", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRUCT)));
      tmpMap.put(_Fields.AE, new org.apache.thrift.meta_data.FieldMetaData("ae", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRUCT)));
      metaDataMap = Collections.unmodifiableMap(tmpMap);
      org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(terminateExperiment_result.class, metaDataMap);
    }

    public terminateExperiment_result() {
    }

    public terminateExperiment_result(
      org.apache.airavata.model.error.InvalidRequestException ire,
      org.apache.airavata.model.error.ExperimentNotFoundException enf,
      org.apache.airavata.model.error.AiravataClientException ace,
      org.apache.airavata.model.error.AiravataSystemException ase,
      org.apache.airavata.model.error.AuthorizationException ae)
    {
      this();
      this.ire = ire;
      this.enf = enf;
      this.ace = ace;
      this.ase = ase;
      this.ae = ae;
    }

    /**
     * Performs a deep copy on <i>other</i>.
     */
    public terminateExperiment_result(terminateExperiment_result other) {
      if (other.isSetIre()) {
        this.ire = new org.apache.airavata.model.error.InvalidRequestException(other.ire);
      }
      if (other.isSetEnf()) {
        this.enf = new org.apache.airavata.model.error.ExperimentNotFoundException(other.enf);
      }
      if (other.isSetAce()) {
        this.ace = new org.apache.airavata.model.error.AiravataClientException(other.ace);
      }
      if (other.isSetAse()) {
        this.ase = new org.apache.airavata.model.error.AiravataSystemException(other.ase);
      }
      if (other.isSetAe()) {
        this.ae = new org.apache.airavata.model.error.AuthorizationException(other.ae);
      }
    }

    public terminateExperiment_result deepCopy() {
      return new terminateExperiment_result(this);
    }

    @Override
    public void clear() {
      this.ire = null;
      this.enf = null;
      this.ace = null;
      this.ase = null;
      this.ae = null;
    }

    public org.apache.airavata.model.error.InvalidRequestException getIre() {
      return this.ire;
    }

    public terminateExperiment_result setIre(org.apache.airavata.model.error.InvalidRequestException ire) {
      this.ire = ire;
      return this;
    }

    public void unsetIre() {
      this.ire = null;
    }

    /** Returns true if field ire is set (has been assigned a value) and false otherwise */
    public boolean isSetIre() {
      return this.ire != null;
    }

    public void setIreIsSet(boolean value) {
      if (!value) {
        this.ire = null;
      }
    }

    public org.apache.airavata.model.error.ExperimentNotFoundException getEnf() {
      return this.enf;
    }

    public terminateExperiment_result setEnf(org.apache.airavata.model.error.ExperimentNotFoundException enf) {
      this.enf = enf;
      return this;
    }

    public void unsetEnf() {
      this.enf = null;
    }

    /** Returns true if field enf is set (has been assigned a value) and false otherwise */
    public boolean isSetEnf() {
      return this.enf != null;
    }

    public void setEnfIsSet(boolean value) {
      if (!value) {
        this.enf = null;
      }
    }

    public org.apache.airavata.model.error.AiravataClientException getAce() {
      return this.ace;
    }

    public terminateExperiment_result setAce(org.apache.airavata.model.error.AiravataClientException ace) {
      this.ace = ace;
      return this;
    }

    public void unsetAce() {
      this.ace = null;
    }

    /** Returns true if field ace is set (has been assigned a value) and false otherwise */
    public boolean isSetAce() {
      return this.ace != null;
    }

    public void setAceIsSet(boolean value) {
      if (!value) {
        this.ace = null;
      }
    }

    public org.apache.airavata.model.error.AiravataSystemException getAse() {
      return this.ase;
    }

    public terminateExperiment_result setAse(org.apache.airavata.model.error.AiravataSystemException ase) {
      this.ase = ase;
      return this;
    }

    public void unsetAse() {
      this.ase = null;
    }

    /** Returns true if field ase is set (has been assigned a value) and false otherwise */
    public boolean isSetAse() {
      return this.ase != null;
    }

    public void setAseIsSet(boolean value) {
      if (!value) {
        this.ase = null;
      }
    }

    public org.apache.airavata.model.error.AuthorizationException getAe() {
      return this.ae;
    }

    public terminateExperiment_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, Object value) {
      switch (field) {
      case IRE:
        if (value == null) {
          unsetIre();
        } else {
          setIre((org.apache.airavata.model.error.InvalidRequestException)value);
        }
        break;

      case ENF:
        if (value == null) {
          unsetEnf();
        } else {
          setEnf((org.apache.airavata.model.error.ExperimentNotFoundException)value);
        }
        break;

      case ACE:
        if (value == null) {
          unsetAce();
        } else {
          setAce((org.apache.airavata.model.error.AiravataClientException)value);
        }
        break;

      case ASE:
        if (value == null) {
          unsetAse();
        } else {
          setAse((org.apache.airavata.model.error.AiravataSystemException)value);
        }
        break;

      case AE:
        if (value == null) {
          unsetAe();
        } else {
          setAe((org.apache.airavata.model.error.AuthorizationException)value);
        }
        break;

      }
    }

    public Object getFieldValue(_Fields field) {
      switch (field) {
      case IRE:
        return getIre();

      case ENF:
        return getEnf();

      case ACE:
        return getAce();

      case ASE:
        return getAse();

      case AE:
        return getAe();

      }
      throw new IllegalStateException();
    }

    /** Returns true if field corresponding to fieldID is set (has been assigned a value) and false otherwise */
    public boolean isSet(_Fields field) {
      if (field == null) {
        throw new IllegalArgumentException();
      }

      switch (field) {
      case IRE:
        return isSetIre();
      case ENF:
        return isSetEnf();
      case ACE:
        return isSetAce();
      case ASE:
        return isSetAse();
      case AE:
        return isSetAe();
      }
      throw new IllegalStateException();
    }

    @Override
    public boolean equals(Object that) {
      if (that == null)
        return false;
      if (that instanceof terminateExperiment_result)
        return this.equals((terminateExperiment_result)that);
      return false;
    }

    public boolean equals(terminateExperiment_result that) {
      if (that == null)
        return false;

      boolean this_present_ire = true && this.isSetIre();
      boolean that_present_ire = true && that.isSetIre();
      if (this_present_ire || that_present_ire) {
        if (!(this_present_ire && that_present_ire))
          return false;
        if (!this.ire.equals(that.ire))
          return false;
      }

      boolean this_present_enf = true && this.isSetEnf();
      boolean that_present_enf = true && that.isSetEnf();
      if (this_present_enf || that_present_enf) {
        if (!(this_present_enf && that_present_enf))
          return false;
        if (!this.enf.equals(that.enf))
          return false;
      }

      boolean this_present_ace = true && this.isSetAce();
      boolean that_present_ace = true && that.isSetAce();
      if (this_present_ace || that_present_ace) {
        if (!(this_present_ace && that_present_ace))
          return false;
        if (!this.ace.equals(that.ace))
          return false;
      }

      boolean this_present_ase = true && this.isSetAse();
      boolean that_present_ase = true && that.isSetAse();
      if (this_present_ase || that_present_ase) {
        if (!(this_present_ase && that_present_ase))
          return false;
        if (!this.ase.equals(that.ase))
          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() {
      List<Object> list = new ArrayList<Object>();

      boolean present_ire = true && (isSetIre());
      list.add(present_ire);
      if (present_ire)
        list.add(ire);

      boolean present_enf = true && (isSetEnf());
      list.add(present_enf);
      if (present_enf)
        list.add(enf);

      boolean present_ace = true && (isSetAce());
      list.add(present_ace);
      if (present_ace)
        list.add(ace);

      boolean present_ase = true && (isSetAse());
      list.add(present_ase);
      if (present_ase)
        list.add(ase);

      boolean present_ae = true && (isSetAe());
      list.add(present_ae);
      if (present_ae)
        list.add(ae);

      return list.hashCode();
    }

    @Override
    public int compareTo(terminateExperiment_result other) {
      if (!getClass().equals(other.getClass())) {
        return getClass().getName().compareTo(other.getClass().getName());
      }

      int lastComparison = 0;

      lastComparison = Boolean.valueOf(isSetIre()).compareTo(other.isSetIre());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetIre()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.ire, other.ire);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = Boolean.valueOf(isSetEnf()).compareTo(other.isSetEnf());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetEnf()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.enf, other.enf);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = Boolean.valueOf(isSetAce()).compareTo(other.isSetAce());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetAce()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.ace, other.ace);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = Boolean.valueOf(isSetAse()).compareTo(other.isSetAse());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetAse()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.ase, other.ase);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = 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 {
      schemes.get(iprot.getScheme()).getScheme().read(iprot, this);
    }

    public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException {
      schemes.get(oprot.getScheme()).getScheme().write(oprot, this);
      }

    @Override
    public String toString() {
      StringBuilder sb = new StringBuilder("terminateExperiment_result(");
      boolean first = true;

      sb.append("ire:");
      if (this.ire == null) {
        sb.append("null");
      } else {
        sb.append(this.ire);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("enf:");
      if (this.enf == null) {
        sb.append("null");
      } else {
        sb.append(this.enf);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("ace:");
      if (this.ace == null) {
        sb.append("null");
      } else {
        sb.append(this.ace);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("ase:");
      if (this.ase == null) {
        sb.append("null");
      } else {
        sb.append(this.ase);
      }
      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, 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 terminateExperiment_resultStandardSchemeFactory implements SchemeFactory {
      public terminateExperiment_resultStandardScheme getScheme() {
        return new terminateExperiment_resultStandardScheme();
      }
    }

    private static class terminateExperiment_resultStandardScheme extends StandardScheme<terminateExperiment_result> {

      public void read(org.apache.thrift.protocol.TProtocol iprot, terminateExperiment_result struct) throws org.apache.thrift.TException {
        org.apache.thrift.protocol.TField schemeField;
        iprot.readStructBegin();
        while (true)
        {
          schemeField = iprot.readFieldBegin();
          if (schemeField.type == org.apache.thrift.protocol.TType.STOP) { 
            break;
          }
          switch (schemeField.id) {
            case 1: // IRE
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.ire = new org.apache.airavata.model.error.InvalidRequestException();
                struct.ire.read(iprot);
                struct.setIreIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 2: // ENF
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.enf = new org.apache.airavata.model.error.ExperimentNotFoundException();
                struct.enf.read(iprot);
                struct.setEnfIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 3: // ACE
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.ace = new org.apache.airavata.model.error.AiravataClientException();
                struct.ace.read(iprot);
                struct.setAceIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 4: // ASE
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.ase = new org.apache.airavata.model.error.AiravataSystemException();
                struct.ase.read(iprot);
                struct.setAseIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 5: // 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, terminateExperiment_result struct) throws org.apache.thrift.TException {
        struct.validate();

        oprot.writeStructBegin(STRUCT_DESC);
        if (struct.ire != null) {
          oprot.writeFieldBegin(IRE_FIELD_DESC);
          struct.ire.write(oprot);
          oprot.writeFieldEnd();
        }
        if (struct.enf != null) {
          oprot.writeFieldBegin(ENF_FIELD_DESC);
          struct.enf.write(oprot);
          oprot.writeFieldEnd();
        }
        if (struct.ace != null) {
          oprot.writeFieldBegin(ACE_FIELD_DESC);
          struct.ace.write(oprot);
          oprot.writeFieldEnd();
        }
        if (struct.ase != null) {
          oprot.writeFieldBegin(ASE_FIELD_DESC);
          struct.ase.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 terminateExperiment_resultTupleSchemeFactory implements SchemeFactory {
      public terminateExperiment_resultTupleScheme getScheme() {
        return new terminateExperiment_resultTupleScheme();
      }
    }

    private static class terminateExperiment_resultTupleScheme extends TupleScheme<terminateExperiment_result> {

      @Override
      public void write(org.apache.thrift.protocol.TProtocol prot, terminateExperiment_result struct) throws org.apache.thrift.TException {
        TTupleProtocol oprot = (TTupleProtocol) prot;
        BitSet optionals = new BitSet();
        if (struct.isSetIre()) {
          optionals.set(0);
        }
        if (struct.isSetEnf()) {
          optionals.set(1);
        }
        if (struct.isSetAce()) {
          optionals.set(2);
        }
        if (struct.isSetAse()) {
          optionals.set(3);
        }
        if (struct.isSetAe()) {
          optionals.set(4);
        }
        oprot.writeBitSet(optionals, 5);
        if (struct.isSetIre()) {
          struct.ire.write(oprot);
        }
        if (struct.isSetEnf()) {
          struct.enf.write(oprot);
        }
        if (struct.isSetAce()) {
          struct.ace.write(oprot);
        }
        if (struct.isSetAse()) {
          struct.ase.write(oprot);
        }
        if (struct.isSetAe()) {
          struct.ae.write(oprot);
        }
      }

      @Override
      public void read(org.apache.thrift.protocol.TProtocol prot, terminateExperiment_result struct) throws org.apache.thrift.TException {
        TTupleProtocol iprot = (TTupleProtocol) prot;
        BitSet incoming = iprot.readBitSet(5);
        if (incoming.get(0)) {
          struct.ire = new org.apache.airavata.model.error.InvalidRequestException();
          struct.ire.read(iprot);
          struct.setIreIsSet(true);
        }
        if (incoming.get(1)) {
          struct.enf = new org.apache.airavata.model.error.ExperimentNotFoundException();
          struct.enf.read(iprot);
          struct.setEnfIsSet(true);
        }
        if (incoming.get(2)) {
          struct.ace = new org.apache.airavata.model.error.AiravataClientException();
          struct.ace.read(iprot);
          struct.setAceIsSet(true);
        }
        if (incoming.get(3)) {
          struct.ase = new org.apache.airavata.model.error.AiravataSystemException();
          struct.ase.read(iprot);
          struct.setAseIsSet(true);
        }
        if (incoming.get(4)) {
          struct.ae = new org.apache.airavata.model.error.AuthorizationException();
          struct.ae.read(iprot);
          struct.setAeIsSet(true);
        }
      }
    }

  }

  public static class registerApplicationModule_args implements org.apache.thrift.TBase<registerApplicationModule_args, registerApplicationModule_args._Fields>, java.io.Serializable, Cloneable, Comparable<registerApplicationModule_args>   {
    private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("registerApplicationModule_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.protocol.TField APPLICATION_MODULE_FIELD_DESC = new org.apache.thrift.protocol.TField("applicationModule", org.apache.thrift.protocol.TType.STRUCT, (short)3);

    private static final Map<Class<? extends IScheme>, SchemeFactory> schemes = new HashMap<Class<? extends IScheme>, SchemeFactory>();
    static {
      schemes.put(StandardScheme.class, new registerApplicationModule_argsStandardSchemeFactory());
      schemes.put(TupleScheme.class, new registerApplicationModule_argsTupleSchemeFactory());
    }

    public org.apache.airavata.model.security.AuthzToken authzToken; // required
    public String gatewayId; // required
    public org.apache.airavata.model.appcatalog.appdeployment.ApplicationModule applicationModule; // required

    /** 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"),
      APPLICATION_MODULE((short)3, "applicationModule");

      private static final Map<String, _Fields> byName = new HashMap<String, _Fields>();

      static {
        for (_Fields field : EnumSet.allOf(_Fields.class)) {
          byName.put(field.getFieldName(), field);
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, or null if its not found.
       */
      public static _Fields findByThriftId(int fieldId) {
        switch(fieldId) {
          case 1: // AUTHZ_TOKEN
            return AUTHZ_TOKEN;
          case 2: // GATEWAY_ID
            return GATEWAY_ID;
          case 3: // APPLICATION_MODULE
            return APPLICATION_MODULE;
          default:
            return null;
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, throwing an exception
       * if it is not found.
       */
      public static _Fields findByThriftIdOrThrow(int fieldId) {
        _Fields fields = findByThriftId(fieldId);
        if (fields == null) throw new IllegalArgumentException("Field " + fieldId + " doesn't exist!");
        return fields;
      }

      /**
       * Find the _Fields constant that matches name, or null if its not found.
       */
      public static _Fields findByName(String name) {
        return byName.get(name);
      }

      private final short _thriftId;
      private final String _fieldName;

      _Fields(short thriftId, String fieldName) {
        _thriftId = thriftId;
        _fieldName = fieldName;
      }

      public short getThriftFieldId() {
        return _thriftId;
      }

      public String getFieldName() {
        return _fieldName;
      }
    }

    // isset id assignments
    public static final Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
    static {
      Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new EnumMap<_Fields, org.apache.thrift.meta_data.FieldMetaData>(_Fields.class);
      tmpMap.put(_Fields.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)));
      tmpMap.put(_Fields.APPLICATION_MODULE, new org.apache.thrift.meta_data.FieldMetaData("applicationModule", org.apache.thrift.TFieldRequirementType.REQUIRED, 
          new org.apache.thrift.meta_data.StructMetaData(org.apache.thrift.protocol.TType.STRUCT, org.apache.airavata.model.appcatalog.appdeployment.ApplicationModule.class)));
      metaDataMap = Collections.unmodifiableMap(tmpMap);
      org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(registerApplicationModule_args.class, metaDataMap);
    }

    public registerApplicationModule_args() {
    }

    public registerApplicationModule_args(
      org.apache.airavata.model.security.AuthzToken authzToken,
      String gatewayId,
      org.apache.airavata.model.appcatalog.appdeployment.ApplicationModule applicationModule)
    {
      this();
      this.authzToken = authzToken;
      this.gatewayId = gatewayId;
      this.applicationModule = applicationModule;
    }

    /**
     * Performs a deep copy on <i>other</i>.
     */
    public registerApplicationModule_args(registerApplicationModule_args other) {
      if (other.isSetAuthzToken()) {
        this.authzToken = new org.apache.airavata.model.security.AuthzToken(other.authzToken);
      }
      if (other.isSetGatewayId()) {
        this.gatewayId = other.gatewayId;
      }
      if (other.isSetApplicationModule()) {
        this.applicationModule = new org.apache.airavata.model.appcatalog.appdeployment.ApplicationModule(other.applicationModule);
      }
    }

    public registerApplicationModule_args deepCopy() {
      return new registerApplicationModule_args(this);
    }

    @Override
    public void clear() {
      this.authzToken = null;
      this.gatewayId = null;
      this.applicationModule = null;
    }

    public org.apache.airavata.model.security.AuthzToken getAuthzToken() {
      return this.authzToken;
    }

    public registerApplicationModule_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 String getGatewayId() {
      return this.gatewayId;
    }

    public registerApplicationModule_args setGatewayId(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 org.apache.airavata.model.appcatalog.appdeployment.ApplicationModule getApplicationModule() {
      return this.applicationModule;
    }

    public registerApplicationModule_args setApplicationModule(org.apache.airavata.model.appcatalog.appdeployment.ApplicationModule applicationModule) {
      this.applicationModule = applicationModule;
      return this;
    }

    public void unsetApplicationModule() {
      this.applicationModule = null;
    }

    /** Returns true if field applicationModule is set (has been assigned a value) and false otherwise */
    public boolean isSetApplicationModule() {
      return this.applicationModule != null;
    }

    public void setApplicationModuleIsSet(boolean value) {
      if (!value) {
        this.applicationModule = null;
      }
    }

    public void setFieldValue(_Fields field, 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((String)value);
        }
        break;

      case APPLICATION_MODULE:
        if (value == null) {
          unsetApplicationModule();
        } else {
          setApplicationModule((org.apache.airavata.model.appcatalog.appdeployment.ApplicationModule)value);
        }
        break;

      }
    }

    public Object getFieldValue(_Fields field) {
      switch (field) {
      case AUTHZ_TOKEN:
        return getAuthzToken();

      case GATEWAY_ID:
        return getGatewayId();

      case APPLICATION_MODULE:
        return getApplicationModule();

      }
      throw new IllegalStateException();
    }

    /** Returns true if field corresponding to fieldID is set (has been assigned a value) and false otherwise */
    public boolean isSet(_Fields field) {
      if (field == null) {
        throw new IllegalArgumentException();
      }

      switch (field) {
      case AUTHZ_TOKEN:
        return isSetAuthzToken();
      case GATEWAY_ID:
        return isSetGatewayId();
      case APPLICATION_MODULE:
        return isSetApplicationModule();
      }
      throw new IllegalStateException();
    }

    @Override
    public boolean equals(Object that) {
      if (that == null)
        return false;
      if (that instanceof registerApplicationModule_args)
        return this.equals((registerApplicationModule_args)that);
      return false;
    }

    public boolean equals(registerApplicationModule_args that) {
      if (that == null)
        return false;

      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;
      }

      boolean this_present_applicationModule = true && this.isSetApplicationModule();
      boolean that_present_applicationModule = true && that.isSetApplicationModule();
      if (this_present_applicationModule || that_present_applicationModule) {
        if (!(this_present_applicationModule && that_present_applicationModule))
          return false;
        if (!this.applicationModule.equals(that.applicationModule))
          return false;
      }

      return true;
    }

    @Override
    public int hashCode() {
      List<Object> list = new ArrayList<Object>();

      boolean present_authzToken = true && (isSetAuthzToken());
      list.add(present_authzToken);
      if (present_authzToken)
        list.add(authzToken);

      boolean present_gatewayId = true && (isSetGatewayId());
      list.add(present_gatewayId);
      if (present_gatewayId)
        list.add(gatewayId);

      boolean present_applicationModule = true && (isSetApplicationModule());
      list.add(present_applicationModule);
      if (present_applicationModule)
        list.add(applicationModule);

      return list.hashCode();
    }

    @Override
    public int compareTo(registerApplicationModule_args other) {
      if (!getClass().equals(other.getClass())) {
        return getClass().getName().compareTo(other.getClass().getName());
      }

      int lastComparison = 0;

      lastComparison = 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 = 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;
        }
      }
      lastComparison = Boolean.valueOf(isSetApplicationModule()).compareTo(other.isSetApplicationModule());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetApplicationModule()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.applicationModule, other.applicationModule);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      return 0;
    }

    public _Fields fieldForId(int fieldId) {
      return _Fields.findByThriftId(fieldId);
    }

    public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
      schemes.get(iprot.getScheme()).getScheme().read(iprot, this);
    }

    public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException {
      schemes.get(oprot.getScheme()).getScheme().write(oprot, this);
    }

    @Override
    public String toString() {
      StringBuilder sb = new StringBuilder("registerApplicationModule_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;
      if (!first) sb.append(", ");
      sb.append("applicationModule:");
      if (this.applicationModule == null) {
        sb.append("null");
      } else {
        sb.append(this.applicationModule);
      }
      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());
      }
      if (applicationModule == null) {
        throw new org.apache.thrift.protocol.TProtocolException("Required field 'applicationModule' was not present! Struct: " + toString());
      }
      // check for sub-struct validity
      if (authzToken != null) {
        authzToken.validate();
      }
      if (applicationModule != null) {
        applicationModule.validate();
      }
    }

    private void writeObject(java.io.ObjectOutputStream out) throws java.io.IOException {
      try {
        write(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(out)));
      } catch (org.apache.thrift.TException te) {
        throw new java.io.IOException(te);
      }
    }

    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, ClassNotFoundException {
      try {
        read(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(in)));
      } catch (org.apache.thrift.TException te) {
        throw new java.io.IOException(te);
      }
    }

    private static class registerApplicationModule_argsStandardSchemeFactory implements SchemeFactory {
      public registerApplicationModule_argsStandardScheme getScheme() {
        return new registerApplicationModule_argsStandardScheme();
      }
    }

    private static class registerApplicationModule_argsStandardScheme extends StandardScheme<registerApplicationModule_args> {

      public void read(org.apache.thrift.protocol.TProtocol iprot, registerApplicationModule_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;
            case 3: // APPLICATION_MODULE
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.applicationModule = new org.apache.airavata.model.appcatalog.appdeployment.ApplicationModule();
                struct.applicationModule.read(iprot);
                struct.setApplicationModuleIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            default:
              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
          }
          iprot.readFieldEnd();
        }
        iprot.readStructEnd();

        // check for required fields of primitive type, which can't be checked in the validate method
        struct.validate();
      }

      public void write(org.apache.thrift.protocol.TProtocol oprot, registerApplicationModule_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();
        }
        if (struct.applicationModule != null) {
          oprot.writeFieldBegin(APPLICATION_MODULE_FIELD_DESC);
          struct.applicationModule.write(oprot);
          oprot.writeFieldEnd();
        }
        oprot.writeFieldStop();
        oprot.writeStructEnd();
      }

    }

    private static class registerApplicationModule_argsTupleSchemeFactory implements SchemeFactory {
      public registerApplicationModule_argsTupleScheme getScheme() {
        return new registerApplicationModule_argsTupleScheme();
      }
    }

    private static class registerApplicationModule_argsTupleScheme extends TupleScheme<registerApplicationModule_args> {

      @Override
      public void write(org.apache.thrift.protocol.TProtocol prot, registerApplicationModule_args struct) throws org.apache.thrift.TException {
        TTupleProtocol oprot = (TTupleProtocol) prot;
        struct.authzToken.write(oprot);
        oprot.writeString(struct.gatewayId);
        struct.applicationModule.write(oprot);
      }

      @Override
      public void read(org.apache.thrift.protocol.TProtocol prot, registerApplicationModule_args struct) throws org.apache.thrift.TException {
        TTupleProtocol iprot = (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);
        struct.applicationModule = new org.apache.airavata.model.appcatalog.appdeployment.ApplicationModule();
        struct.applicationModule.read(iprot);
        struct.setApplicationModuleIsSet(true);
      }
    }

  }

  public static class registerApplicationModule_result implements org.apache.thrift.TBase<registerApplicationModule_result, registerApplicationModule_result._Fields>, java.io.Serializable, Cloneable, Comparable<registerApplicationModule_result>   {
    private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("registerApplicationModule_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 IRE_FIELD_DESC = new org.apache.thrift.protocol.TField("ire", org.apache.thrift.protocol.TType.STRUCT, (short)1);
    private static final org.apache.thrift.protocol.TField ACE_FIELD_DESC = new org.apache.thrift.protocol.TField("ace", org.apache.thrift.protocol.TType.STRUCT, (short)2);
    private static final org.apache.thrift.protocol.TField ASE_FIELD_DESC = new org.apache.thrift.protocol.TField("ase", org.apache.thrift.protocol.TType.STRUCT, (short)3);
    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)4);

    private static final Map<Class<? extends IScheme>, SchemeFactory> schemes = new HashMap<Class<? extends IScheme>, SchemeFactory>();
    static {
      schemes.put(StandardScheme.class, new registerApplicationModule_resultStandardSchemeFactory());
      schemes.put(TupleScheme.class, new registerApplicationModule_resultTupleSchemeFactory());
    }

    public String success; // required
    public org.apache.airavata.model.error.InvalidRequestException ire; // required
    public org.apache.airavata.model.error.AiravataClientException ace; // required
    public org.apache.airavata.model.error.AiravataSystemException ase; // 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"),
      IRE((short)1, "ire"),
      ACE((short)2, "ace"),
      ASE((short)3, "ase"),
      AE((short)4, "ae");

      private static final Map<String, _Fields> byName = new HashMap<String, _Fields>();

      static {
        for (_Fields field : EnumSet.allOf(_Fields.class)) {
          byName.put(field.getFieldName(), field);
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, or null if its not found.
       */
      public static _Fields findByThriftId(int fieldId) {
        switch(fieldId) {
          case 0: // SUCCESS
            return SUCCESS;
          case 1: // IRE
            return IRE;
          case 2: // ACE
            return ACE;
          case 3: // ASE
            return ASE;
          case 4: // 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 IllegalArgumentException("Field " + fieldId + " doesn't exist!");
        return fields;
      }

      /**
       * Find the _Fields constant that matches name, or null if its not found.
       */
      public static _Fields findByName(String name) {
        return byName.get(name);
      }

      private final short _thriftId;
      private final String _fieldName;

      _Fields(short thriftId, String fieldName) {
        _thriftId = thriftId;
        _fieldName = fieldName;
      }

      public short getThriftFieldId() {
        return _thriftId;
      }

      public String getFieldName() {
        return _fieldName;
      }
    }

    // isset id assignments
    public static final Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
    static {
      Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new EnumMap<_Fields, org.apache.thrift.meta_data.FieldMetaData>(_Fields.class);
      tmpMap.put(_Fields.SUCCESS, new org.apache.thrift.meta_data.FieldMetaData("success", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING)));
      tmpMap.put(_Fields.IRE, new org.apache.thrift.meta_data.FieldMetaData("ire", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRUCT)));
      tmpMap.put(_Fields.ACE, new org.apache.thrift.meta_data.FieldMetaData("ace", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRUCT)));
      tmpMap.put(_Fields.ASE, new org.apache.thrift.meta_data.FieldMetaData("ase", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRUCT)));
      tmpMap.put(_Fields.AE, new org.apache.thrift.meta_data.FieldMetaData("ae", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRUCT)));
      metaDataMap = Collections.unmodifiableMap(tmpMap);
      org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(registerApplicationModule_result.class, metaDataMap);
    }

    public registerApplicationModule_result() {
    }

    public registerApplicationModule_result(
      String success,
      org.apache.airavata.model.error.InvalidRequestException ire,
      org.apache.airavata.model.error.AiravataClientException ace,
      org.apache.airavata.model.error.AiravataSystemException ase,
      org.apache.airavata.model.error.AuthorizationException ae)
    {
      this();
      this.success = success;
      this.ire = ire;
      this.ace = ace;
      this.ase = ase;
      this.ae = ae;
    }

    /**
     * Performs a deep copy on <i>other</i>.
     */
    public registerApplicationModule_result(registerApplicationModule_result other) {
      if (other.isSetSuccess()) {
        this.success = other.success;
      }
      if (other.isSetIre()) {
        this.ire = new org.apache.airavata.model.error.InvalidRequestException(other.ire);
      }
      if (other.isSetAce()) {
        this.ace = new org.apache.airavata.model.error.AiravataClientException(other.ace);
      }
      if (other.isSetAse()) {
        this.ase = new org.apache.airavata.model.error.AiravataSystemException(other.ase);
      }
      if (other.isSetAe()) {
        this.ae = new org.apache.airavata.model.error.AuthorizationException(other.ae);
      }
    }

    public registerApplicationModule_result deepCopy() {
      return new registerApplicationModule_result(this);
    }

    @Override
    public void clear() {
      this.success = null;
      this.ire = null;
      this.ace = null;
      this.ase = null;
      this.ae = null;
    }

    public String getSuccess() {
      return this.success;
    }

    public registerApplicationModule_result setSuccess(String success) {
      this.success = success;
      return this;
    }

    public void unsetSuccess() {
      this.success = null;
    }

    /** Returns true if field success is set (has been assigned a value) and false otherwise */
    public boolean isSetSuccess() {
      return this.success != null;
    }

    public void setSuccessIsSet(boolean value) {
      if (!value) {
        this.success = null;
      }
    }

    public org.apache.airavata.model.error.InvalidRequestException getIre() {
      return this.ire;
    }

    public registerApplicationModule_result setIre(org.apache.airavata.model.error.InvalidRequestException ire) {
      this.ire = ire;
      return this;
    }

    public void unsetIre() {
      this.ire = null;
    }

    /** Returns true if field ire is set (has been assigned a value) and false otherwise */
    public boolean isSetIre() {
      return this.ire != null;
    }

    public void setIreIsSet(boolean value) {
      if (!value) {
        this.ire = null;
      }
    }

    public org.apache.airavata.model.error.AiravataClientException getAce() {
      return this.ace;
    }

    public registerApplicationModule_result setAce(org.apache.airavata.model.error.AiravataClientException ace) {
      this.ace = ace;
      return this;
    }

    public void unsetAce() {
      this.ace = null;
    }

    /** Returns true if field ace is set (has been assigned a value) and false otherwise */
    public boolean isSetAce() {
      return this.ace != null;
    }

    public void setAceIsSet(boolean value) {
      if (!value) {
        this.ace = null;
      }
    }

    public org.apache.airavata.model.error.AiravataSystemException getAse() {
      return this.ase;
    }

    public registerApplicationModule_result setAse(org.apache.airavata.model.error.AiravataSystemException ase) {
      this.ase = ase;
      return this;
    }

    public void unsetAse() {
      this.ase = null;
    }

    /** Returns true if field ase is set (has been assigned a value) and false otherwise */
    public boolean isSetAse() {
      return this.ase != null;
    }

    public void setAseIsSet(boolean value) {
      if (!value) {
        this.ase = null;
      }
    }

    public org.apache.airavata.model.error.AuthorizationException getAe() {
      return this.ae;
    }

    public registerApplicationModule_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, Object value) {
      switch (field) {
      case SUCCESS:
        if (value == null) {
          unsetSuccess();
        } else {
          setSuccess((String)value);
        }
        break;

      case IRE:
        if (value == null) {
          unsetIre();
        } else {
          setIre((org.apache.airavata.model.error.InvalidRequestException)value);
        }
        break;

      case ACE:
        if (value == null) {
          unsetAce();
        } else {
          setAce((org.apache.airavata.model.error.AiravataClientException)value);
        }
        break;

      case ASE:
        if (value == null) {
          unsetAse();
        } else {
          setAse((org.apache.airavata.model.error.AiravataSystemException)value);
        }
        break;

      case AE:
        if (value == null) {
          unsetAe();
        } else {
          setAe((org.apache.airavata.model.error.AuthorizationException)value);
        }
        break;

      }
    }

    public Object getFieldValue(_Fields field) {
      switch (field) {
      case SUCCESS:
        return getSuccess();

      case IRE:
        return getIre();

      case ACE:
        return getAce();

      case ASE:
        return getAse();

      case AE:
        return getAe();

      }
      throw new IllegalStateException();
    }

    /** Returns true if field corresponding to fieldID is set (has been assigned a value) and false otherwise */
    public boolean isSet(_Fields field) {
      if (field == null) {
        throw new IllegalArgumentException();
      }

      switch (field) {
      case SUCCESS:
        return isSetSuccess();
      case IRE:
        return isSetIre();
      case ACE:
        return isSetAce();
      case ASE:
        return isSetAse();
      case AE:
        return isSetAe();
      }
      throw new IllegalStateException();
    }

    @Override
    public boolean equals(Object that) {
      if (that == null)
        return false;
      if (that instanceof registerApplicationModule_result)
        return this.equals((registerApplicationModule_result)that);
      return false;
    }

    public boolean equals(registerApplicationModule_result that) {
      if (that == null)
        return false;

      boolean this_present_success = true && this.isSetSuccess();
      boolean that_present_success = true && that.isSetSuccess();
      if (this_present_success || that_present_success) {
        if (!(this_present_success && that_present_success))
          return false;
        if (!this.success.equals(that.success))
          return false;
      }

      boolean this_present_ire = true && this.isSetIre();
      boolean that_present_ire = true && that.isSetIre();
      if (this_present_ire || that_present_ire) {
        if (!(this_present_ire && that_present_ire))
          return false;
        if (!this.ire.equals(that.ire))
          return false;
      }

      boolean this_present_ace = true && this.isSetAce();
      boolean that_present_ace = true && that.isSetAce();
      if (this_present_ace || that_present_ace) {
        if (!(this_present_ace && that_present_ace))
          return false;
        if (!this.ace.equals(that.ace))
          return false;
      }

      boolean this_present_ase = true && this.isSetAse();
      boolean that_present_ase = true && that.isSetAse();
      if (this_present_ase || that_present_ase) {
        if (!(this_present_ase && that_present_ase))
          return false;
        if (!this.ase.equals(that.ase))
          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() {
      List<Object> list = new ArrayList<Object>();

      boolean present_success = true && (isSetSuccess());
      list.add(present_success);
      if (present_success)
        list.add(success);

      boolean present_ire = true && (isSetIre());
      list.add(present_ire);
      if (present_ire)
        list.add(ire);

      boolean present_ace = true && (isSetAce());
      list.add(present_ace);
      if (present_ace)
        list.add(ace);

      boolean present_ase = true && (isSetAse());
      list.add(present_ase);
      if (present_ase)
        list.add(ase);

      boolean present_ae = true && (isSetAe());
      list.add(present_ae);
      if (present_ae)
        list.add(ae);

      return list.hashCode();
    }

    @Override
    public int compareTo(registerApplicationModule_result other) {
      if (!getClass().equals(other.getClass())) {
        return getClass().getName().compareTo(other.getClass().getName());
      }

      int lastComparison = 0;

      lastComparison = Boolean.valueOf(isSetSuccess()).compareTo(other.isSetSuccess());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetSuccess()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.success, other.success);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = Boolean.valueOf(isSetIre()).compareTo(other.isSetIre());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetIre()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.ire, other.ire);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = Boolean.valueOf(isSetAce()).compareTo(other.isSetAce());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetAce()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.ace, other.ace);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = Boolean.valueOf(isSetAse()).compareTo(other.isSetAse());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetAse()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.ase, other.ase);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = 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 {
      schemes.get(iprot.getScheme()).getScheme().read(iprot, this);
    }

    public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException {
      schemes.get(oprot.getScheme()).getScheme().write(oprot, this);
      }

    @Override
    public String toString() {
      StringBuilder sb = new StringBuilder("registerApplicationModule_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("ire:");
      if (this.ire == null) {
        sb.append("null");
      } else {
        sb.append(this.ire);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("ace:");
      if (this.ace == null) {
        sb.append("null");
      } else {
        sb.append(this.ace);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("ase:");
      if (this.ase == null) {
        sb.append("null");
      } else {
        sb.append(this.ase);
      }
      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, 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 registerApplicationModule_resultStandardSchemeFactory implements SchemeFactory {
      public registerApplicationModule_resultStandardScheme getScheme() {
        return new registerApplicationModule_resultStandardScheme();
      }
    }

    private static class registerApplicationModule_resultStandardScheme extends StandardScheme<registerApplicationModule_result> {

      public void read(org.apache.thrift.protocol.TProtocol iprot, registerApplicationModule_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: // IRE
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.ire = new org.apache.airavata.model.error.InvalidRequestException();
                struct.ire.read(iprot);
                struct.setIreIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 2: // ACE
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.ace = new org.apache.airavata.model.error.AiravataClientException();
                struct.ace.read(iprot);
                struct.setAceIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 3: // ASE
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.ase = new org.apache.airavata.model.error.AiravataSystemException();
                struct.ase.read(iprot);
                struct.setAseIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 4: // 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, registerApplicationModule_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.ire != null) {
          oprot.writeFieldBegin(IRE_FIELD_DESC);
          struct.ire.write(oprot);
          oprot.writeFieldEnd();
        }
        if (struct.ace != null) {
          oprot.writeFieldBegin(ACE_FIELD_DESC);
          struct.ace.write(oprot);
          oprot.writeFieldEnd();
        }
        if (struct.ase != null) {
          oprot.writeFieldBegin(ASE_FIELD_DESC);
          struct.ase.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 registerApplicationModule_resultTupleSchemeFactory implements SchemeFactory {
      public registerApplicationModule_resultTupleScheme getScheme() {
        return new registerApplicationModule_resultTupleScheme();
      }
    }

    private static class registerApplicationModule_resultTupleScheme extends TupleScheme<registerApplicationModule_result> {

      @Override
      public void write(org.apache.thrift.protocol.TProtocol prot, registerApplicationModule_result struct) throws org.apache.thrift.TException {
        TTupleProtocol oprot = (TTupleProtocol) prot;
        BitSet optionals = new BitSet();
        if (struct.isSetSuccess()) {
          optionals.set(0);
        }
        if (struct.isSetIre()) {
          optionals.set(1);
        }
        if (struct.isSetAce()) {
          optionals.set(2);
        }
        if (struct.isSetAse()) {
          optionals.set(3);
        }
        if (struct.isSetAe()) {
          optionals.set(4);
        }
        oprot.writeBitSet(optionals, 5);
        if (struct.isSetSuccess()) {
          oprot.writeString(struct.success);
        }
        if (struct.isSetIre()) {
          struct.ire.write(oprot);
        }
        if (struct.isSetAce()) {
          struct.ace.write(oprot);
        }
        if (struct.isSetAse()) {
          struct.ase.write(oprot);
        }
        if (struct.isSetAe()) {
          struct.ae.write(oprot);
        }
      }

      @Override
      public void read(org.apache.thrift.protocol.TProtocol prot, registerApplicationModule_result struct) throws org.apache.thrift.TException {
        TTupleProtocol iprot = (TTupleProtocol) prot;
        BitSet incoming = iprot.readBitSet(5);
        if (incoming.get(0)) {
          struct.success = iprot.readString();
          struct.setSuccessIsSet(true);
        }
        if (incoming.get(1)) {
          struct.ire = new org.apache.airavata.model.error.InvalidRequestException();
          struct.ire.read(iprot);
          struct.setIreIsSet(true);
        }
        if (incoming.get(2)) {
          struct.ace = new org.apache.airavata.model.error.AiravataClientException();
          struct.ace.read(iprot);
          struct.setAceIsSet(true);
        }
        if (incoming.get(3)) {
          struct.ase = new org.apache.airavata.model.error.AiravataSystemException();
          struct.ase.read(iprot);
          struct.setAseIsSet(true);
        }
        if (incoming.get(4)) {
          struct.ae = new org.apache.airavata.model.error.AuthorizationException();
          struct.ae.read(iprot);
          struct.setAeIsSet(true);
        }
      }
    }

  }

  public static class getApplicationModule_args implements org.apache.thrift.TBase<getApplicationModule_args, getApplicationModule_args._Fields>, java.io.Serializable, Cloneable, Comparable<getApplicationModule_args>   {
    private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("getApplicationModule_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 APP_MODULE_ID_FIELD_DESC = new org.apache.thrift.protocol.TField("appModuleId", org.apache.thrift.protocol.TType.STRING, (short)2);

    private static final Map<Class<? extends IScheme>, SchemeFactory> schemes = new HashMap<Class<? extends IScheme>, SchemeFactory>();
    static {
      schemes.put(StandardScheme.class, new getApplicationModule_argsStandardSchemeFactory());
      schemes.put(TupleScheme.class, new getApplicationModule_argsTupleSchemeFactory());
    }

    public org.apache.airavata.model.security.AuthzToken authzToken; // required
    public String appModuleId; // required

    /** 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"),
      APP_MODULE_ID((short)2, "appModuleId");

      private static final Map<String, _Fields> byName = new HashMap<String, _Fields>();

      static {
        for (_Fields field : EnumSet.allOf(_Fields.class)) {
          byName.put(field.getFieldName(), field);
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, or null if its not found.
       */
      public static _Fields findByThriftId(int fieldId) {
        switch(fieldId) {
          case 1: // AUTHZ_TOKEN
            return AUTHZ_TOKEN;
          case 2: // APP_MODULE_ID
            return APP_MODULE_ID;
          default:
            return null;
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, throwing an exception
       * if it is not found.
       */
      public static _Fields findByThriftIdOrThrow(int fieldId) {
        _Fields fields = findByThriftId(fieldId);
        if (fields == null) throw new IllegalArgumentException("Field " + fieldId + " doesn't exist!");
        return fields;
      }

      /**
       * Find the _Fields constant that matches name, or null if its not found.
       */
      public static _Fields findByName(String name) {
        return byName.get(name);
      }

      private final short _thriftId;
      private final String _fieldName;

      _Fields(short thriftId, String fieldName) {
        _thriftId = thriftId;
        _fieldName = fieldName;
      }

      public short getThriftFieldId() {
        return _thriftId;
      }

      public String getFieldName() {
        return _fieldName;
      }
    }

    // isset id assignments
    public static final Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
    static {
      Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new EnumMap<_Fields, org.apache.thrift.meta_data.FieldMetaData>(_Fields.class);
      tmpMap.put(_Fields.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.APP_MODULE_ID, new org.apache.thrift.meta_data.FieldMetaData("appModuleId", org.apache.thrift.TFieldRequirementType.REQUIRED, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING)));
      metaDataMap = Collections.unmodifiableMap(tmpMap);
      org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(getApplicationModule_args.class, metaDataMap);
    }

    public getApplicationModule_args() {
    }

    public getApplicationModule_args(
      org.apache.airavata.model.security.AuthzToken authzToken,
      String appModuleId)
    {
      this();
      this.authzToken = authzToken;
      this.appModuleId = appModuleId;
    }

    /**
     * Performs a deep copy on <i>other</i>.
     */
    public getApplicationModule_args(getApplicationModule_args other) {
      if (other.isSetAuthzToken()) {
        this.authzToken = new org.apache.airavata.model.security.AuthzToken(other.authzToken);
      }
      if (other.isSetAppModuleId()) {
        this.appModuleId = other.appModuleId;
      }
    }

    public getApplicationModule_args deepCopy() {
      return new getApplicationModule_args(this);
    }

    @Override
    public void clear() {
      this.authzToken = null;
      this.appModuleId = null;
    }

    public org.apache.airavata.model.security.AuthzToken getAuthzToken() {
      return this.authzToken;
    }

    public getApplicationModule_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 String getAppModuleId() {
      return this.appModuleId;
    }

    public getApplicationModule_args setAppModuleId(String appModuleId) {
      this.appModuleId = appModuleId;
      return this;
    }

    public void unsetAppModuleId() {
      this.appModuleId = null;
    }

    /** Returns true if field appModuleId is set (has been assigned a value) and false otherwise */
    public boolean isSetAppModuleId() {
      return this.appModuleId != null;
    }

    public void setAppModuleIdIsSet(boolean value) {
      if (!value) {
        this.appModuleId = null;
      }
    }

    public void setFieldValue(_Fields field, Object value) {
      switch (field) {
      case AUTHZ_TOKEN:
        if (value == null) {
          unsetAuthzToken();
        } else {
          setAuthzToken((org.apache.airavata.model.security.AuthzToken)value);
        }
        break;

      case APP_MODULE_ID:
        if (value == null) {
          unsetAppModuleId();
        } else {
          setAppModuleId((String)value);
        }
        break;

      }
    }

    public Object getFieldValue(_Fields field) {
      switch (field) {
      case AUTHZ_TOKEN:
        return getAuthzToken();

      case APP_MODULE_ID:
        return getAppModuleId();

      }
      throw new IllegalStateException();
    }

    /** Returns true if field corresponding to fieldID is set (has been assigned a value) and false otherwise */
    public boolean isSet(_Fields field) {
      if (field == null) {
        throw new IllegalArgumentException();
      }

      switch (field) {
      case AUTHZ_TOKEN:
        return isSetAuthzToken();
      case APP_MODULE_ID:
        return isSetAppModuleId();
      }
      throw new IllegalStateException();
    }

    @Override
    public boolean equals(Object that) {
      if (that == null)
        return false;
      if (that instanceof getApplicationModule_args)
        return this.equals((getApplicationModule_args)that);
      return false;
    }

    public boolean equals(getApplicationModule_args that) {
      if (that == null)
        return false;

      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_appModuleId = true && this.isSetAppModuleId();
      boolean that_present_appModuleId = true && that.isSetAppModuleId();
      if (this_present_appModuleId || that_present_appModuleId) {
        if (!(this_present_appModuleId && that_present_appModuleId))
          return false;
        if (!this.appModuleId.equals(that.appModuleId))
          return false;
      }

      return true;
    }

    @Override
    public int hashCode() {
      List<Object> list = new ArrayList<Object>();

      boolean present_authzToken = true && (isSetAuthzToken());
      list.add(present_authzToken);
      if (present_authzToken)
        list.add(authzToken);

      boolean present_appModuleId = true && (isSetAppModuleId());
      list.add(present_appModuleId);
      if (present_appModuleId)
        list.add(appModuleId);

      return list.hashCode();
    }

    @Override
    public int compareTo(getApplicationModule_args other) {
      if (!getClass().equals(other.getClass())) {
        return getClass().getName().compareTo(other.getClass().getName());
      }

      int lastComparison = 0;

      lastComparison = 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 = Boolean.valueOf(isSetAppModuleId()).compareTo(other.isSetAppModuleId());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetAppModuleId()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.appModuleId, other.appModuleId);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      return 0;
    }

    public _Fields fieldForId(int fieldId) {
      return _Fields.findByThriftId(fieldId);
    }

    public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
      schemes.get(iprot.getScheme()).getScheme().read(iprot, this);
    }

    public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException {
      schemes.get(oprot.getScheme()).getScheme().write(oprot, this);
    }

    @Override
    public String toString() {
      StringBuilder sb = new StringBuilder("getApplicationModule_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("appModuleId:");
      if (this.appModuleId == null) {
        sb.append("null");
      } else {
        sb.append(this.appModuleId);
      }
      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 (appModuleId == null) {
        throw new org.apache.thrift.protocol.TProtocolException("Required field 'appModuleId' 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, 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 getApplicationModule_argsStandardSchemeFactory implements SchemeFactory {
      public getApplicationModule_argsStandardScheme getScheme() {
        return new getApplicationModule_argsStandardScheme();
      }
    }

    private static class getApplicationModule_argsStandardScheme extends StandardScheme<getApplicationModule_args> {

      public void read(org.apache.thrift.protocol.TProtocol iprot, getApplicationModule_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: // APP_MODULE_ID
              if (schemeField.type == org.apache.thrift.protocol.TType.STRING) {
                struct.appModuleId = iprot.readString();
                struct.setAppModuleIdIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            default:
              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
          }
          iprot.readFieldEnd();
        }
        iprot.readStructEnd();

        // check for required fields of primitive type, which can't be checked in the validate method
        struct.validate();
      }

      public void write(org.apache.thrift.protocol.TProtocol oprot, getApplicationModule_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.appModuleId != null) {
          oprot.writeFieldBegin(APP_MODULE_ID_FIELD_DESC);
          oprot.writeString(struct.appModuleId);
          oprot.writeFieldEnd();
        }
        oprot.writeFieldStop();
        oprot.writeStructEnd();
      }

    }

    private static class getApplicationModule_argsTupleSchemeFactory implements SchemeFactory {
      public getApplicationModule_argsTupleScheme getScheme() {
        return new getApplicationModule_argsTupleScheme();
      }
    }

    private static class getApplicationModule_argsTupleScheme extends TupleScheme<getApplicationModule_args> {

      @Override
      public void write(org.apache.thrift.protocol.TProtocol prot, getApplicationModule_args struct) throws org.apache.thrift.TException {
        TTupleProtocol oprot = (TTupleProtocol) prot;
        struct.authzToken.write(oprot);
        oprot.writeString(struct.appModuleId);
      }

      @Override
      public void read(org.apache.thrift.protocol.TProtocol prot, getApplicationModule_args struct) throws org.apache.thrift.TException {
        TTupleProtocol iprot = (TTupleProtocol) prot;
        struct.authzToken = new org.apache.airavata.model.security.AuthzToken();
        struct.authzToken.read(iprot);
        struct.setAuthzTokenIsSet(true);
        struct.appModuleId = iprot.readString();
        struct.setAppModuleIdIsSet(true);
      }
    }

  }

  public static class getApplicationModule_result implements org.apache.thrift.TBase<getApplicationModule_result, getApplicationModule_result._Fields>, java.io.Serializable, Cloneable, Comparable<getApplicationModule_result>   {
    private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("getApplicationModule_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 IRE_FIELD_DESC = new org.apache.thrift.protocol.TField("ire", org.apache.thrift.protocol.TType.STRUCT, (short)1);
    private static final org.apache.thrift.protocol.TField ACE_FIELD_DESC = new org.apache.thrift.protocol.TField("ace", org.apache.thrift.protocol.TType.STRUCT, (short)2);
    private static final org.apache.thrift.protocol.TField ASE_FIELD_DESC = new org.apache.thrift.protocol.TField("ase", org.apache.thrift.protocol.TType.STRUCT, (short)3);
    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)4);

    private static final Map<Class<? extends IScheme>, SchemeFactory> schemes = new HashMap<Class<? extends IScheme>, SchemeFactory>();
    static {
      schemes.put(StandardScheme.class, new getApplicationModule_resultStandardSchemeFactory());
      schemes.put(TupleScheme.class, new getApplicationModule_resultTupleSchemeFactory());
    }

    public org.apache.airavata.model.appcatalog.appdeployment.ApplicationModule success; // required
    public org.apache.airavata.model.error.InvalidRequestException ire; // required
    public org.apache.airavata.model.error.AiravataClientException ace; // required
    public org.apache.airavata.model.error.AiravataSystemException ase; // 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"),
      IRE((short)1, "ire"),
      ACE((short)2, "ace"),
      ASE((short)3, "ase"),
      AE((short)4, "ae");

      private static final Map<String, _Fields> byName = new HashMap<String, _Fields>();

      static {
        for (_Fields field : EnumSet.allOf(_Fields.class)) {
          byName.put(field.getFieldName(), field);
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, or null if its not found.
       */
      public static _Fields findByThriftId(int fieldId) {
        switch(fieldId) {
          case 0: // SUCCESS
            return SUCCESS;
          case 1: // IRE
            return IRE;
          case 2: // ACE
            return ACE;
          case 3: // ASE
            return ASE;
          case 4: // 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 IllegalArgumentException("Field " + fieldId + " doesn't exist!");
        return fields;
      }

      /**
       * Find the _Fields constant that matches name, or null if its not found.
       */
      public static _Fields findByName(String name) {
        return byName.get(name);
      }

      private final short _thriftId;
      private final String _fieldName;

      _Fields(short thriftId, String fieldName) {
        _thriftId = thriftId;
        _fieldName = fieldName;
      }

      public short getThriftFieldId() {
        return _thriftId;
      }

      public String getFieldName() {
        return _fieldName;
      }
    }

    // isset id assignments
    public static final Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
    static {
      Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new EnumMap<_Fields, org.apache.thrift.meta_data.FieldMetaData>(_Fields.class);
      tmpMap.put(_Fields.SUCCESS, new org.apache.thrift.meta_data.FieldMetaData("success", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.StructMetaData(org.apache.thrift.protocol.TType.STRUCT, org.apache.airavata.model.appcatalog.appdeployment.ApplicationModule.class)));
      tmpMap.put(_Fields.IRE, new org.apache.thrift.meta_data.FieldMetaData("ire", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRUCT)));
      tmpMap.put(_Fields.ACE, new org.apache.thrift.meta_data.FieldMetaData("ace", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRUCT)));
      tmpMap.put(_Fields.ASE, new org.apache.thrift.meta_data.FieldMetaData("ase", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRUCT)));
      tmpMap.put(_Fields.AE, new org.apache.thrift.meta_data.FieldMetaData("ae", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRUCT)));
      metaDataMap = Collections.unmodifiableMap(tmpMap);
      org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(getApplicationModule_result.class, metaDataMap);
    }

    public getApplicationModule_result() {
    }

    public getApplicationModule_result(
      org.apache.airavata.model.appcatalog.appdeployment.ApplicationModule success,
      org.apache.airavata.model.error.InvalidRequestException ire,
      org.apache.airavata.model.error.AiravataClientException ace,
      org.apache.airavata.model.error.AiravataSystemException ase,
      org.apache.airavata.model.error.AuthorizationException ae)
    {
      this();
      this.success = success;
      this.ire = ire;
      this.ace = ace;
      this.ase = ase;
      this.ae = ae;
    }

    /**
     * Performs a deep copy on <i>other</i>.
     */
    public getApplicationModule_result(getApplicationModule_result other) {
      if (other.isSetSuccess()) {
        this.success = new org.apache.airavata.model.appcatalog.appdeployment.ApplicationModule(other.success);
      }
      if (other.isSetIre()) {
        this.ire = new org.apache.airavata.model.error.InvalidRequestException(other.ire);
      }
      if (other.isSetAce()) {
        this.ace = new org.apache.airavata.model.error.AiravataClientException(other.ace);
      }
      if (other.isSetAse()) {
        this.ase = new org.apache.airavata.model.error.AiravataSystemException(other.ase);
      }
      if (other.isSetAe()) {
        this.ae = new org.apache.airavata.model.error.AuthorizationException(other.ae);
      }
    }

    public getApplicationModule_result deepCopy() {
      return new getApplicationModule_result(this);
    }

    @Override
    public void clear() {
      this.success = null;
      this.ire = null;
      this.ace = null;
      this.ase = null;
      this.ae = null;
    }

    public org.apache.airavata.model.appcatalog.appdeployment.ApplicationModule getSuccess() {
      return this.success;
    }

    public getApplicationModule_result setSuccess(org.apache.airavata.model.appcatalog.appdeployment.ApplicationModule 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.model.error.InvalidRequestException getIre() {
      return this.ire;
    }

    public getApplicationModule_result setIre(org.apache.airavata.model.error.InvalidRequestException ire) {
      this.ire = ire;
      return this;
    }

    public void unsetIre() {
      this.ire = null;
    }

    /** Returns true if field ire is set (has been assigned a value) and false otherwise */
    public boolean isSetIre() {
      return this.ire != null;
    }

    public void setIreIsSet(boolean value) {
      if (!value) {
        this.ire = null;
      }
    }

    public org.apache.airavata.model.error.AiravataClientException getAce() {
      return this.ace;
    }

    public getApplicationModule_result setAce(org.apache.airavata.model.error.AiravataClientException ace) {
      this.ace = ace;
      return this;
    }

    public void unsetAce() {
      this.ace = null;
    }

    /** Returns true if field ace is set (has been assigned a value) and false otherwise */
    public boolean isSetAce() {
      return this.ace != null;
    }

    public void setAceIsSet(boolean value) {
      if (!value) {
        this.ace = null;
      }
    }

    public org.apache.airavata.model.error.AiravataSystemException getAse() {
      return this.ase;
    }

    public getApplicationModule_result setAse(org.apache.airavata.model.error.AiravataSystemException ase) {
      this.ase = ase;
      return this;
    }

    public void unsetAse() {
      this.ase = null;
    }

    /** Returns true if field ase is set (has been assigned a value) and false otherwise */
    public boolean isSetAse() {
      return this.ase != null;
    }

    public void setAseIsSet(boolean value) {
      if (!value) {
        this.ase = null;
      }
    }

    public org.apache.airavata.model.error.AuthorizationException getAe() {
      return this.ae;
    }

    public getApplicationModule_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, Object value) {
      switch (field) {
      case SUCCESS:
        if (value == null) {
          unsetSuccess();
        } else {
          setSuccess((org.apache.airavata.model.appcatalog.appdeployment.ApplicationModule)value);
        }
        break;

      case IRE:
        if (value == null) {
          unsetIre();
        } else {
          setIre((org.apache.airavata.model.error.InvalidRequestException)value);
        }
        break;

      case ACE:
        if (value == null) {
          unsetAce();
        } else {
          setAce((org.apache.airavata.model.error.AiravataClientException)value);
        }
        break;

      case ASE:
        if (value == null) {
          unsetAse();
        } else {
          setAse((org.apache.airavata.model.error.AiravataSystemException)value);
        }
        break;

      case AE:
        if (value == null) {
          unsetAe();
        } else {
          setAe((org.apache.airavata.model.error.AuthorizationException)value);
        }
        break;

      }
    }

    public Object getFieldValue(_Fields field) {
      switch (field) {
      case SUCCESS:
        return getSuccess();

      case IRE:
        return getIre();

      case ACE:
        return getAce();

      case ASE:
        return getAse();

      case AE:
        return getAe();

      }
      throw new IllegalStateException();
    }

    /** Returns true if field corresponding to fieldID is set (has been assigned a value) and false otherwise */
    public boolean isSet(_Fields field) {
      if (field == null) {
        throw new IllegalArgumentException();
      }

      switch (field) {
      case SUCCESS:
        return isSetSuccess();
      case IRE:
        return isSetIre();
      case ACE:
        return isSetAce();
      case ASE:
        return isSetAse();
      case AE:
        return isSetAe();
      }
      throw new IllegalStateException();
    }

    @Override
    public boolean equals(Object that) {
      if (that == null)
        return false;
      if (that instanceof getApplicationModule_result)
        return this.equals((getApplicationModule_result)that);
      return false;
    }

    public boolean equals(getApplicationModule_result that) {
      if (that == null)
        return false;

      boolean this_present_success = true && this.isSetSuccess();
      boolean that_present_success = true && that.isSetSuccess();
      if (this_present_success || that_present_success) {
        if (!(this_present_success && that_present_success))
          return false;
        if (!this.success.equals(that.success))
          return false;
      }

      boolean this_present_ire = true && this.isSetIre();
      boolean that_present_ire = true && that.isSetIre();
      if (this_present_ire || that_present_ire) {
        if (!(this_present_ire && that_present_ire))
          return false;
        if (!this.ire.equals(that.ire))
          return false;
      }

      boolean this_present_ace = true && this.isSetAce();
      boolean that_present_ace = true && that.isSetAce();
      if (this_present_ace || that_present_ace) {
        if (!(this_present_ace && that_present_ace))
          return false;
        if (!this.ace.equals(that.ace))
          return false;
      }

      boolean this_present_ase = true && this.isSetAse();
      boolean that_present_ase = true && that.isSetAse();
      if (this_present_ase || that_present_ase) {
        if (!(this_present_ase && that_present_ase))
          return false;
        if (!this.ase.equals(that.ase))
          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() {
      List<Object> list = new ArrayList<Object>();

      boolean present_success = true && (isSetSuccess());
      list.add(present_success);
      if (present_success)
        list.add(success);

      boolean present_ire = true && (isSetIre());
      list.add(present_ire);
      if (present_ire)
        list.add(ire);

      boolean present_ace = true && (isSetAce());
      list.add(present_ace);
      if (present_ace)
        list.add(ace);

      boolean present_ase = true && (isSetAse());
      list.add(present_ase);
      if (present_ase)
        list.add(ase);

      boolean present_ae = true && (isSetAe());
      list.add(present_ae);
      if (present_ae)
        list.add(ae);

      return list.hashCode();
    }

    @Override
    public int compareTo(getApplicationModule_result other) {
      if (!getClass().equals(other.getClass())) {
        return getClass().getName().compareTo(other.getClass().getName());
      }

      int lastComparison = 0;

      lastComparison = Boolean.valueOf(isSetSuccess()).compareTo(other.isSetSuccess());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetSuccess()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.success, other.success);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = Boolean.valueOf(isSetIre()).compareTo(other.isSetIre());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetIre()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.ire, other.ire);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = Boolean.valueOf(isSetAce()).compareTo(other.isSetAce());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetAce()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.ace, other.ace);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = Boolean.valueOf(isSetAse()).compareTo(other.isSetAse());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetAse()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.ase, other.ase);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = 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 {
      schemes.get(iprot.getScheme()).getScheme().read(iprot, this);
    }

    public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException {
      schemes.get(oprot.getScheme()).getScheme().write(oprot, this);
      }

    @Override
    public String toString() {
      StringBuilder sb = new StringBuilder("getApplicationModule_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("ire:");
      if (this.ire == null) {
        sb.append("null");
      } else {
        sb.append(this.ire);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("ace:");
      if (this.ace == null) {
        sb.append("null");
      } else {
        sb.append(this.ace);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("ase:");
      if (this.ase == null) {
        sb.append("null");
      } else {
        sb.append(this.ase);
      }
      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, 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 getApplicationModule_resultStandardSchemeFactory implements SchemeFactory {
      public getApplicationModule_resultStandardScheme getScheme() {
        return new getApplicationModule_resultStandardScheme();
      }
    }

    private static class getApplicationModule_resultStandardScheme extends StandardScheme<getApplicationModule_result> {

      public void read(org.apache.thrift.protocol.TProtocol iprot, getApplicationModule_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.appcatalog.appdeployment.ApplicationModule();
                struct.success.read(iprot);
                struct.setSuccessIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 1: // IRE
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.ire = new org.apache.airavata.model.error.InvalidRequestException();
                struct.ire.read(iprot);
                struct.setIreIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 2: // ACE
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.ace = new org.apache.airavata.model.error.AiravataClientException();
                struct.ace.read(iprot);
                struct.setAceIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 3: // ASE
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.ase = new org.apache.airavata.model.error.AiravataSystemException();
                struct.ase.read(iprot);
                struct.setAseIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 4: // 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, getApplicationModule_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.ire != null) {
          oprot.writeFieldBegin(IRE_FIELD_DESC);
          struct.ire.write(oprot);
          oprot.writeFieldEnd();
        }
        if (struct.ace != null) {
          oprot.writeFieldBegin(ACE_FIELD_DESC);
          struct.ace.write(oprot);
          oprot.writeFieldEnd();
        }
        if (struct.ase != null) {
          oprot.writeFieldBegin(ASE_FIELD_DESC);
          struct.ase.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 getApplicationModule_resultTupleSchemeFactory implements SchemeFactory {
      public getApplicationModule_resultTupleScheme getScheme() {
        return new getApplicationModule_resultTupleScheme();
      }
    }

    private static class getApplicationModule_resultTupleScheme extends TupleScheme<getApplicationModule_result> {

      @Override
      public void write(org.apache.thrift.protocol.TProtocol prot, getApplicationModule_result struct) throws org.apache.thrift.TException {
        TTupleProtocol oprot = (TTupleProtocol) prot;
        BitSet optionals = new BitSet();
        if (struct.isSetSuccess()) {
          optionals.set(0);
        }
        if (struct.isSetIre()) {
          optionals.set(1);
        }
        if (struct.isSetAce()) {
          optionals.set(2);
        }
        if (struct.isSetAse()) {
          optionals.set(3);
        }
        if (struct.isSetAe()) {
          optionals.set(4);
        }
        oprot.writeBitSet(optionals, 5);
        if (struct.isSetSuccess()) {
          struct.success.write(oprot);
        }
        if (struct.isSetIre()) {
          struct.ire.write(oprot);
        }
        if (struct.isSetAce()) {
          struct.ace.write(oprot);
        }
        if (struct.isSetAse()) {
          struct.ase.write(oprot);
        }
        if (struct.isSetAe()) {
          struct.ae.write(oprot);
        }
      }

      @Override
      public void read(org.apache.thrift.protocol.TProtocol prot, getApplicationModule_result struct) throws org.apache.thrift.TException {
        TTupleProtocol iprot = (TTupleProtocol) prot;
        BitSet incoming = iprot.readBitSet(5);
        if (incoming.get(0)) {
          struct.success = new org.apache.airavata.model.appcatalog.appdeployment.ApplicationModule();
          struct.success.read(iprot);
          struct.setSuccessIsSet(true);
        }
        if (incoming.get(1)) {
          struct.ire = new org.apache.airavata.model.error.InvalidRequestException();
          struct.ire.read(iprot);
          struct.setIreIsSet(true);
        }
        if (incoming.get(2)) {
          struct.ace = new org.apache.airavata.model.error.AiravataClientException();
          struct.ace.read(iprot);
          struct.setAceIsSet(true);
        }
        if (incoming.get(3)) {
          struct.ase = new org.apache.airavata.model.error.AiravataSystemException();
          struct.ase.read(iprot);
          struct.setAseIsSet(true);
        }
        if (incoming.get(4)) {
          struct.ae = new org.apache.airavata.model.error.AuthorizationException();
          struct.ae.read(iprot);
          struct.setAeIsSet(true);
        }
      }
    }

  }

  public static class updateApplicationModule_args implements org.apache.thrift.TBase<updateApplicationModule_args, updateApplicationModule_args._Fields>, java.io.Serializable, Cloneable, Comparable<updateApplicationModule_args>   {
    private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("updateApplicationModule_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 APP_MODULE_ID_FIELD_DESC = new org.apache.thrift.protocol.TField("appModuleId", org.apache.thrift.protocol.TType.STRING, (short)2);
    private static final org.apache.thrift.protocol.TField APPLICATION_MODULE_FIELD_DESC = new org.apache.thrift.protocol.TField("applicationModule", org.apache.thrift.protocol.TType.STRUCT, (short)3);

    private static final Map<Class<? extends IScheme>, SchemeFactory> schemes = new HashMap<Class<? extends IScheme>, SchemeFactory>();
    static {
      schemes.put(StandardScheme.class, new updateApplicationModule_argsStandardSchemeFactory());
      schemes.put(TupleScheme.class, new updateApplicationModule_argsTupleSchemeFactory());
    }

    public org.apache.airavata.model.security.AuthzToken authzToken; // required
    public String appModuleId; // required
    public org.apache.airavata.model.appcatalog.appdeployment.ApplicationModule applicationModule; // required

    /** 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"),
      APP_MODULE_ID((short)2, "appModuleId"),
      APPLICATION_MODULE((short)3, "applicationModule");

      private static final Map<String, _Fields> byName = new HashMap<String, _Fields>();

      static {
        for (_Fields field : EnumSet.allOf(_Fields.class)) {
          byName.put(field.getFieldName(), field);
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, or null if its not found.
       */
      public static _Fields findByThriftId(int fieldId) {
        switch(fieldId) {
          case 1: // AUTHZ_TOKEN
            return AUTHZ_TOKEN;
          case 2: // APP_MODULE_ID
            return APP_MODULE_ID;
          case 3: // APPLICATION_MODULE
            return APPLICATION_MODULE;
          default:
            return null;
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, throwing an exception
       * if it is not found.
       */
      public static _Fields findByThriftIdOrThrow(int fieldId) {
        _Fields fields = findByThriftId(fieldId);
        if (fields == null) throw new IllegalArgumentException("Field " + fieldId + " doesn't exist!");
        return fields;
      }

      /**
       * Find the _Fields constant that matches name, or null if its not found.
       */
      public static _Fields findByName(String name) {
        return byName.get(name);
      }

      private final short _thriftId;
      private final String _fieldName;

      _Fields(short thriftId, String fieldName) {
        _thriftId = thriftId;
        _fieldName = fieldName;
      }

      public short getThriftFieldId() {
        return _thriftId;
      }

      public String getFieldName() {
        return _fieldName;
      }
    }

    // isset id assignments
    public static final Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
    static {
      Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new EnumMap<_Fields, org.apache.thrift.meta_data.FieldMetaData>(_Fields.class);
      tmpMap.put(_Fields.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.APP_MODULE_ID, new org.apache.thrift.meta_data.FieldMetaData("appModuleId", org.apache.thrift.TFieldRequirementType.REQUIRED, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING)));
      tmpMap.put(_Fields.APPLICATION_MODULE, new org.apache.thrift.meta_data.FieldMetaData("applicationModule", org.apache.thrift.TFieldRequirementType.REQUIRED, 
          new org.apache.thrift.meta_data.StructMetaData(org.apache.thrift.protocol.TType.STRUCT, org.apache.airavata.model.appcatalog.appdeployment.ApplicationModule.class)));
      metaDataMap = Collections.unmodifiableMap(tmpMap);
      org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(updateApplicationModule_args.class, metaDataMap);
    }

    public updateApplicationModule_args() {
    }

    public updateApplicationModule_args(
      org.apache.airavata.model.security.AuthzToken authzToken,
      String appModuleId,
      org.apache.airavata.model.appcatalog.appdeployment.ApplicationModule applicationModule)
    {
      this();
      this.authzToken = authzToken;
      this.appModuleId = appModuleId;
      this.applicationModule = applicationModule;
    }

    /**
     * Performs a deep copy on <i>other</i>.
     */
    public updateApplicationModule_args(updateApplicationModule_args other) {
      if (other.isSetAuthzToken()) {
        this.authzToken = new org.apache.airavata.model.security.AuthzToken(other.authzToken);
      }
      if (other.isSetAppModuleId()) {
        this.appModuleId = other.appModuleId;
      }
      if (other.isSetApplicationModule()) {
        this.applicationModule = new org.apache.airavata.model.appcatalog.appdeployment.ApplicationModule(other.applicationModule);
      }
    }

    public updateApplicationModule_args deepCopy() {
      return new updateApplicationModule_args(this);
    }

    @Override
    public void clear() {
      this.authzToken = null;
      this.appModuleId = null;
      this.applicationModule = null;
    }

    public org.apache.airavata.model.security.AuthzToken getAuthzToken() {
      return this.authzToken;
    }

    public updateApplicationModule_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 String getAppModuleId() {
      return this.appModuleId;
    }

    public updateApplicationModule_args setAppModuleId(String appModuleId) {
      this.appModuleId = appModuleId;
      return this;
    }

    public void unsetAppModuleId() {
      this.appModuleId = null;
    }

    /** Returns true if field appModuleId is set (has been assigned a value) and false otherwise */
    public boolean isSetAppModuleId() {
      return this.appModuleId != null;
    }

    public void setAppModuleIdIsSet(boolean value) {
      if (!value) {
        this.appModuleId = null;
      }
    }

    public org.apache.airavata.model.appcatalog.appdeployment.ApplicationModule getApplicationModule() {
      return this.applicationModule;
    }

    public updateApplicationModule_args setApplicationModule(org.apache.airavata.model.appcatalog.appdeployment.ApplicationModule applicationModule) {
      this.applicationModule = applicationModule;
      return this;
    }

    public void unsetApplicationModule() {
      this.applicationModule = null;
    }

    /** Returns true if field applicationModule is set (has been assigned a value) and false otherwise */
    public boolean isSetApplicationModule() {
      return this.applicationModule != null;
    }

    public void setApplicationModuleIsSet(boolean value) {
      if (!value) {
        this.applicationModule = null;
      }
    }

    public void setFieldValue(_Fields field, Object value) {
      switch (field) {
      case AUTHZ_TOKEN:
        if (value == null) {
          unsetAuthzToken();
        } else {
          setAuthzToken((org.apache.airavata.model.security.AuthzToken)value);
        }
        break;

      case APP_MODULE_ID:
        if (value == null) {
          unsetAppModuleId();
        } else {
          setAppModuleId((String)value);
        }
        break;

      case APPLICATION_MODULE:
        if (value == null) {
          unsetApplicationModule();
        } else {
          setApplicationModule((org.apache.airavata.model.appcatalog.appdeployment.ApplicationModule)value);
        }
        break;

      }
    }

    public Object getFieldValue(_Fields field) {
      switch (field) {
      case AUTHZ_TOKEN:
        return getAuthzToken();

      case APP_MODULE_ID:
        return getAppModuleId();

      case APPLICATION_MODULE:
        return getApplicationModule();

      }
      throw new IllegalStateException();
    }

    /** Returns true if field corresponding to fieldID is set (has been assigned a value) and false otherwise */
    public boolean isSet(_Fields field) {
      if (field == null) {
        throw new IllegalArgumentException();
      }

      switch (field) {
      case AUTHZ_TOKEN:
        return isSetAuthzToken();
      case APP_MODULE_ID:
        return isSetAppModuleId();
      case APPLICATION_MODULE:
        return isSetApplicationModule();
      }
      throw new IllegalStateException();
    }

    @Override
    public boolean equals(Object that) {
      if (that == null)
        return false;
      if (that instanceof updateApplicationModule_args)
        return this.equals((updateApplicationModule_args)that);
      return false;
    }

    public boolean equals(updateApplicationModule_args that) {
      if (that == null)
        return false;

      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_appModuleId = true && this.isSetAppModuleId();
      boolean that_present_appModuleId = true && that.isSetAppModuleId();
      if (this_present_appModuleId || that_present_appModuleId) {
        if (!(this_present_appModuleId && that_present_appModuleId))
          return false;
        if (!this.appModuleId.equals(that.appModuleId))
          return false;
      }

      boolean this_present_applicationModule = true && this.isSetApplicationModule();
      boolean that_present_applicationModule = true && that.isSetApplicationModule();
      if (this_present_applicationModule || that_present_applicationModule) {
        if (!(this_present_applicationModule && that_present_applicationModule))
          return false;
        if (!this.applicationModule.equals(that.applicationModule))
          return false;
      }

      return true;
    }

    @Override
    public int hashCode() {
      List<Object> list = new ArrayList<Object>();

      boolean present_authzToken = true && (isSetAuthzToken());
      list.add(present_authzToken);
      if (present_authzToken)
        list.add(authzToken);

      boolean present_appModuleId = true && (isSetAppModuleId());
      list.add(present_appModuleId);
      if (present_appModuleId)
        list.add(appModuleId);

      boolean present_applicationModule = true && (isSetApplicationModule());
      list.add(present_applicationModule);
      if (present_applicationModule)
        list.add(applicationModule);

      return list.hashCode();
    }

    @Override
    public int compareTo(updateApplicationModule_args other) {
      if (!getClass().equals(other.getClass())) {
        return getClass().getName().compareTo(other.getClass().getName());
      }

      int lastComparison = 0;

      lastComparison = 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 = Boolean.valueOf(isSetAppModuleId()).compareTo(other.isSetAppModuleId());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetAppModuleId()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.appModuleId, other.appModuleId);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = Boolean.valueOf(isSetApplicationModule()).compareTo(other.isSetApplicationModule());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetApplicationModule()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.applicationModule, other.applicationModule);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      return 0;
    }

    public _Fields fieldForId(int fieldId) {
      return _Fields.findByThriftId(fieldId);
    }

    public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
      schemes.get(iprot.getScheme()).getScheme().read(iprot, this);
    }

    public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException {
      schemes.get(oprot.getScheme()).getScheme().write(oprot, this);
    }

    @Override
    public String toString() {
      StringBuilder sb = new StringBuilder("updateApplicationModule_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("appModuleId:");
      if (this.appModuleId == null) {
        sb.append("null");
      } else {
        sb.append(this.appModuleId);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("applicationModule:");
      if (this.applicationModule == null) {
        sb.append("null");
      } else {
        sb.append(this.applicationModule);
      }
      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 (appModuleId == null) {
        throw new org.apache.thrift.protocol.TProtocolException("Required field 'appModuleId' was not present! Struct: " + toString());
      }
      if (applicationModule == null) {
        throw new org.apache.thrift.protocol.TProtocolException("Required field 'applicationModule' was not present! Struct: " + toString());
      }
      // check for sub-struct validity
      if (authzToken != null) {
        authzToken.validate();
      }
      if (applicationModule != null) {
        applicationModule.validate();
      }
    }

    private void writeObject(java.io.ObjectOutputStream out) throws java.io.IOException {
      try {
        write(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(out)));
      } catch (org.apache.thrift.TException te) {
        throw new java.io.IOException(te);
      }
    }

    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, ClassNotFoundException {
      try {
        read(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(in)));
      } catch (org.apache.thrift.TException te) {
        throw new java.io.IOException(te);
      }
    }

    private static class updateApplicationModule_argsStandardSchemeFactory implements SchemeFactory {
      public updateApplicationModule_argsStandardScheme getScheme() {
        return new updateApplicationModule_argsStandardScheme();
      }
    }

    private static class updateApplicationModule_argsStandardScheme extends StandardScheme<updateApplicationModule_args> {

      public void read(org.apache.thrift.protocol.TProtocol iprot, updateApplicationModule_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: // APP_MODULE_ID
              if (schemeField.type == org.apache.thrift.protocol.TType.STRING) {
                struct.appModuleId = iprot.readString();
                struct.setAppModuleIdIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 3: // APPLICATION_MODULE
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.applicationModule = new org.apache.airavata.model.appcatalog.appdeployment.ApplicationModule();
                struct.applicationModule.read(iprot);
                struct.setApplicationModuleIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            default:
              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
          }
          iprot.readFieldEnd();
        }
        iprot.readStructEnd();

        // check for required fields of primitive type, which can't be checked in the validate method
        struct.validate();
      }

      public void write(org.apache.thrift.protocol.TProtocol oprot, updateApplicationModule_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.appModuleId != null) {
          oprot.writeFieldBegin(APP_MODULE_ID_FIELD_DESC);
          oprot.writeString(struct.appModuleId);
          oprot.writeFieldEnd();
        }
        if (struct.applicationModule != null) {
          oprot.writeFieldBegin(APPLICATION_MODULE_FIELD_DESC);
          struct.applicationModule.write(oprot);
          oprot.writeFieldEnd();
        }
        oprot.writeFieldStop();
        oprot.writeStructEnd();
      }

    }

    private static class updateApplicationModule_argsTupleSchemeFactory implements SchemeFactory {
      public updateApplicationModule_argsTupleScheme getScheme() {
        return new updateApplicationModule_argsTupleScheme();
      }
    }

    private static class updateApplicationModule_argsTupleScheme extends TupleScheme<updateApplicationModule_args> {

      @Override
      public void write(org.apache.thrift.protocol.TProtocol prot, updateApplicationModule_args struct) throws org.apache.thrift.TException {
        TTupleProtocol oprot = (TTupleProtocol) prot;
        struct.authzToken.write(oprot);
        oprot.writeString(struct.appModuleId);
        struct.applicationModule.write(oprot);
      }

      @Override
      public void read(org.apache.thrift.protocol.TProtocol prot, updateApplicationModule_args struct) throws org.apache.thrift.TException {
        TTupleProtocol iprot = (TTupleProtocol) prot;
        struct.authzToken = new org.apache.airavata.model.security.AuthzToken();
        struct.authzToken.read(iprot);
        struct.setAuthzTokenIsSet(true);
        struct.appModuleId = iprot.readString();
        struct.setAppModuleIdIsSet(true);
        struct.applicationModule = new org.apache.airavata.model.appcatalog.appdeployment.ApplicationModule();
        struct.applicationModule.read(iprot);
        struct.setApplicationModuleIsSet(true);
      }
    }

  }

  public static class updateApplicationModule_result implements org.apache.thrift.TBase<updateApplicationModule_result, updateApplicationModule_result._Fields>, java.io.Serializable, Cloneable, Comparable<updateApplicationModule_result>   {
    private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("updateApplicationModule_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 IRE_FIELD_DESC = new org.apache.thrift.protocol.TField("ire", org.apache.thrift.protocol.TType.STRUCT, (short)1);
    private static final org.apache.thrift.protocol.TField ACE_FIELD_DESC = new org.apache.thrift.protocol.TField("ace", org.apache.thrift.protocol.TType.STRUCT, (short)2);
    private static final org.apache.thrift.protocol.TField ASE_FIELD_DESC = new org.apache.thrift.protocol.TField("ase", org.apache.thrift.protocol.TType.STRUCT, (short)3);
    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)4);

    private static final Map<Class<? extends IScheme>, SchemeFactory> schemes = new HashMap<Class<? extends IScheme>, SchemeFactory>();
    static {
      schemes.put(StandardScheme.class, new updateApplicationModule_resultStandardSchemeFactory());
      schemes.put(TupleScheme.class, new updateApplicationModule_resultTupleSchemeFactory());
    }

    public boolean success; // required
    public org.apache.airavata.model.error.InvalidRequestException ire; // required
    public org.apache.airavata.model.error.AiravataClientException ace; // required
    public org.apache.airavata.model.error.AiravataSystemException ase; // 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"),
      IRE((short)1, "ire"),
      ACE((short)2, "ace"),
      ASE((short)3, "ase"),
      AE((short)4, "ae");

      private static final Map<String, _Fields> byName = new HashMap<String, _Fields>();

      static {
        for (_Fields field : EnumSet.allOf(_Fields.class)) {
          byName.put(field.getFieldName(), field);
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, or null if its not found.
       */
      public static _Fields findByThriftId(int fieldId) {
        switch(fieldId) {
          case 0: // SUCCESS
            return SUCCESS;
          case 1: // IRE
            return IRE;
          case 2: // ACE
            return ACE;
          case 3: // ASE
            return ASE;
          case 4: // 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 IllegalArgumentException("Field " + fieldId + " doesn't exist!");
        return fields;
      }

      /**
       * Find the _Fields constant that matches name, or null if its not found.
       */
      public static _Fields findByName(String name) {
        return byName.get(name);
      }

      private final short _thriftId;
      private final String _fieldName;

      _Fields(short thriftId, String fieldName) {
        _thriftId = thriftId;
        _fieldName = fieldName;
      }

      public short getThriftFieldId() {
        return _thriftId;
      }

      public String getFieldName() {
        return _fieldName;
      }
    }

    // isset id assignments
    private static final int __SUCCESS_ISSET_ID = 0;
    private byte __isset_bitfield = 0;
    public static final Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
    static {
      Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new EnumMap<_Fields, org.apache.thrift.meta_data.FieldMetaData>(_Fields.class);
      tmpMap.put(_Fields.SUCCESS, new org.apache.thrift.meta_data.FieldMetaData("success", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.BOOL)));
      tmpMap.put(_Fields.IRE, new org.apache.thrift.meta_data.FieldMetaData("ire", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRUCT)));
      tmpMap.put(_Fields.ACE, new org.apache.thrift.meta_data.FieldMetaData("ace", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRUCT)));
      tmpMap.put(_Fields.ASE, new org.apache.thrift.meta_data.FieldMetaData("ase", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRUCT)));
      tmpMap.put(_Fields.AE, new org.apache.thrift.meta_data.FieldMetaData("ae", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRUCT)));
      metaDataMap = Collections.unmodifiableMap(tmpMap);
      org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(updateApplicationModule_result.class, metaDataMap);
    }

    public updateApplicationModule_result() {
    }

    public updateApplicationModule_result(
      boolean success,
      org.apache.airavata.model.error.InvalidRequestException ire,
      org.apache.airavata.model.error.AiravataClientException ace,
      org.apache.airavata.model.error.AiravataSystemException ase,
      org.apache.airavata.model.error.AuthorizationException ae)
    {
      this();
      this.success = success;
      setSuccessIsSet(true);
      this.ire = ire;
      this.ace = ace;
      this.ase = ase;
      this.ae = ae;
    }

    /**
     * Performs a deep copy on <i>other</i>.
     */
    public updateApplicationModule_result(updateApplicationModule_result other) {
      __isset_bitfield = other.__isset_bitfield;
      this.success = other.success;
      if (other.isSetIre()) {
        this.ire = new org.apache.airavata.model.error.InvalidRequestException(other.ire);
      }
      if (other.isSetAce()) {
        this.ace = new org.apache.airavata.model.error.AiravataClientException(other.ace);
      }
      if (other.isSetAse()) {
        this.ase = new org.apache.airavata.model.error.AiravataSystemException(other.ase);
      }
      if (other.isSetAe()) {
        this.ae = new org.apache.airavata.model.error.AuthorizationException(other.ae);
      }
    }

    public updateApplicationModule_result deepCopy() {
      return new updateApplicationModule_result(this);
    }

    @Override
    public void clear() {
      setSuccessIsSet(false);
      this.success = false;
      this.ire = null;
      this.ace = null;
      this.ase = null;
      this.ae = null;
    }

    public boolean isSuccess() {
      return this.success;
    }

    public updateApplicationModule_result setSuccess(boolean success) {
      this.success = success;
      setSuccessIsSet(true);
      return this;
    }

    public void unsetSuccess() {
      __isset_bitfield = EncodingUtils.clearBit(__isset_bitfield, __SUCCESS_ISSET_ID);
    }

    /** Returns true if field success is set (has been assigned a value) and false otherwise */
    public boolean isSetSuccess() {
      return EncodingUtils.testBit(__isset_bitfield, __SUCCESS_ISSET_ID);
    }

    public void setSuccessIsSet(boolean value) {
      __isset_bitfield = EncodingUtils.setBit(__isset_bitfield, __SUCCESS_ISSET_ID, value);
    }

    public org.apache.airavata.model.error.InvalidRequestException getIre() {
      return this.ire;
    }

    public updateApplicationModule_result setIre(org.apache.airavata.model.error.InvalidRequestException ire) {
      this.ire = ire;
      return this;
    }

    public void unsetIre() {
      this.ire = null;
    }

    /** Returns true if field ire is set (has been assigned a value) and false otherwise */
    public boolean isSetIre() {
      return this.ire != null;
    }

    public void setIreIsSet(boolean value) {
      if (!value) {
        this.ire = null;
      }
    }

    public org.apache.airavata.model.error.AiravataClientException getAce() {
      return this.ace;
    }

    public updateApplicationModule_result setAce(org.apache.airavata.model.error.AiravataClientException ace) {
      this.ace = ace;
      return this;
    }

    public void unsetAce() {
      this.ace = null;
    }

    /** Returns true if field ace is set (has been assigned a value) and false otherwise */
    public boolean isSetAce() {
      return this.ace != null;
    }

    public void setAceIsSet(boolean value) {
      if (!value) {
        this.ace = null;
      }
    }

    public org.apache.airavata.model.error.AiravataSystemException getAse() {
      return this.ase;
    }

    public updateApplicationModule_result setAse(org.apache.airavata.model.error.AiravataSystemException ase) {
      this.ase = ase;
      return this;
    }

    public void unsetAse() {
      this.ase = null;
    }

    /** Returns true if field ase is set (has been assigned a value) and false otherwise */
    public boolean isSetAse() {
      return this.ase != null;
    }

    public void setAseIsSet(boolean value) {
      if (!value) {
        this.ase = null;
      }
    }

    public org.apache.airavata.model.error.AuthorizationException getAe() {
      return this.ae;
    }

    public updateApplicationModule_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, Object value) {
      switch (field) {
      case SUCCESS:
        if (value == null) {
          unsetSuccess();
        } else {
          setSuccess((Boolean)value);
        }
        break;

      case IRE:
        if (value == null) {
          unsetIre();
        } else {
          setIre((org.apache.airavata.model.error.InvalidRequestException)value);
        }
        break;

      case ACE:
        if (value == null) {
          unsetAce();
        } else {
          setAce((org.apache.airavata.model.error.AiravataClientException)value);
        }
        break;

      case ASE:
        if (value == null) {
          unsetAse();
        } else {
          setAse((org.apache.airavata.model.error.AiravataSystemException)value);
        }
        break;

      case AE:
        if (value == null) {
          unsetAe();
        } else {
          setAe((org.apache.airavata.model.error.AuthorizationException)value);
        }
        break;

      }
    }

    public Object getFieldValue(_Fields field) {
      switch (field) {
      case SUCCESS:
        return Boolean.valueOf(isSuccess());

      case IRE:
        return getIre();

      case ACE:
        return getAce();

      case ASE:
        return getAse();

      case AE:
        return getAe();

      }
      throw new IllegalStateException();
    }

    /** Returns true if field corresponding to fieldID is set (has been assigned a value) and false otherwise */
    public boolean isSet(_Fields field) {
      if (field == null) {
        throw new IllegalArgumentException();
      }

      switch (field) {
      case SUCCESS:
        return isSetSuccess();
      case IRE:
        return isSetIre();
      case ACE:
        return isSetAce();
      case ASE:
        return isSetAse();
      case AE:
        return isSetAe();
      }
      throw new IllegalStateException();
    }

    @Override
    public boolean equals(Object that) {
      if (that == null)
        return false;
      if (that instanceof updateApplicationModule_result)
        return this.equals((updateApplicationModule_result)that);
      return false;
    }

    public boolean equals(updateApplicationModule_result that) {
      if (that == null)
        return false;

      boolean this_present_success = true;
      boolean that_present_success = true;
      if (this_present_success || that_present_success) {
        if (!(this_present_success && that_present_success))
          return false;
        if (this.success != that.success)
          return false;
      }

      boolean this_present_ire = true && this.isSetIre();
      boolean that_present_ire = true && that.isSetIre();
      if (this_present_ire || that_present_ire) {
        if (!(this_present_ire && that_present_ire))
          return false;
        if (!this.ire.equals(that.ire))
          return false;
      }

      boolean this_present_ace = true && this.isSetAce();
      boolean that_present_ace = true && that.isSetAce();
      if (this_present_ace || that_present_ace) {
        if (!(this_present_ace && that_present_ace))
          return false;
        if (!this.ace.equals(that.ace))
          return false;
      }

      boolean this_present_ase = true && this.isSetAse();
      boolean that_present_ase = true && that.isSetAse();
      if (this_present_ase || that_present_ase) {
        if (!(this_present_ase && that_present_ase))
          return false;
        if (!this.ase.equals(that.ase))
          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() {
      List<Object> list = new ArrayList<Object>();

      boolean present_success = true;
      list.add(present_success);
      if (present_success)
        list.add(success);

      boolean present_ire = true && (isSetIre());
      list.add(present_ire);
      if (present_ire)
        list.add(ire);

      boolean present_ace = true && (isSetAce());
      list.add(present_ace);
      if (present_ace)
        list.add(ace);

      boolean present_ase = true && (isSetAse());
      list.add(present_ase);
      if (present_ase)
        list.add(ase);

      boolean present_ae = true && (isSetAe());
      list.add(present_ae);
      if (present_ae)
        list.add(ae);

      return list.hashCode();
    }

    @Override
    public int compareTo(updateApplicationModule_result other) {
      if (!getClass().equals(other.getClass())) {
        return getClass().getName().compareTo(other.getClass().getName());
      }

      int lastComparison = 0;

      lastComparison = Boolean.valueOf(isSetSuccess()).compareTo(other.isSetSuccess());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetSuccess()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.success, other.success);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = Boolean.valueOf(isSetIre()).compareTo(other.isSetIre());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetIre()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.ire, other.ire);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = Boolean.valueOf(isSetAce()).compareTo(other.isSetAce());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetAce()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.ace, other.ace);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = Boolean.valueOf(isSetAse()).compareTo(other.isSetAse());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetAse()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.ase, other.ase);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = 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 {
      schemes.get(iprot.getScheme()).getScheme().read(iprot, this);
    }

    public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException {
      schemes.get(oprot.getScheme()).getScheme().write(oprot, this);
      }

    @Override
    public String toString() {
      StringBuilder sb = new StringBuilder("updateApplicationModule_result(");
      boolean first = true;

      sb.append("success:");
      sb.append(this.success);
      first = false;
      if (!first) sb.append(", ");
      sb.append("ire:");
      if (this.ire == null) {
        sb.append("null");
      } else {
        sb.append(this.ire);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("ace:");
      if (this.ace == null) {
        sb.append("null");
      } else {
        sb.append(this.ace);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("ase:");
      if (this.ase == null) {
        sb.append("null");
      } else {
        sb.append(this.ase);
      }
      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, 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 updateApplicationModule_resultStandardSchemeFactory implements SchemeFactory {
      public updateApplicationModule_resultStandardScheme getScheme() {
        return new updateApplicationModule_resultStandardScheme();
      }
    }

    private static class updateApplicationModule_resultStandardScheme extends StandardScheme<updateApplicationModule_result> {

      public void read(org.apache.thrift.protocol.TProtocol iprot, updateApplicationModule_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: // IRE
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.ire = new org.apache.airavata.model.error.InvalidRequestException();
                struct.ire.read(iprot);
                struct.setIreIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 2: // ACE
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.ace = new org.apache.airavata.model.error.AiravataClientException();
                struct.ace.read(iprot);
                struct.setAceIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 3: // ASE
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.ase = new org.apache.airavata.model.error.AiravataSystemException();
                struct.ase.read(iprot);
                struct.setAseIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 4: // 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, updateApplicationModule_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.ire != null) {
          oprot.writeFieldBegin(IRE_FIELD_DESC);
          struct.ire.write(oprot);
          oprot.writeFieldEnd();
        }
        if (struct.ace != null) {
          oprot.writeFieldBegin(ACE_FIELD_DESC);
          struct.ace.write(oprot);
          oprot.writeFieldEnd();
        }
        if (struct.ase != null) {
          oprot.writeFieldBegin(ASE_FIELD_DESC);
          struct.ase.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 updateApplicationModule_resultTupleSchemeFactory implements SchemeFactory {
      public updateApplicationModule_resultTupleScheme getScheme() {
        return new updateApplicationModule_resultTupleScheme();
      }
    }

    private static class updateApplicationModule_resultTupleScheme extends TupleScheme<updateApplicationModule_result> {

      @Override
      public void write(org.apache.thrift.protocol.TProtocol prot, updateApplicationModule_result struct) throws org.apache.thrift.TException {
        TTupleProtocol oprot = (TTupleProtocol) prot;
        BitSet optionals = new BitSet();
        if (struct.isSetSuccess()) {
          optionals.set(0);
        }
        if (struct.isSetIre()) {
          optionals.set(1);
        }
        if (struct.isSetAce()) {
          optionals.set(2);
        }
        if (struct.isSetAse()) {
          optionals.set(3);
        }
        if (struct.isSetAe()) {
          optionals.set(4);
        }
        oprot.writeBitSet(optionals, 5);
        if (struct.isSetSuccess()) {
          oprot.writeBool(struct.success);
        }
        if (struct.isSetIre()) {
          struct.ire.write(oprot);
        }
        if (struct.isSetAce()) {
          struct.ace.write(oprot);
        }
        if (struct.isSetAse()) {
          struct.ase.write(oprot);
        }
        if (struct.isSetAe()) {
          struct.ae.write(oprot);
        }
      }

      @Override
      public void read(org.apache.thrift.protocol.TProtocol prot, updateApplicationModule_result struct) throws org.apache.thrift.TException {
        TTupleProtocol iprot = (TTupleProtocol) prot;
        BitSet incoming = iprot.readBitSet(5);
        if (incoming.get(0)) {
          struct.success = iprot.readBool();
          struct.setSuccessIsSet(true);
        }
        if (incoming.get(1)) {
          struct.ire = new org.apache.airavata.model.error.InvalidRequestException();
          struct.ire.read(iprot);
          struct.setIreIsSet(true);
        }
        if (incoming.get(2)) {
          struct.ace = new org.apache.airavata.model.error.AiravataClientException();
          struct.ace.read(iprot);
          struct.setAceIsSet(true);
        }
        if (incoming.get(3)) {
          struct.ase = new org.apache.airavata.model.error.AiravataSystemException();
          struct.ase.read(iprot);
          struct.setAseIsSet(true);
        }
        if (incoming.get(4)) {
          struct.ae = new org.apache.airavata.model.error.AuthorizationException();
          struct.ae.read(iprot);
          struct.setAeIsSet(true);
        }
      }
    }

  }

  public static class getAllAppModules_args implements org.apache.thrift.TBase<getAllAppModules_args, getAllAppModules_args._Fields>, java.io.Serializable, Cloneable, Comparable<getAllAppModules_args>   {
    private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("getAllAppModules_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 Map<Class<? extends IScheme>, SchemeFactory> schemes = new HashMap<Class<? extends IScheme>, SchemeFactory>();
    static {
      schemes.put(StandardScheme.class, new getAllAppModules_argsStandardSchemeFactory());
      schemes.put(TupleScheme.class, new getAllAppModules_argsTupleSchemeFactory());
    }

    public org.apache.airavata.model.security.AuthzToken authzToken; // required
    public 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 Map<String, _Fields> byName = new HashMap<String, _Fields>();

      static {
        for (_Fields field : EnumSet.allOf(_Fields.class)) {
          byName.put(field.getFieldName(), field);
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, or null if its not found.
       */
      public static _Fields findByThriftId(int fieldId) {
        switch(fieldId) {
          case 1: // 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 IllegalArgumentException("Field " + fieldId + " doesn't exist!");
        return fields;
      }

      /**
       * Find the _Fields constant that matches name, or null if its not found.
       */
      public static _Fields findByName(String name) {
        return byName.get(name);
      }

      private final short _thriftId;
      private final String _fieldName;

      _Fields(short thriftId, String fieldName) {
        _thriftId = thriftId;
        _fieldName = fieldName;
      }

      public short getThriftFieldId() {
        return _thriftId;
      }

      public String getFieldName() {
        return _fieldName;
      }
    }

    // isset id assignments
    public static final Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
    static {
      Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new EnumMap<_Fields, org.apache.thrift.meta_data.FieldMetaData>(_Fields.class);
      tmpMap.put(_Fields.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 = Collections.unmodifiableMap(tmpMap);
      org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(getAllAppModules_args.class, metaDataMap);
    }

    public getAllAppModules_args() {
    }

    public getAllAppModules_args(
      org.apache.airavata.model.security.AuthzToken authzToken,
      String gatewayId)
    {
      this();
      this.authzToken = authzToken;
      this.gatewayId = gatewayId;
    }

    /**
     * Performs a deep copy on <i>other</i>.
     */
    public getAllAppModules_args(getAllAppModules_args other) {
      if (other.isSetAuthzToken()) {
        this.authzToken = new org.apache.airavata.model.security.AuthzToken(other.authzToken);
      }
      if (other.isSetGatewayId()) {
        this.gatewayId = other.gatewayId;
      }
    }

    public getAllAppModules_args deepCopy() {
      return new getAllAppModules_args(this);
    }

    @Override
    public void clear() {
      this.authzToken = null;
      this.gatewayId = null;
    }

    public org.apache.airavata.model.security.AuthzToken getAuthzToken() {
      return this.authzToken;
    }

    public getAllAppModules_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 String getGatewayId() {
      return this.gatewayId;
    }

    public getAllAppModules_args setGatewayId(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, 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((String)value);
        }
        break;

      }
    }

    public Object getFieldValue(_Fields field) {
      switch (field) {
      case AUTHZ_TOKEN:
        return getAuthzToken();

      case GATEWAY_ID:
        return getGatewayId();

      }
      throw new IllegalStateException();
    }

    /** Returns true if field corresponding to fieldID is set (has been assigned a value) and false otherwise */
    public boolean isSet(_Fields field) {
      if (field == null) {
        throw new IllegalArgumentException();
      }

      switch (field) {
      case AUTHZ_TOKEN:
        return isSetAuthzToken();
      case GATEWAY_ID:
        return isSetGatewayId();
      }
      throw new IllegalStateException();
    }

    @Override
    public boolean equals(Object that) {
      if (that == null)
        return false;
      if (that instanceof getAllAppModules_args)
        return this.equals((getAllAppModules_args)that);
      return false;
    }

    public boolean equals(getAllAppModules_args that) {
      if (that == null)
        return false;

      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() {
      List<Object> list = new ArrayList<Object>();

      boolean present_authzToken = true && (isSetAuthzToken());
      list.add(present_authzToken);
      if (present_authzToken)
        list.add(authzToken);

      boolean present_gatewayId = true && (isSetGatewayId());
      list.add(present_gatewayId);
      if (present_gatewayId)
        list.add(gatewayId);

      return list.hashCode();
    }

    @Override
    public int compareTo(getAllAppModules_args other) {
      if (!getClass().equals(other.getClass())) {
        return getClass().getName().compareTo(other.getClass().getName());
      }

      int lastComparison = 0;

      lastComparison = 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 = 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 {
      schemes.get(iprot.getScheme()).getScheme().read(iprot, this);
    }

    public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException {
      schemes.get(oprot.getScheme()).getScheme().write(oprot, this);
    }

    @Override
    public String toString() {
      StringBuilder sb = new StringBuilder("getAllAppModules_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, 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 getAllAppModules_argsStandardSchemeFactory implements SchemeFactory {
      public getAllAppModules_argsStandardScheme getScheme() {
        return new getAllAppModules_argsStandardScheme();
      }
    }

    private static class getAllAppModules_argsStandardScheme extends StandardScheme<getAllAppModules_args> {

      public void read(org.apache.thrift.protocol.TProtocol iprot, getAllAppModules_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, getAllAppModules_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 getAllAppModules_argsTupleSchemeFactory implements SchemeFactory {
      public getAllAppModules_argsTupleScheme getScheme() {
        return new getAllAppModules_argsTupleScheme();
      }
    }

    private static class getAllAppModules_argsTupleScheme extends TupleScheme<getAllAppModules_args> {

      @Override
      public void write(org.apache.thrift.protocol.TProtocol prot, getAllAppModules_args struct) throws org.apache.thrift.TException {
        TTupleProtocol oprot = (TTupleProtocol) prot;
        struct.authzToken.write(oprot);
        oprot.writeString(struct.gatewayId);
      }

      @Override
      public void read(org.apache.thrift.protocol.TProtocol prot, getAllAppModules_args struct) throws org.apache.thrift.TException {
        TTupleProtocol iprot = (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);
      }
    }

  }

  public static class getAllAppModules_result implements org.apache.thrift.TBase<getAllAppModules_result, getAllAppModules_result._Fields>, java.io.Serializable, Cloneable, Comparable<getAllAppModules_result>   {
    private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("getAllAppModules_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 IRE_FIELD_DESC = new org.apache.thrift.protocol.TField("ire", org.apache.thrift.protocol.TType.STRUCT, (short)1);
    private static final org.apache.thrift.protocol.TField ACE_FIELD_DESC = new org.apache.thrift.protocol.TField("ace", org.apache.thrift.protocol.TType.STRUCT, (short)2);
    private static final org.apache.thrift.protocol.TField ASE_FIELD_DESC = new org.apache.thrift.protocol.TField("ase", org.apache.thrift.protocol.TType.STRUCT, (short)3);
    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)4);

    private static final Map<Class<? extends IScheme>, SchemeFactory> schemes = new HashMap<Class<? extends IScheme>, SchemeFactory>();
    static {
      schemes.put(StandardScheme.class, new getAllAppModules_resultStandardSchemeFactory());
      schemes.put(TupleScheme.class, new getAllAppModules_resultTupleSchemeFactory());
    }

    public List<org.apache.airavata.model.appcatalog.appdeployment.ApplicationModule> success; // required
    public org.apache.airavata.model.error.InvalidRequestException ire; // required
    public org.apache.airavata.model.error.AiravataClientException ace; // required
    public org.apache.airavata.model.error.AiravataSystemException ase; // 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"),
      IRE((short)1, "ire"),
      ACE((short)2, "ace"),
      ASE((short)3, "ase"),
      AE((short)4, "ae");

      private static final Map<String, _Fields> byName = new HashMap<String, _Fields>();

      static {
        for (_Fields field : EnumSet.allOf(_Fields.class)) {
          byName.put(field.getFieldName(), field);
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, or null if its not found.
       */
      public static _Fields findByThriftId(int fieldId) {
        switch(fieldId) {
          case 0: // SUCCESS
            return SUCCESS;
          case 1: // IRE
            return IRE;
          case 2: // ACE
            return ACE;
          case 3: // ASE
            return ASE;
          case 4: // 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 IllegalArgumentException("Field " + fieldId + " doesn't exist!");
        return fields;
      }

      /**
       * Find the _Fields constant that matches name, or null if its not found.
       */
      public static _Fields findByName(String name) {
        return byName.get(name);
      }

      private final short _thriftId;
      private final String _fieldName;

      _Fields(short thriftId, String fieldName) {
        _thriftId = thriftId;
        _fieldName = fieldName;
      }

      public short getThriftFieldId() {
        return _thriftId;
      }

      public String getFieldName() {
        return _fieldName;
      }
    }

    // isset id assignments
    public static final Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
    static {
      Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new EnumMap<_Fields, org.apache.thrift.meta_data.FieldMetaData>(_Fields.class);
      tmpMap.put(_Fields.SUCCESS, new org.apache.thrift.meta_data.FieldMetaData("success", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.ListMetaData(org.apache.thrift.protocol.TType.LIST, 
              new org.apache.thrift.meta_data.StructMetaData(org.apache.thrift.protocol.TType.STRUCT, org.apache.airavata.model.appcatalog.appdeployment.ApplicationModule.class))));
      tmpMap.put(_Fields.IRE, new org.apache.thrift.meta_data.FieldMetaData("ire", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRUCT)));
      tmpMap.put(_Fields.ACE, new org.apache.thrift.meta_data.FieldMetaData("ace", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRUCT)));
      tmpMap.put(_Fields.ASE, new org.apache.thrift.meta_data.FieldMetaData("ase", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRUCT)));
      tmpMap.put(_Fields.AE, new org.apache.thrift.meta_data.FieldMetaData("ae", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRUCT)));
      metaDataMap = Collections.unmodifiableMap(tmpMap);
      org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(getAllAppModules_result.class, metaDataMap);
    }

    public getAllAppModules_result() {
    }

    public getAllAppModules_result(
      List<org.apache.airavata.model.appcatalog.appdeployment.ApplicationModule> success,
      org.apache.airavata.model.error.InvalidRequestException ire,
      org.apache.airavata.model.error.AiravataClientException ace,
      org.apache.airavata.model.error.AiravataSystemException ase,
      org.apache.airavata.model.error.AuthorizationException ae)
    {
      this();
      this.success = success;
      this.ire = ire;
      this.ace = ace;
      this.ase = ase;
      this.ae = ae;
    }

    /**
     * Performs a deep copy on <i>other</i>.
     */
    public getAllAppModules_result(getAllAppModules_result other) {
      if (other.isSetSuccess()) {
        List<org.apache.airavata.model.appcatalog.appdeployment.ApplicationModule> __this__success = new ArrayList<org.apache.airavata.model.appcatalog.appdeployment.ApplicationModule>(other.success.size());
        for (org.apache.airavata.model.appcatalog.appdeployment.ApplicationModule other_element : other.success) {
          __this__success.add(new org.apache.airavata.model.appcatalog.appdeployment.ApplicationModule(other_element));
        }
        this.success = __this__success;
      }
      if (other.isSetIre()) {
        this.ire = new org.apache.airavata.model.error.InvalidRequestException(other.ire);
      }
      if (other.isSetAce()) {
        this.ace = new org.apache.airavata.model.error.AiravataClientException(other.ace);
      }
      if (other.isSetAse()) {
        this.ase = new org.apache.airavata.model.error.AiravataSystemException(other.ase);
      }
      if (other.isSetAe()) {
        this.ae = new org.apache.airavata.model.error.AuthorizationException(other.ae);
      }
    }

    public getAllAppModules_result deepCopy() {
      return new getAllAppModules_result(this);
    }

    @Override
    public void clear() {
      this.success = null;
      this.ire = null;
      this.ace = null;
      this.ase = null;
      this.ae = null;
    }

    public int getSuccessSize() {
      return (this.success == null) ? 0 : this.success.size();
    }

    public java.util.Iterator<org.apache.airavata.model.appcatalog.appdeployment.ApplicationModule> getSuccessIterator() {
      return (this.success == null) ? null : this.success.iterator();
    }

    public void addToSuccess(org.apache.airavata.model.appcatalog.appdeployment.ApplicationModule elem) {
      if (this.success == null) {
        this.success = new ArrayList<org.apache.airavata.model.appcatalog.appdeployment.ApplicationModule>();
      }
      this.success.add(elem);
    }

    public List<org.apache.airavata.model.appcatalog.appdeployment.ApplicationModule> getSuccess() {
      return this.success;
    }

    public getAllAppModules_result setSuccess(List<org.apache.airavata.model.appcatalog.appdeployment.ApplicationModule> 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.model.error.InvalidRequestException getIre() {
      return this.ire;
    }

    public getAllAppModules_result setIre(org.apache.airavata.model.error.InvalidRequestException ire) {
      this.ire = ire;
      return this;
    }

    public void unsetIre() {
      this.ire = null;
    }

    /** Returns true if field ire is set (has been assigned a value) and false otherwise */
    public boolean isSetIre() {
      return this.ire != null;
    }

    public void setIreIsSet(boolean value) {
      if (!value) {
        this.ire = null;
      }
    }

    public org.apache.airavata.model.error.AiravataClientException getAce() {
      return this.ace;
    }

    public getAllAppModules_result setAce(org.apache.airavata.model.error.AiravataClientException ace) {
      this.ace = ace;
      return this;
    }

    public void unsetAce() {
      this.ace = null;
    }

    /** Returns true if field ace is set (has been assigned a value) and false otherwise */
    public boolean isSetAce() {
      return this.ace != null;
    }

    public void setAceIsSet(boolean value) {
      if (!value) {
        this.ace = null;
      }
    }

    public org.apache.airavata.model.error.AiravataSystemException getAse() {
      return this.ase;
    }

    public getAllAppModules_result setAse(org.apache.airavata.model.error.AiravataSystemException ase) {
      this.ase = ase;
      return this;
    }

    public void unsetAse() {
      this.ase = null;
    }

    /** Returns true if field ase is set (has been assigned a value) and false otherwise */
    public boolean isSetAse() {
      return this.ase != null;
    }

    public void setAseIsSet(boolean value) {
      if (!value) {
        this.ase = null;
      }
    }

    public org.apache.airavata.model.error.AuthorizationException getAe() {
      return this.ae;
    }

    public getAllAppModules_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, Object value) {
      switch (field) {
      case SUCCESS:
        if (value == null) {
          unsetSuccess();
        } else {
          setSuccess((List<org.apache.airavata.model.appcatalog.appdeployment.ApplicationModule>)value);
        }
        break;

      case IRE:
        if (value == null) {
          unsetIre();
        } else {
          setIre((org.apache.airavata.model.error.InvalidRequestException)value);
        }
        break;

      case ACE:
        if (value == null) {
          unsetAce();
        } else {
          setAce((org.apache.airavata.model.error.AiravataClientException)value);
        }
        break;

      case ASE:
        if (value == null) {
          unsetAse();
        } else {
          setAse((org.apache.airavata.model.error.AiravataSystemException)value);
        }
        break;

      case AE:
        if (value == null) {
          unsetAe();
        } else {
          setAe((org.apache.airavata.model.error.AuthorizationException)value);
        }
        break;

      }
    }

    public Object getFieldValue(_Fields field) {
      switch (field) {
      case SUCCESS:
        return getSuccess();

      case IRE:
        return getIre();

      case ACE:
        return getAce();

      case ASE:
        return getAse();

      case AE:
        return getAe();

      }
      throw new IllegalStateException();
    }

    /** Returns true if field corresponding to fieldID is set (has been assigned a value) and false otherwise */
    public boolean isSet(_Fields field) {
      if (field == null) {
        throw new IllegalArgumentException();
      }

      switch (field) {
      case SUCCESS:
        return isSetSuccess();
      case IRE:
        return isSetIre();
      case ACE:
        return isSetAce();
      case ASE:
        return isSetAse();
      case AE:
        return isSetAe();
      }
      throw new IllegalStateException();
    }

    @Override
    public boolean equals(Object that) {
      if (that == null)
        return false;
      if (that instanceof getAllAppModules_result)
        return this.equals((getAllAppModules_result)that);
      return false;
    }

    public boolean equals(getAllAppModules_result that) {
      if (that == null)
        return false;

      boolean this_present_success = true && this.isSetSuccess();
      boolean that_present_success = true && that.isSetSuccess();
      if (this_present_success || that_present_success) {
        if (!(this_present_success && that_present_success))
          return false;
        if (!this.success.equals(that.success))
          return false;
      }

      boolean this_present_ire = true && this.isSetIre();
      boolean that_present_ire = true && that.isSetIre();
      if (this_present_ire || that_present_ire) {
        if (!(this_present_ire && that_present_ire))
          return false;
        if (!this.ire.equals(that.ire))
          return false;
      }

      boolean this_present_ace = true && this.isSetAce();
      boolean that_present_ace = true && that.isSetAce();
      if (this_present_ace || that_present_ace) {
        if (!(this_present_ace && that_present_ace))
          return false;
        if (!this.ace.equals(that.ace))
          return false;
      }

      boolean this_present_ase = true && this.isSetAse();
      boolean that_present_ase = true && that.isSetAse();
      if (this_present_ase || that_present_ase) {
        if (!(this_present_ase && that_present_ase))
          return false;
        if (!this.ase.equals(that.ase))
          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() {
      List<Object> list = new ArrayList<Object>();

      boolean present_success = true && (isSetSuccess());
      list.add(present_success);
      if (present_success)
        list.add(success);

      boolean present_ire = true && (isSetIre());
      list.add(present_ire);
      if (present_ire)
        list.add(ire);

      boolean present_ace = true && (isSetAce());
      list.add(present_ace);
      if (present_ace)
        list.add(ace);

      boolean present_ase = true && (isSetAse());
      list.add(present_ase);
      if (present_ase)
        list.add(ase);

      boolean present_ae = true && (isSetAe());
      list.add(present_ae);
      if (present_ae)
        list.add(ae);

      return list.hashCode();
    }

    @Override
    public int compareTo(getAllAppModules_result other) {
      if (!getClass().equals(other.getClass())) {
        return getClass().getName().compareTo(other.getClass().getName());
      }

      int lastComparison = 0;

      lastComparison = Boolean.valueOf(isSetSuccess()).compareTo(other.isSetSuccess());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetSuccess()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.success, other.success);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = Boolean.valueOf(isSetIre()).compareTo(other.isSetIre());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetIre()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.ire, other.ire);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = Boolean.valueOf(isSetAce()).compareTo(other.isSetAce());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetAce()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.ace, other.ace);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = Boolean.valueOf(isSetAse()).compareTo(other.isSetAse());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetAse()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.ase, other.ase);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = 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 {
      schemes.get(iprot.getScheme()).getScheme().read(iprot, this);
    }

    public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException {
      schemes.get(oprot.getScheme()).getScheme().write(oprot, this);
      }

    @Override
    public String toString() {
      StringBuilder sb = new StringBuilder("getAllAppModules_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("ire:");
      if (this.ire == null) {
        sb.append("null");
      } else {
        sb.append(this.ire);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("ace:");
      if (this.ace == null) {
        sb.append("null");
      } else {
        sb.append(this.ace);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("ase:");
      if (this.ase == null) {
        sb.append("null");
      } else {
        sb.append(this.ase);
      }
      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, 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 getAllAppModules_resultStandardSchemeFactory implements SchemeFactory {
      public getAllAppModules_resultStandardScheme getScheme() {
        return new getAllAppModules_resultStandardScheme();
      }
    }

    private static class getAllAppModules_resultStandardScheme extends StandardScheme<getAllAppModules_result> {

      public void read(org.apache.thrift.protocol.TProtocol iprot, getAllAppModules_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 _list150 = iprot.readListBegin();
                  struct.success = new ArrayList<org.apache.airavata.model.appcatalog.appdeployment.ApplicationModule>(_list150.size);
                  org.apache.airavata.model.appcatalog.appdeployment.ApplicationModule _elem151;
                  for (int _i152 = 0; _i152 < _list150.size; ++_i152)
                  {
                    _elem151 = new org.apache.airavata.model.appcatalog.appdeployment.ApplicationModule();
                    _elem151.read(iprot);
                    struct.success.add(_elem151);
                  }
                  iprot.readListEnd();
                }
                struct.setSuccessIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 1: // IRE
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.ire = new org.apache.airavata.model.error.InvalidRequestException();
                struct.ire.read(iprot);
                struct.setIreIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 2: // ACE
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.ace = new org.apache.airavata.model.error.AiravataClientException();
                struct.ace.read(iprot);
                struct.setAceIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 3: // ASE
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.ase = new org.apache.airavata.model.error.AiravataSystemException();
                struct.ase.read(iprot);
                struct.setAseIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 4: // 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, getAllAppModules_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.appcatalog.appdeployment.ApplicationModule _iter153 : struct.success)
            {
              _iter153.write(oprot);
            }
            oprot.writeListEnd();
          }
          oprot.writeFieldEnd();
        }
        if (struct.ire != null) {
          oprot.writeFieldBegin(IRE_FIELD_DESC);
          struct.ire.write(oprot);
          oprot.writeFieldEnd();
        }
        if (struct.ace != null) {
          oprot.writeFieldBegin(ACE_FIELD_DESC);
          struct.ace.write(oprot);
          oprot.writeFieldEnd();
        }
        if (struct.ase != null) {
          oprot.writeFieldBegin(ASE_FIELD_DESC);
          struct.ase.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 getAllAppModules_resultTupleSchemeFactory implements SchemeFactory {
      public getAllAppModules_resultTupleScheme getScheme() {
        return new getAllAppModules_resultTupleScheme();
      }
    }

    private static class getAllAppModules_resultTupleScheme extends TupleScheme<getAllAppModules_result> {

      @Override
      public void write(org.apache.thrift.protocol.TProtocol prot, getAllAppModules_result struct) throws org.apache.thrift.TException {
        TTupleProtocol oprot = (TTupleProtocol) prot;
        BitSet optionals = new BitSet();
        if (struct.isSetSuccess()) {
          optionals.set(0);
        }
        if (struct.isSetIre()) {
          optionals.set(1);
        }
        if (struct.isSetAce()) {
          optionals.set(2);
        }
        if (struct.isSetAse()) {
          optionals.set(3);
        }
        if (struct.isSetAe()) {
          optionals.set(4);
        }
        oprot.writeBitSet(optionals, 5);
        if (struct.isSetSuccess()) {
          {
            oprot.writeI32(struct.success.size());
            for (org.apache.airavata.model.appcatalog.appdeployment.ApplicationModule _iter154 : struct.success)
            {
              _iter154.write(oprot);
            }
          }
        }
        if (struct.isSetIre()) {
          struct.ire.write(oprot);
        }
        if (struct.isSetAce()) {
          struct.ace.write(oprot);
        }
        if (struct.isSetAse()) {
          struct.ase.write(oprot);
        }
        if (struct.isSetAe()) {
          struct.ae.write(oprot);
        }
      }

      @Override
      public void read(org.apache.thrift.protocol.TProtocol prot, getAllAppModules_result struct) throws org.apache.thrift.TException {
        TTupleProtocol iprot = (TTupleProtocol) prot;
        BitSet incoming = iprot.readBitSet(5);
        if (incoming.get(0)) {
          {
            org.apache.thrift.protocol.TList _list155 = new org.apache.thrift.protocol.TList(org.apache.thrift.protocol.TType.STRUCT, iprot.readI32());
            struct.success = new ArrayList<org.apache.airavata.model.appcatalog.appdeployment.ApplicationModule>(_list155.size);
            org.apache.airavata.model.appcatalog.appdeployment.ApplicationModule _elem156;
            for (int _i157 = 0; _i157 < _list155.size; ++_i157)
            {
              _elem156 = new org.apache.airavata.model.appcatalog.appdeployment.ApplicationModule();
              _elem156.read(iprot);
              struct.success.add(_elem156);
            }
          }
          struct.setSuccessIsSet(true);
        }
        if (incoming.get(1)) {
          struct.ire = new org.apache.airavata.model.error.InvalidRequestException();
          struct.ire.read(iprot);
          struct.setIreIsSet(true);
        }
        if (incoming.get(2)) {
          struct.ace = new org.apache.airavata.model.error.AiravataClientException();
          struct.ace.read(iprot);
          struct.setAceIsSet(true);
        }
        if (incoming.get(3)) {
          struct.ase = new org.apache.airavata.model.error.AiravataSystemException();
          struct.ase.read(iprot);
          struct.setAseIsSet(true);
        }
        if (incoming.get(4)) {
          struct.ae = new org.apache.airavata.model.error.AuthorizationException();
          struct.ae.read(iprot);
          struct.setAeIsSet(true);
        }
      }
    }

  }

  public static class deleteApplicationModule_args implements org.apache.thrift.TBase<deleteApplicationModule_args, deleteApplicationModule_args._Fields>, java.io.Serializable, Cloneable, Comparable<deleteApplicationModule_args>   {
    private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("deleteApplicationModule_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 APP_MODULE_ID_FIELD_DESC = new org.apache.thrift.protocol.TField("appModuleId", org.apache.thrift.protocol.TType.STRING, (short)2);

    private static final Map<Class<? extends IScheme>, SchemeFactory> schemes = new HashMap<Class<? extends IScheme>, SchemeFactory>();
    static {
      schemes.put(StandardScheme.class, new deleteApplicationModule_argsStandardSchemeFactory());
      schemes.put(TupleScheme.class, new deleteApplicationModule_argsTupleSchemeFactory());
    }

    public org.apache.airavata.model.security.AuthzToken authzToken; // required
    public String appModuleId; // required

    /** 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"),
      APP_MODULE_ID((short)2, "appModuleId");

      private static final Map<String, _Fields> byName = new HashMap<String, _Fields>();

      static {
        for (_Fields field : EnumSet.allOf(_Fields.class)) {
          byName.put(field.getFieldName(), field);
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, or null if its not found.
       */
      public static _Fields findByThriftId(int fieldId) {
        switch(fieldId) {
          case 1: // AUTHZ_TOKEN
            return AUTHZ_TOKEN;
          case 2: // APP_MODULE_ID
            return APP_MODULE_ID;
          default:
            return null;
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, throwing an exception
       * if it is not found.
       */
      public static _Fields findByThriftIdOrThrow(int fieldId) {
        _Fields fields = findByThriftId(fieldId);
        if (fields == null) throw new IllegalArgumentException("Field " + fieldId + " doesn't exist!");
        return fields;
      }

      /**
       * Find the _Fields constant that matches name, or null if its not found.
       */
      public static _Fields findByName(String name) {
        return byName.get(name);
      }

      private final short _thriftId;
      private final String _fieldName;

      _Fields(short thriftId, String fieldName) {
        _thriftId = thriftId;
        _fieldName = fieldName;
      }

      public short getThriftFieldId() {
        return _thriftId;
      }

      public String getFieldName() {
        return _fieldName;
      }
    }

    // isset id assignments
    public static final Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
    static {
      Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new EnumMap<_Fields, org.apache.thrift.meta_data.FieldMetaData>(_Fields.class);
      tmpMap.put(_Fields.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.APP_MODULE_ID, new org.apache.thrift.meta_data.FieldMetaData("appModuleId", org.apache.thrift.TFieldRequirementType.REQUIRED, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING)));
      metaDataMap = Collections.unmodifiableMap(tmpMap);
      org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(deleteApplicationModule_args.class, metaDataMap);
    }

    public deleteApplicationModule_args() {
    }

    public deleteApplicationModule_args(
      org.apache.airavata.model.security.AuthzToken authzToken,
      String appModuleId)
    {
      this();
      this.authzToken = authzToken;
      this.appModuleId = appModuleId;
    }

    /**
     * Performs a deep copy on <i>other</i>.
     */
    public deleteApplicationModule_args(deleteApplicationModule_args other) {
      if (other.isSetAuthzToken()) {
        this.authzToken = new org.apache.airavata.model.security.AuthzToken(other.authzToken);
      }
      if (other.isSetAppModuleId()) {
        this.appModuleId = other.appModuleId;
      }
    }

    public deleteApplicationModule_args deepCopy() {
      return new deleteApplicationModule_args(this);
    }

    @Override
    public void clear() {
      this.authzToken = null;
      this.appModuleId = null;
    }

    public org.apache.airavata.model.security.AuthzToken getAuthzToken() {
      return this.authzToken;
    }

    public deleteApplicationModule_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 String getAppModuleId() {
      return this.appModuleId;
    }

    public deleteApplicationModule_args setAppModuleId(String appModuleId) {
      this.appModuleId = appModuleId;
      return this;
    }

    public void unsetAppModuleId() {
      this.appModuleId = null;
    }

    /** Returns true if field appModuleId is set (has been assigned a value) and false otherwise */
    public boolean isSetAppModuleId() {
      return this.appModuleId != null;
    }

    public void setAppModuleIdIsSet(boolean value) {
      if (!value) {
        this.appModuleId = null;
      }
    }

    public void setFieldValue(_Fields field, Object value) {
      switch (field) {
      case AUTHZ_TOKEN:
        if (value == null) {
          unsetAuthzToken();
        } else {
          setAuthzToken((org.apache.airavata.model.security.AuthzToken)value);
        }
        break;

      case APP_MODULE_ID:
        if (value == null) {
          unsetAppModuleId();
        } else {
          setAppModuleId((String)value);
        }
        break;

      }
    }

    public Object getFieldValue(_Fields field) {
      switch (field) {
      case AUTHZ_TOKEN:
        return getAuthzToken();

      case APP_MODULE_ID:
        return getAppModuleId();

      }
      throw new IllegalStateException();
    }

    /** Returns true if field corresponding to fieldID is set (has been assigned a value) and false otherwise */
    public boolean isSet(_Fields field) {
      if (field == null) {
        throw new IllegalArgumentException();
      }

      switch (field) {
      case AUTHZ_TOKEN:
        return isSetAuthzToken();
      case APP_MODULE_ID:
        return isSetAppModuleId();
      }
      throw new IllegalStateException();
    }

    @Override
    public boolean equals(Object that) {
      if (that == null)
        return false;
      if (that instanceof deleteApplicationModule_args)
        return this.equals((deleteApplicationModule_args)that);
      return false;
    }

    public boolean equals(deleteApplicationModule_args that) {
      if (that == null)
        return false;

      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_appModuleId = true && this.isSetAppModuleId();
      boolean that_present_appModuleId = true && that.isSetAppModuleId();
      if (this_present_appModuleId || that_present_appModuleId) {
        if (!(this_present_appModuleId && that_present_appModuleId))
          return false;
        if (!this.appModuleId.equals(that.appModuleId))
          return false;
      }

      return true;
    }

    @Override
    public int hashCode() {
      List<Object> list = new ArrayList<Object>();

      boolean present_authzToken = true && (isSetAuthzToken());
      list.add(present_authzToken);
      if (present_authzToken)
        list.add(authzToken);

      boolean present_appModuleId = true && (isSetAppModuleId());
      list.add(present_appModuleId);
      if (present_appModuleId)
        list.add(appModuleId);

      return list.hashCode();
    }

    @Override
    public int compareTo(deleteApplicationModule_args other) {
      if (!getClass().equals(other.getClass())) {
        return getClass().getName().compareTo(other.getClass().getName());
      }

      int lastComparison = 0;

      lastComparison = 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 = Boolean.valueOf(isSetAppModuleId()).compareTo(other.isSetAppModuleId());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetAppModuleId()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.appModuleId, other.appModuleId);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      return 0;
    }

    public _Fields fieldForId(int fieldId) {
      return _Fields.findByThriftId(fieldId);
    }

    public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
      schemes.get(iprot.getScheme()).getScheme().read(iprot, this);
    }

    public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException {
      schemes.get(oprot.getScheme()).getScheme().write(oprot, this);
    }

    @Override
    public String toString() {
      StringBuilder sb = new StringBuilder("deleteApplicationModule_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("appModuleId:");
      if (this.appModuleId == null) {
        sb.append("null");
      } else {
        sb.append(this.appModuleId);
      }
      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 (appModuleId == null) {
        throw new org.apache.thrift.protocol.TProtocolException("Required field 'appModuleId' 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, 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 deleteApplicationModule_argsStandardSchemeFactory implements SchemeFactory {
      public deleteApplicationModule_argsStandardScheme getScheme() {
        return new deleteApplicationModule_argsStandardScheme();
      }
    }

    private static class deleteApplicationModule_argsStandardScheme extends StandardScheme<deleteApplicationModule_args> {

      public void read(org.apache.thrift.protocol.TProtocol iprot, deleteApplicationModule_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: // APP_MODULE_ID
              if (schemeField.type == org.apache.thrift.protocol.TType.STRING) {
                struct.appModuleId = iprot.readString();
                struct.setAppModuleIdIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            default:
              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
          }
          iprot.readFieldEnd();
        }
        iprot.readStructEnd();

        // check for required fields of primitive type, which can't be checked in the validate method
        struct.validate();
      }

      public void write(org.apache.thrift.protocol.TProtocol oprot, deleteApplicationModule_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.appModuleId != null) {
          oprot.writeFieldBegin(APP_MODULE_ID_FIELD_DESC);
          oprot.writeString(struct.appModuleId);
          oprot.writeFieldEnd();
        }
        oprot.writeFieldStop();
        oprot.writeStructEnd();
      }

    }

    private static class deleteApplicationModule_argsTupleSchemeFactory implements SchemeFactory {
      public deleteApplicationModule_argsTupleScheme getScheme() {
        return new deleteApplicationModule_argsTupleScheme();
      }
    }

    private static class deleteApplicationModule_argsTupleScheme extends TupleScheme<deleteApplicationModule_args> {

      @Override
      public void write(org.apache.thrift.protocol.TProtocol prot, deleteApplicationModule_args struct) throws org.apache.thrift.TException {
        TTupleProtocol oprot = (TTupleProtocol) prot;
        struct.authzToken.write(oprot);
        oprot.writeString(struct.appModuleId);
      }

      @Override
      public void read(org.apache.thrift.protocol.TProtocol prot, deleteApplicationModule_args struct) throws org.apache.thrift.TException {
        TTupleProtocol iprot = (TTupleProtocol) prot;
        struct.authzToken = new org.apache.airavata.model.security.AuthzToken();
        struct.authzToken.read(iprot);
        struct.setAuthzTokenIsSet(true);
        struct.appModuleId = iprot.readString();
        struct.setAppModuleIdIsSet(true);
      }
    }

  }

  public static class deleteApplicationModule_result implements org.apache.thrift.TBase<deleteApplicationModule_result, deleteApplicationModule_result._Fields>, java.io.Serializable, Cloneable, Comparable<deleteApplicationModule_result>   {
    private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("deleteApplicationModule_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 IRE_FIELD_DESC = new org.apache.thrift.protocol.TField("ire", org.apache.thrift.protocol.TType.STRUCT, (short)1);
    private static final org.apache.thrift.protocol.TField ACE_FIELD_DESC = new org.apache.thrift.protocol.TField("ace", org.apache.thrift.protocol.TType.STRUCT, (short)2);
    private static final org.apache.thrift.protocol.TField ASE_FIELD_DESC = new org.apache.thrift.protocol.TField("ase", org.apache.thrift.protocol.TType.STRUCT, (short)3);
    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)4);

    private static final Map<Class<? extends IScheme>, SchemeFactory> schemes = new HashMap<Class<? extends IScheme>, SchemeFactory>();
    static {
      schemes.put(StandardScheme.class, new deleteApplicationModule_resultStandardSchemeFactory());
      schemes.put(TupleScheme.class, new deleteApplicationModule_resultTupleSchemeFactory());
    }

    public boolean success; // required
    public org.apache.airavata.model.error.InvalidRequestException ire; // required
    public org.apache.airavata.model.error.AiravataClientException ace; // required
    public org.apache.airavata.model.error.AiravataSystemException ase; // 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"),
      IRE((short)1, "ire"),
      ACE((short)2, "ace"),
      ASE((short)3, "ase"),
      AE((short)4, "ae");

      private static final Map<String, _Fields> byName = new HashMap<String, _Fields>();

      static {
        for (_Fields field : EnumSet.allOf(_Fields.class)) {
          byName.put(field.getFieldName(), field);
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, or null if its not found.
       */
      public static _Fields findByThriftId(int fieldId) {
        switch(fieldId) {
          case 0: // SUCCESS
            return SUCCESS;
          case 1: // IRE
            return IRE;
          case 2: // ACE
            return ACE;
          case 3: // ASE
            return ASE;
          case 4: // 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 IllegalArgumentException("Field " + fieldId + " doesn't exist!");
        return fields;
      }

      /**
       * Find the _Fields constant that matches name, or null if its not found.
       */
      public static _Fields findByName(String name) {
        return byName.get(name);
      }

      private final short _thriftId;
      private final String _fieldName;

      _Fields(short thriftId, String fieldName) {
        _thriftId = thriftId;
        _fieldName = fieldName;
      }

      public short getThriftFieldId() {
        return _thriftId;
      }

      public String getFieldName() {
        return _fieldName;
      }
    }

    // isset id assignments
    private static final int __SUCCESS_ISSET_ID = 0;
    private byte __isset_bitfield = 0;
    public static final Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
    static {
      Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new EnumMap<_Fields, org.apache.thrift.meta_data.FieldMetaData>(_Fields.class);
      tmpMap.put(_Fields.SUCCESS, new org.apache.thrift.meta_data.FieldMetaData("success", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.BOOL)));
      tmpMap.put(_Fields.IRE, new org.apache.thrift.meta_data.FieldMetaData("ire", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRUCT)));
      tmpMap.put(_Fields.ACE, new org.apache.thrift.meta_data.FieldMetaData("ace", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRUCT)));
      tmpMap.put(_Fields.ASE, new org.apache.thrift.meta_data.FieldMetaData("ase", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRUCT)));
      tmpMap.put(_Fields.AE, new org.apache.thrift.meta_data.FieldMetaData("ae", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRUCT)));
      metaDataMap = Collections.unmodifiableMap(tmpMap);
      org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(deleteApplicationModule_result.class, metaDataMap);
    }

    public deleteApplicationModule_result() {
    }

    public deleteApplicationModule_result(
      boolean success,
      org.apache.airavata.model.error.InvalidRequestException ire,
      org.apache.airavata.model.error.AiravataClientException ace,
      org.apache.airavata.model.error.AiravataSystemException ase,
      org.apache.airavata.model.error.AuthorizationException ae)
    {
      this();
      this.success = success;
      setSuccessIsSet(true);
      this.ire = ire;
      this.ace = ace;
      this.ase = ase;
      this.ae = ae;
    }

    /**
     * Performs a deep copy on <i>other</i>.
     */
    public deleteApplicationModule_result(deleteApplicationModule_result other) {
      __isset_bitfield = other.__isset_bitfield;
      this.success = other.success;
      if (other.isSetIre()) {
        this.ire = new org.apache.airavata.model.error.InvalidRequestException(other.ire);
      }
      if (other.isSetAce()) {
        this.ace = new org.apache.airavata.model.error.AiravataClientException(other.ace);
      }
      if (other.isSetAse()) {
        this.ase = new org.apache.airavata.model.error.AiravataSystemException(other.ase);
      }
      if (other.isSetAe()) {
        this.ae = new org.apache.airavata.model.error.AuthorizationException(other.ae);
      }
    }

    public deleteApplicationModule_result deepCopy() {
      return new deleteApplicationModule_result(this);
    }

    @Override
    public void clear() {
      setSuccessIsSet(false);
      this.success = false;
      this.ire = null;
      this.ace = null;
      this.ase = null;
      this.ae = null;
    }

    public boolean isSuccess() {
      return this.success;
    }

    public deleteApplicationModule_result setSuccess(boolean success) {
      this.success = success;
      setSuccessIsSet(true);
      return this;
    }

    public void unsetSuccess() {
      __isset_bitfield = EncodingUtils.clearBit(__isset_bitfield, __SUCCESS_ISSET_ID);
    }

    /** Returns true if field success is set (has been assigned a value) and false otherwise */
    public boolean isSetSuccess() {
      return EncodingUtils.testBit(__isset_bitfield, __SUCCESS_ISSET_ID);
    }

    public void setSuccessIsSet(boolean value) {
      __isset_bitfield = EncodingUtils.setBit(__isset_bitfield, __SUCCESS_ISSET_ID, value);
    }

    public org.apache.airavata.model.error.InvalidRequestException getIre() {
      return this.ire;
    }

    public deleteApplicationModule_result setIre(org.apache.airavata.model.error.InvalidRequestException ire) {
      this.ire = ire;
      return this;
    }

    public void unsetIre() {
      this.ire = null;
    }

    /** Returns true if field ire is set (has been assigned a value) and false otherwise */
    public boolean isSetIre() {
      return this.ire != null;
    }

    public void setIreIsSet(boolean value) {
      if (!value) {
        this.ire = null;
      }
    }

    public org.apache.airavata.model.error.AiravataClientException getAce() {
      return this.ace;
    }

    public deleteApplicationModule_result setAce(org.apache.airavata.model.error.AiravataClientException ace) {
      this.ace = ace;
      return this;
    }

    public void unsetAce() {
      this.ace = null;
    }

    /** Returns true if field ace is set (has been assigned a value) and false otherwise */
    public boolean isSetAce() {
      return this.ace != null;
    }

    public void setAceIsSet(boolean value) {
      if (!value) {
        this.ace = null;
      }
    }

    public org.apache.airavata.model.error.AiravataSystemException getAse() {
      return this.ase;
    }

    public deleteApplicationModule_result setAse(org.apache.airavata.model.error.AiravataSystemException ase) {
      this.ase = ase;
      return this;
    }

    public void unsetAse() {
      this.ase = null;
    }

    /** Returns true if field ase is set (has been assigned a value) and false otherwise */
    public boolean isSetAse() {
      return this.ase != null;
    }

    public void setAseIsSet(boolean value) {
      if (!value) {
        this.ase = null;
      }
    }

    public org.apache.airavata.model.error.AuthorizationException getAe() {
      return this.ae;
    }

    public deleteApplicationModule_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, Object value) {
      switch (field) {
      case SUCCESS:
        if (value == null) {
          unsetSuccess();
        } else {
          setSuccess((Boolean)value);
        }
        break;

      case IRE:
        if (value == null) {
          unsetIre();
        } else {
          setIre((org.apache.airavata.model.error.InvalidRequestException)value);
        }
        break;

      case ACE:
        if (value == null) {
          unsetAce();
        } else {
          setAce((org.apache.airavata.model.error.AiravataClientException)value);
        }
        break;

      case ASE:
        if (value == null) {
          unsetAse();
        } else {
          setAse((org.apache.airavata.model.error.AiravataSystemException)value);
        }
        break;

      case AE:
        if (value == null) {
          unsetAe();
        } else {
          setAe((org.apache.airavata.model.error.AuthorizationException)value);
        }
        break;

      }
    }

    public Object getFieldValue(_Fields field) {
      switch (field) {
      case SUCCESS:
        return Boolean.valueOf(isSuccess());

      case IRE:
        return getIre();

      case ACE:
        return getAce();

      case ASE:
        return getAse();

      case AE:
        return getAe();

      }
      throw new IllegalStateException();
    }

    /** Returns true if field corresponding to fieldID is set (has been assigned a value) and false otherwise */
    public boolean isSet(_Fields field) {
      if (field == null) {
        throw new IllegalArgumentException();
      }

      switch (field) {
      case SUCCESS:
        return isSetSuccess();
      case IRE:
        return isSetIre();
      case ACE:
        return isSetAce();
      case ASE:
        return isSetAse();
      case AE:
        return isSetAe();
      }
      throw new IllegalStateException();
    }

    @Override
    public boolean equals(Object that) {
      if (that == null)
        return false;
      if (that instanceof deleteApplicationModule_result)
        return this.equals((deleteApplicationModule_result)that);
      return false;
    }

    public boolean equals(deleteApplicationModule_result that) {
      if (that == null)
        return false;

      boolean this_present_success = true;
      boolean that_present_success = true;
      if (this_present_success || that_present_success) {
        if (!(this_present_success && that_present_success))
          return false;
        if (this.success != that.success)
          return false;
      }

      boolean this_present_ire = true && this.isSetIre();
      boolean that_present_ire = true && that.isSetIre();
      if (this_present_ire || that_present_ire) {
        if (!(this_present_ire && that_present_ire))
          return false;
        if (!this.ire.equals(that.ire))
          return false;
      }

      boolean this_present_ace = true && this.isSetAce();
      boolean that_present_ace = true && that.isSetAce();
      if (this_present_ace || that_present_ace) {
        if (!(this_present_ace && that_present_ace))
          return false;
        if (!this.ace.equals(that.ace))
          return false;
      }

      boolean this_present_ase = true && this.isSetAse();
      boolean that_present_ase = true && that.isSetAse();
      if (this_present_ase || that_present_ase) {
        if (!(this_present_ase && that_present_ase))
          return false;
        if (!this.ase.equals(that.ase))
          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() {
      List<Object> list = new ArrayList<Object>();

      boolean present_success = true;
      list.add(present_success);
      if (present_success)
        list.add(success);

      boolean present_ire = true && (isSetIre());
      list.add(present_ire);
      if (present_ire)
        list.add(ire);

      boolean present_ace = true && (isSetAce());
      list.add(present_ace);
      if (present_ace)
        list.add(ace);

      boolean present_ase = true && (isSetAse());
      list.add(present_ase);
      if (present_ase)
        list.add(ase);

      boolean present_ae = true && (isSetAe());
      list.add(present_ae);
      if (present_ae)
        list.add(ae);

      return list.hashCode();
    }

    @Override
    public int compareTo(deleteApplicationModule_result other) {
      if (!getClass().equals(other.getClass())) {
        return getClass().getName().compareTo(other.getClass().getName());
      }

      int lastComparison = 0;

      lastComparison = Boolean.valueOf(isSetSuccess()).compareTo(other.isSetSuccess());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetSuccess()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.success, other.success);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = Boolean.valueOf(isSetIre()).compareTo(other.isSetIre());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetIre()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.ire, other.ire);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = Boolean.valueOf(isSetAce()).compareTo(other.isSetAce());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetAce()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.ace, other.ace);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = Boolean.valueOf(isSetAse()).compareTo(other.isSetAse());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetAse()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.ase, other.ase);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = 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 {
      schemes.get(iprot.getScheme()).getScheme().read(iprot, this);
    }

    public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException {
      schemes.get(oprot.getScheme()).getScheme().write(oprot, this);
      }

    @Override
    public String toString() {
      StringBuilder sb = new StringBuilder("deleteApplicationModule_result(");
      boolean first = true;

      sb.append("success:");
      sb.append(this.success);
      first = false;
      if (!first) sb.append(", ");
      sb.append("ire:");
      if (this.ire == null) {
        sb.append("null");
      } else {
        sb.append(this.ire);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("ace:");
      if (this.ace == null) {
        sb.append("null");
      } else {
        sb.append(this.ace);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("ase:");
      if (this.ase == null) {
        sb.append("null");
      } else {
        sb.append(this.ase);
      }
      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, 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 deleteApplicationModule_resultStandardSchemeFactory implements SchemeFactory {
      public deleteApplicationModule_resultStandardScheme getScheme() {
        return new deleteApplicationModule_resultStandardScheme();
      }
    }

    private static class deleteApplicationModule_resultStandardScheme extends StandardScheme<deleteApplicationModule_result> {

      public void read(org.apache.thrift.protocol.TProtocol iprot, deleteApplicationModule_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: // IRE
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.ire = new org.apache.airavata.model.error.InvalidRequestException();
                struct.ire.read(iprot);
                struct.setIreIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 2: // ACE
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.ace = new org.apache.airavata.model.error.AiravataClientException();
                struct.ace.read(iprot);
                struct.setAceIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 3: // ASE
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.ase = new org.apache.airavata.model.error.AiravataSystemException();
                struct.ase.read(iprot);
                struct.setAseIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 4: // 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, deleteApplicationModule_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.ire != null) {
          oprot.writeFieldBegin(IRE_FIELD_DESC);
          struct.ire.write(oprot);
          oprot.writeFieldEnd();
        }
        if (struct.ace != null) {
          oprot.writeFieldBegin(ACE_FIELD_DESC);
          struct.ace.write(oprot);
          oprot.writeFieldEnd();
        }
        if (struct.ase != null) {
          oprot.writeFieldBegin(ASE_FIELD_DESC);
          struct.ase.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 deleteApplicationModule_resultTupleSchemeFactory implements SchemeFactory {
      public deleteApplicationModule_resultTupleScheme getScheme() {
        return new deleteApplicationModule_resultTupleScheme();
      }
    }

    private static class deleteApplicationModule_resultTupleScheme extends TupleScheme<deleteApplicationModule_result> {

      @Override
      public void write(org.apache.thrift.protocol.TProtocol prot, deleteApplicationModule_result struct) throws org.apache.thrift.TException {
        TTupleProtocol oprot = (TTupleProtocol) prot;
        BitSet optionals = new BitSet();
        if (struct.isSetSuccess()) {
          optionals.set(0);
        }
        if (struct.isSetIre()) {
          optionals.set(1);
        }
        if (struct.isSetAce()) {
          optionals.set(2);
        }
        if (struct.isSetAse()) {
          optionals.set(3);
        }
        if (struct.isSetAe()) {
          optionals.set(4);
        }
        oprot.writeBitSet(optionals, 5);
        if (struct.isSetSuccess()) {
          oprot.writeBool(struct.success);
        }
        if (struct.isSetIre()) {
          struct.ire.write(oprot);
        }
        if (struct.isSetAce()) {
          struct.ace.write(oprot);
        }
        if (struct.isSetAse()) {
          struct.ase.write(oprot);
        }
        if (struct.isSetAe()) {
          struct.ae.write(oprot);
        }
      }

      @Override
      public void read(org.apache.thrift.protocol.TProtocol prot, deleteApplicationModule_result struct) throws org.apache.thrift.TException {
        TTupleProtocol iprot = (TTupleProtocol) prot;
        BitSet incoming = iprot.readBitSet(5);
        if (incoming.get(0)) {
          struct.success = iprot.readBool();
          struct.setSuccessIsSet(true);
        }
        if (incoming.get(1)) {
          struct.ire = new org.apache.airavata.model.error.InvalidRequestException();
          struct.ire.read(iprot);
          struct.setIreIsSet(true);
        }
        if (incoming.get(2)) {
          struct.ace = new org.apache.airavata.model.error.AiravataClientException();
          struct.ace.read(iprot);
          struct.setAceIsSet(true);
        }
        if (incoming.get(3)) {
          struct.ase = new org.apache.airavata.model.error.AiravataSystemException();
          struct.ase.read(iprot);
          struct.setAseIsSet(true);
        }
        if (incoming.get(4)) {
          struct.ae = new org.apache.airavata.model.error.AuthorizationException();
          struct.ae.read(iprot);
          struct.setAeIsSet(true);
        }
      }
    }

  }

  public static class registerApplicationDeployment_args implements org.apache.thrift.TBase<registerApplicationDeployment_args, registerApplicationDeployment_args._Fields>, java.io.Serializable, Cloneable, Comparable<registerApplicationDeployment_args>   {
    private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("registerApplicationDeployment_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.protocol.TField APPLICATION_DEPLOYMENT_FIELD_DESC = new org.apache.thrift.protocol.TField("applicationDeployment", org.apache.thrift.protocol.TType.STRUCT, (short)3);

    private static final Map<Class<? extends IScheme>, SchemeFactory> schemes = new HashMap<Class<? extends IScheme>, SchemeFactory>();
    static {
      schemes.put(StandardScheme.class, new registerApplicationDeployment_argsStandardSchemeFactory());
      schemes.put(TupleScheme.class, new registerApplicationDeployment_argsTupleSchemeFactory());
    }

    public org.apache.airavata.model.security.AuthzToken authzToken; // required
    public String gatewayId; // required
    public org.apache.airavata.model.appcatalog.appdeployment.ApplicationDeploymentDescription applicationDeployment; // required

    /** 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"),
      APPLICATION_DEPLOYMENT((short)3, "applicationDeployment");

      private static final Map<String, _Fields> byName = new HashMap<String, _Fields>();

      static {
        for (_Fields field : EnumSet.allOf(_Fields.class)) {
          byName.put(field.getFieldName(), field);
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, or null if its not found.
       */
      public static _Fields findByThriftId(int fieldId) {
        switch(fieldId) {
          case 1: // AUTHZ_TOKEN
            return AUTHZ_TOKEN;
          case 2: // GATEWAY_ID
            return GATEWAY_ID;
          case 3: // APPLICATION_DEPLOYMENT
            return APPLICATION_DEPLOYMENT;
          default:
            return null;
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, throwing an exception
       * if it is not found.
       */
      public static _Fields findByThriftIdOrThrow(int fieldId) {
        _Fields fields = findByThriftId(fieldId);
        if (fields == null) throw new IllegalArgumentException("Field " + fieldId + " doesn't exist!");
        return fields;
      }

      /**
       * Find the _Fields constant that matches name, or null if its not found.
       */
      public static _Fields findByName(String name) {
        return byName.get(name);
      }

      private final short _thriftId;
      private final String _fieldName;

      _Fields(short thriftId, String fieldName) {
        _thriftId = thriftId;
        _fieldName = fieldName;
      }

      public short getThriftFieldId() {
        return _thriftId;
      }

      public String getFieldName() {
        return _fieldName;
      }
    }

    // isset id assignments
    public static final Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
    static {
      Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new EnumMap<_Fields, org.apache.thrift.meta_data.FieldMetaData>(_Fields.class);
      tmpMap.put(_Fields.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)));
      tmpMap.put(_Fields.APPLICATION_DEPLOYMENT, new org.apache.thrift.meta_data.FieldMetaData("applicationDeployment", org.apache.thrift.TFieldRequirementType.REQUIRED, 
          new org.apache.thrift.meta_data.StructMetaData(org.apache.thrift.protocol.TType.STRUCT, org.apache.airavata.model.appcatalog.appdeployment.ApplicationDeploymentDescription.class)));
      metaDataMap = Collections.unmodifiableMap(tmpMap);
      org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(registerApplicationDeployment_args.class, metaDataMap);
    }

    public registerApplicationDeployment_args() {
    }

    public registerApplicationDeployment_args(
      org.apache.airavata.model.security.AuthzToken authzToken,
      String gatewayId,
      org.apache.airavata.model.appcatalog.appdeployment.ApplicationDeploymentDescription applicationDeployment)
    {
      this();
      this.authzToken = authzToken;
      this.gatewayId = gatewayId;
      this.applicationDeployment = applicationDeployment;
    }

    /**
     * Performs a deep copy on <i>other</i>.
     */
    public registerApplicationDeployment_args(registerApplicationDeployment_args other) {
      if (other.isSetAuthzToken()) {
        this.authzToken = new org.apache.airavata.model.security.AuthzToken(other.authzToken);
      }
      if (other.isSetGatewayId()) {
        this.gatewayId = other.gatewayId;
      }
      if (other.isSetApplicationDeployment()) {
        this.applicationDeployment = new org.apache.airavata.model.appcatalog.appdeployment.ApplicationDeploymentDescription(other.applicationDeployment);
      }
    }

    public registerApplicationDeployment_args deepCopy() {
      return new registerApplicationDeployment_args(this);
    }

    @Override
    public void clear() {
      this.authzToken = null;
      this.gatewayId = null;
      this.applicationDeployment = null;
    }

    public org.apache.airavata.model.security.AuthzToken getAuthzToken() {
      return this.authzToken;
    }

    public registerApplicationDeployment_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 String getGatewayId() {
      return this.gatewayId;
    }

    public registerApplicationDeployment_args setGatewayId(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 org.apache.airavata.model.appcatalog.appdeployment.ApplicationDeploymentDescription getApplicationDeployment() {
      return this.applicationDeployment;
    }

    public registerApplicationDeployment_args setApplicationDeployment(org.apache.airavata.model.appcatalog.appdeployment.ApplicationDeploymentDescription applicationDeployment) {
      this.applicationDeployment = applicationDeployment;
      return this;
    }

    public void unsetApplicationDeployment() {
      this.applicationDeployment = null;
    }

    /** Returns true if field applicationDeployment is set (has been assigned a value) and false otherwise */
    public boolean isSetApplicationDeployment() {
      return this.applicationDeployment != null;
    }

    public void setApplicationDeploymentIsSet(boolean value) {
      if (!value) {
        this.applicationDeployment = null;
      }
    }

    public void setFieldValue(_Fields field, 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((String)value);
        }
        break;

      case APPLICATION_DEPLOYMENT:
        if (value == null) {
          unsetApplicationDeployment();
        } else {
          setApplicationDeployment((org.apache.airavata.model.appcatalog.appdeployment.ApplicationDeploymentDescription)value);
        }
        break;

      }
    }

    public Object getFieldValue(_Fields field) {
      switch (field) {
      case AUTHZ_TOKEN:
        return getAuthzToken();

      case GATEWAY_ID:
        return getGatewayId();

      case APPLICATION_DEPLOYMENT:
        return getApplicationDeployment();

      }
      throw new IllegalStateException();
    }

    /** Returns true if field corresponding to fieldID is set (has been assigned a value) and false otherwise */
    public boolean isSet(_Fields field) {
      if (field == null) {
        throw new IllegalArgumentException();
      }

      switch (field) {
      case AUTHZ_TOKEN:
        return isSetAuthzToken();
      case GATEWAY_ID:
        return isSetGatewayId();
      case APPLICATION_DEPLOYMENT:
        return isSetApplicationDeployment();
      }
      throw new IllegalStateException();
    }

    @Override
    public boolean equals(Object that) {
      if (that == null)
        return false;
      if (that instanceof registerApplicationDeployment_args)
        return this.equals((registerApplicationDeployment_args)that);
      return false;
    }

    public boolean equals(registerApplicationDeployment_args that) {
      if (that == null)
        return false;

      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;
      }

      boolean this_present_applicationDeployment = true && this.isSetApplicationDeployment();
      boolean that_present_applicationDeployment = true && that.isSetApplicationDeployment();
      if (this_present_applicationDeployment || that_present_applicationDeployment) {
        if (!(this_present_applicationDeployment && that_present_applicationDeployment))
          return false;
        if (!this.applicationDeployment.equals(that.applicationDeployment))
          return false;
      }

      return true;
    }

    @Override
    public int hashCode() {
      List<Object> list = new ArrayList<Object>();

      boolean present_authzToken = true && (isSetAuthzToken());
      list.add(present_authzToken);
      if (present_authzToken)
        list.add(authzToken);

      boolean present_gatewayId = true && (isSetGatewayId());
      list.add(present_gatewayId);
      if (present_gatewayId)
        list.add(gatewayId);

      boolean present_applicationDeployment = true && (isSetApplicationDeployment());
      list.add(present_applicationDeployment);
      if (present_applicationDeployment)
        list.add(applicationDeployment);

      return list.hashCode();
    }

    @Override
    public int compareTo(registerApplicationDeployment_args other) {
      if (!getClass().equals(other.getClass())) {
        return getClass().getName().compareTo(other.getClass().getName());
      }

      int lastComparison = 0;

      lastComparison = 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 = 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;
        }
      }
      lastComparison = Boolean.valueOf(isSetApplicationDeployment()).compareTo(other.isSetApplicationDeployment());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetApplicationDeployment()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.applicationDeployment, other.applicationDeployment);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      return 0;
    }

    public _Fields fieldForId(int fieldId) {
      return _Fields.findByThriftId(fieldId);
    }

    public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
      schemes.get(iprot.getScheme()).getScheme().read(iprot, this);
    }

    public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException {
      schemes.get(oprot.getScheme()).getScheme().write(oprot, this);
    }

    @Override
    public String toString() {
      StringBuilder sb = new StringBuilder("registerApplicationDeployment_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;
      if (!first) sb.append(", ");
      sb.append("applicationDeployment:");
      if (this.applicationDeployment == null) {
        sb.append("null");
      } else {
        sb.append(this.applicationDeployment);
      }
      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());
      }
      if (applicationDeployment == null) {
        throw new org.apache.thrift.protocol.TProtocolException("Required field 'applicationDeployment' was not present! Struct: " + toString());
      }
      // check for sub-struct validity
      if (authzToken != null) {
        authzToken.validate();
      }
      if (applicationDeployment != null) {
        applicationDeployment.validate();
      }
    }

    private void writeObject(java.io.ObjectOutputStream out) throws java.io.IOException {
      try {
        write(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(out)));
      } catch (org.apache.thrift.TException te) {
        throw new java.io.IOException(te);
      }
    }

    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, ClassNotFoundException {
      try {
        read(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(in)));
      } catch (org.apache.thrift.TException te) {
        throw new java.io.IOException(te);
      }
    }

    private static class registerApplicationDeployment_argsStandardSchemeFactory implements SchemeFactory {
      public registerApplicationDeployment_argsStandardScheme getScheme() {
        return new registerApplicationDeployment_argsStandardScheme();
      }
    }

    private static class registerApplicationDeployment_argsStandardScheme extends StandardScheme<registerApplicationDeployment_args> {

      public void read(org.apache.thrift.protocol.TProtocol iprot, registerApplicationDeployment_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;
            case 3: // APPLICATION_DEPLOYMENT
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.applicationDeployment = new org.apache.airavata.model.appcatalog.appdeployment.ApplicationDeploymentDescription();
                struct.applicationDeployment.read(iprot);
                struct.setApplicationDeploymentIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            default:
              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
          }
          iprot.readFieldEnd();
        }
        iprot.readStructEnd();

        // check for required fields of primitive type, which can't be checked in the validate method
        struct.validate();
      }

      public void write(org.apache.thrift.protocol.TProtocol oprot, registerApplicationDeployment_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();
        }
        if (struct.applicationDeployment != null) {
          oprot.writeFieldBegin(APPLICATION_DEPLOYMENT_FIELD_DESC);
          struct.applicationDeployment.write(oprot);
          oprot.writeFieldEnd();
        }
        oprot.writeFieldStop();
        oprot.writeStructEnd();
      }

    }

    private static class registerApplicationDeployment_argsTupleSchemeFactory implements SchemeFactory {
      public registerApplicationDeployment_argsTupleScheme getScheme() {
        return new registerApplicationDeployment_argsTupleScheme();
      }
    }

    private static class registerApplicationDeployment_argsTupleScheme extends TupleScheme<registerApplicationDeployment_args> {

      @Override
      public void write(org.apache.thrift.protocol.TProtocol prot, registerApplicationDeployment_args struct) throws org.apache.thrift.TException {
        TTupleProtocol oprot = (TTupleProtocol) prot;
        struct.authzToken.write(oprot);
        oprot.writeString(struct.gatewayId);
        struct.applicationDeployment.write(oprot);
      }

      @Override
      public void read(org.apache.thrift.protocol.TProtocol prot, registerApplicationDeployment_args struct) throws org.apache.thrift.TException {
        TTupleProtocol iprot = (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);
        struct.applicationDeployment = new org.apache.airavata.model.appcatalog.appdeployment.ApplicationDeploymentDescription();
        struct.applicationDeployment.read(iprot);
        struct.setApplicationDeploymentIsSet(true);
      }
    }

  }

  public static class registerApplicationDeployment_result implements org.apache.thrift.TBase<registerApplicationDeployment_result, registerApplicationDeployment_result._Fields>, java.io.Serializable, Cloneable, Comparable<registerApplicationDeployment_result>   {
    private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("registerApplicationDeployment_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 IRE_FIELD_DESC = new org.apache.thrift.protocol.TField("ire", org.apache.thrift.protocol.TType.STRUCT, (short)1);
    private static final org.apache.thrift.protocol.TField ACE_FIELD_DESC = new org.apache.thrift.protocol.TField("ace", org.apache.thrift.protocol.TType.STRUCT, (short)2);
    private static final org.apache.thrift.protocol.TField ASE_FIELD_DESC = new org.apache.thrift.protocol.TField("ase", org.apache.thrift.protocol.TType.STRUCT, (short)3);
    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)4);

    private static final Map<Class<? extends IScheme>, SchemeFactory> schemes = new HashMap<Class<? extends IScheme>, SchemeFactory>();
    static {
      schemes.put(StandardScheme.class, new registerApplicationDeployment_resultStandardSchemeFactory());
      schemes.put(TupleScheme.class, new registerApplicationDeployment_resultTupleSchemeFactory());
    }

    public String success; // required
    public org.apache.airavata.model.error.InvalidRequestException ire; // required
    public org.apache.airavata.model.error.AiravataClientException ace; // required
    public org.apache.airavata.model.error.AiravataSystemException ase; // 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"),
      IRE((short)1, "ire"),
      ACE((short)2, "ace"),
      ASE((short)3, "ase"),
      AE((short)4, "ae");

      private static final Map<String, _Fields> byName = new HashMap<String, _Fields>();

      static {
        for (_Fields field : EnumSet.allOf(_Fields.class)) {
          byName.put(field.getFieldName(), field);
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, or null if its not found.
       */
      public static _Fields findByThriftId(int fieldId) {
        switch(fieldId) {
          case 0: // SUCCESS
            return SUCCESS;
          case 1: // IRE
            return IRE;
          case 2: // ACE
            return ACE;
          case 3: // ASE
            return ASE;
          case 4: // 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 IllegalArgumentException("Field " + fieldId + " doesn't exist!");
        return fields;
      }

      /**
       * Find the _Fields constant that matches name, or null if its not found.
       */
      public static _Fields findByName(String name) {
        return byName.get(name);
      }

      private final short _thriftId;
      private final String _fieldName;

      _Fields(short thriftId, String fieldName) {
        _thriftId = thriftId;
        _fieldName = fieldName;
      }

      public short getThriftFieldId() {
        return _thriftId;
      }

      public String getFieldName() {
        return _fieldName;
      }
    }

    // isset id assignments
    public static final Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
    static {
      Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new EnumMap<_Fields, org.apache.thrift.meta_data.FieldMetaData>(_Fields.class);
      tmpMap.put(_Fields.SUCCESS, new org.apache.thrift.meta_data.FieldMetaData("success", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING)));
      tmpMap.put(_Fields.IRE, new org.apache.thrift.meta_data.FieldMetaData("ire", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRUCT)));
      tmpMap.put(_Fields.ACE, new org.apache.thrift.meta_data.FieldMetaData("ace", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRUCT)));
      tmpMap.put(_Fields.ASE, new org.apache.thrift.meta_data.FieldMetaData("ase", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRUCT)));
      tmpMap.put(_Fields.AE, new org.apache.thrift.meta_data.FieldMetaData("ae", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRUCT)));
      metaDataMap = Collections.unmodifiableMap(tmpMap);
      org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(registerApplicationDeployment_result.class, metaDataMap);
    }

    public registerApplicationDeployment_result() {
    }

    public registerApplicationDeployment_result(
      String success,
      org.apache.airavata.model.error.InvalidRequestException ire,
      org.apache.airavata.model.error.AiravataClientException ace,
      org.apache.airavata.model.error.AiravataSystemException ase,
      org.apache.airavata.model.error.AuthorizationException ae)
    {
      this();
      this.success = success;
      this.ire = ire;
      this.ace = ace;
      this.ase = ase;
      this.ae = ae;
    }

    /**
     * Performs a deep copy on <i>other</i>.
     */
    public registerApplicationDeployment_result(registerApplicationDeployment_result other) {
      if (other.isSetSuccess()) {
        this.success = other.success;
      }
      if (other.isSetIre()) {
        this.ire = new org.apache.airavata.model.error.InvalidRequestException(other.ire);
      }
      if (other.isSetAce()) {
        this.ace = new org.apache.airavata.model.error.AiravataClientException(other.ace);
      }
      if (other.isSetAse()) {
        this.ase = new org.apache.airavata.model.error.AiravataSystemException(other.ase);
      }
      if (other.isSetAe()) {
        this.ae = new org.apache.airavata.model.error.AuthorizationException(other.ae);
      }
    }

    public registerApplicationDeployment_result deepCopy() {
      return new registerApplicationDeployment_result(this);
    }

    @Override
    public void clear() {
      this.success = null;
      this.ire = null;
      this.ace = null;
      this.ase = null;
      this.ae = null;
    }

    public String getSuccess() {
      return this.success;
    }

    public registerApplicationDeployment_result setSuccess(String success) {
      this.success = success;
      return this;
    }

    public void unsetSuccess() {
      this.success = null;
    }

    /** Returns true if field success is set (has been assigned a value) and false otherwise */
    public boolean isSetSuccess() {
      return this.success != null;
    }

    public void setSuccessIsSet(boolean value) {
      if (!value) {
        this.success = null;
      }
    }

    public org.apache.airavata.model.error.InvalidRequestException getIre() {
      return this.ire;
    }

    public registerApplicationDeployment_result setIre(org.apache.airavata.model.error.InvalidRequestException ire) {
      this.ire = ire;
      return this;
    }

    public void unsetIre() {
      this.ire = null;
    }

    /** Returns true if field ire is set (has been assigned a value) and false otherwise */
    public boolean isSetIre() {
      return this.ire != null;
    }

    public void setIreIsSet(boolean value) {
      if (!value) {
        this.ire = null;
      }
    }

    public org.apache.airavata.model.error.AiravataClientException getAce() {
      return this.ace;
    }

    public registerApplicationDeployment_result setAce(org.apache.airavata.model.error.AiravataClientException ace) {
      this.ace = ace;
      return this;
    }

    public void unsetAce() {
      this.ace = null;
    }

    /** Returns true if field ace is set (has been assigned a value) and false otherwise */
    public boolean isSetAce() {
      return this.ace != null;
    }

    public void setAceIsSet(boolean value) {
      if (!value) {
        this.ace = null;
      }
    }

    public org.apache.airavata.model.error.AiravataSystemException getAse() {
      return this.ase;
    }

    public registerApplicationDeployment_result setAse(org.apache.airavata.model.error.AiravataSystemException ase) {
      this.ase = ase;
      return this;
    }

    public void unsetAse() {
      this.ase = null;
    }

    /** Returns true if field ase is set (has been assigned a value) and false otherwise */
    public boolean isSetAse() {
      return this.ase != null;
    }

    public void setAseIsSet(boolean value) {
      if (!value) {
        this.ase = null;
      }
    }

    public org.apache.airavata.model.error.AuthorizationException getAe() {
      return this.ae;
    }

    public registerApplicationDeployment_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, Object value) {
      switch (field) {
      case SUCCESS:
        if (value == null) {
          unsetSuccess();
        } else {
          setSuccess((String)value);
        }
        break;

      case IRE:
        if (value == null) {
          unsetIre();
        } else {
          setIre((org.apache.airavata.model.error.InvalidRequestException)value);
        }
        break;

      case ACE:
        if (value == null) {
          unsetAce();
        } else {
          setAce((org.apache.airavata.model.error.AiravataClientException)value);
        }
        break;

      case ASE:
        if (value == null) {
          unsetAse();
        } else {
          setAse((org.apache.airavata.model.error.AiravataSystemException)value);
        }
        break;

      case AE:
        if (value == null) {
          unsetAe();
        } else {
          setAe((org.apache.airavata.model.error.AuthorizationException)value);
        }
        break;

      }
    }

    public Object getFieldValue(_Fields field) {
      switch (field) {
      case SUCCESS:
        return getSuccess();

      case IRE:
        return getIre();

      case ACE:
        return getAce();

      case ASE:
        return getAse();

      case AE:
        return getAe();

      }
      throw new IllegalStateException();
    }

    /** Returns true if field corresponding to fieldID is set (has been assigned a value) and false otherwise */
    public boolean isSet(_Fields field) {
      if (field == null) {
        throw new IllegalArgumentException();
      }

      switch (field) {
      case SUCCESS:
        return isSetSuccess();
      case IRE:
        return isSetIre();
      case ACE:
        return isSetAce();
      case ASE:
        return isSetAse();
      case AE:
        return isSetAe();
      }
      throw new IllegalStateException();
    }

    @Override
    public boolean equals(Object that) {
      if (that == null)
        return false;
      if (that instanceof registerApplicationDeployment_result)
        return this.equals((registerApplicationDeployment_result)that);
      return false;
    }

    public boolean equals(registerApplicationDeployment_result that) {
      if (that == null)
        return false;

      boolean this_present_success = true && this.isSetSuccess();
      boolean that_present_success = true && that.isSetSuccess();
      if (this_present_success || that_present_success) {
        if (!(this_present_success && that_present_success))
          return false;
        if (!this.success.equals(that.success))
          return false;
      }

      boolean this_present_ire = true && this.isSetIre();
      boolean that_present_ire = true && that.isSetIre();
      if (this_present_ire || that_present_ire) {
        if (!(this_present_ire && that_present_ire))
          return false;
        if (!this.ire.equals(that.ire))
          return false;
      }

      boolean this_present_ace = true && this.isSetAce();
      boolean that_present_ace = true && that.isSetAce();
      if (this_present_ace || that_present_ace) {
        if (!(this_present_ace && that_present_ace))
          return false;
        if (!this.ace.equals(that.ace))
          return false;
      }

      boolean this_present_ase = true && this.isSetAse();
      boolean that_present_ase = true && that.isSetAse();
      if (this_present_ase || that_present_ase) {
        if (!(this_present_ase && that_present_ase))
          return false;
        if (!this.ase.equals(that.ase))
          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() {
      List<Object> list = new ArrayList<Object>();

      boolean present_success = true && (isSetSuccess());
      list.add(present_success);
      if (present_success)
        list.add(success);

      boolean present_ire = true && (isSetIre());
      list.add(present_ire);
      if (present_ire)
        list.add(ire);

      boolean present_ace = true && (isSetAce());
      list.add(present_ace);
      if (present_ace)
        list.add(ace);

      boolean present_ase = true && (isSetAse());
      list.add(present_ase);
      if (present_ase)
        list.add(ase);

      boolean present_ae = true && (isSetAe());
      list.add(present_ae);
      if (present_ae)
        list.add(ae);

      return list.hashCode();
    }

    @Override
    public int compareTo(registerApplicationDeployment_result other) {
      if (!getClass().equals(other.getClass())) {
        return getClass().getName().compareTo(other.getClass().getName());
      }

      int lastComparison = 0;

      lastComparison = Boolean.valueOf(isSetSuccess()).compareTo(other.isSetSuccess());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetSuccess()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.success, other.success);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = Boolean.valueOf(isSetIre()).compareTo(other.isSetIre());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetIre()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.ire, other.ire);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = Boolean.valueOf(isSetAce()).compareTo(other.isSetAce());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetAce()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.ace, other.ace);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = Boolean.valueOf(isSetAse()).compareTo(other.isSetAse());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetAse()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.ase, other.ase);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = 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 {
      schemes.get(iprot.getScheme()).getScheme().read(iprot, this);
    }

    public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException {
      schemes.get(oprot.getScheme()).getScheme().write(oprot, this);
      }

    @Override
    public String toString() {
      StringBuilder sb = new StringBuilder("registerApplicationDeployment_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("ire:");
      if (this.ire == null) {
        sb.append("null");
      } else {
        sb.append(this.ire);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("ace:");
      if (this.ace == null) {
        sb.append("null");
      } else {
        sb.append(this.ace);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("ase:");
      if (this.ase == null) {
        sb.append("null");
      } else {
        sb.append(this.ase);
      }
      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, 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 registerApplicationDeployment_resultStandardSchemeFactory implements SchemeFactory {
      public registerApplicationDeployment_resultStandardScheme getScheme() {
        return new registerApplicationDeployment_resultStandardScheme();
      }
    }

    private static class registerApplicationDeployment_resultStandardScheme extends StandardScheme<registerApplicationDeployment_result> {

      public void read(org.apache.thrift.protocol.TProtocol iprot, registerApplicationDeployment_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: // IRE
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.ire = new org.apache.airavata.model.error.InvalidRequestException();
                struct.ire.read(iprot);
                struct.setIreIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 2: // ACE
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.ace = new org.apache.airavata.model.error.AiravataClientException();
                struct.ace.read(iprot);
                struct.setAceIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 3: // ASE
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.ase = new org.apache.airavata.model.error.AiravataSystemException();
                struct.ase.read(iprot);
                struct.setAseIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 4: // 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, registerApplicationDeployment_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.ire != null) {
          oprot.writeFieldBegin(IRE_FIELD_DESC);
          struct.ire.write(oprot);
          oprot.writeFieldEnd();
        }
        if (struct.ace != null) {
          oprot.writeFieldBegin(ACE_FIELD_DESC);
          struct.ace.write(oprot);
          oprot.writeFieldEnd();
        }
        if (struct.ase != null) {
          oprot.writeFieldBegin(ASE_FIELD_DESC);
          struct.ase.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 registerApplicationDeployment_resultTupleSchemeFactory implements SchemeFactory {
      public registerApplicationDeployment_resultTupleScheme getScheme() {
        return new registerApplicationDeployment_resultTupleScheme();
      }
    }

    private static class registerApplicationDeployment_resultTupleScheme extends TupleScheme<registerApplicationDeployment_result> {

      @Override
      public void write(org.apache.thrift.protocol.TProtocol prot, registerApplicationDeployment_result struct) throws org.apache.thrift.TException {
        TTupleProtocol oprot = (TTupleProtocol) prot;
        BitSet optionals = new BitSet();
        if (struct.isSetSuccess()) {
          optionals.set(0);
        }
        if (struct.isSetIre()) {
          optionals.set(1);
        }
        if (struct.isSetAce()) {
          optionals.set(2);
        }
        if (struct.isSetAse()) {
          optionals.set(3);
        }
        if (struct.isSetAe()) {
          optionals.set(4);
        }
        oprot.writeBitSet(optionals, 5);
        if (struct.isSetSuccess()) {
          oprot.writeString(struct.success);
        }
        if (struct.isSetIre()) {
          struct.ire.write(oprot);
        }
        if (struct.isSetAce()) {
          struct.ace.write(oprot);
        }
        if (struct.isSetAse()) {
          struct.ase.write(oprot);
        }
        if (struct.isSetAe()) {
          struct.ae.write(oprot);
        }
      }

      @Override
      public void read(org.apache.thrift.protocol.TProtocol prot, registerApplicationDeployment_result struct) throws org.apache.thrift.TException {
        TTupleProtocol iprot = (TTupleProtocol) prot;
        BitSet incoming = iprot.readBitSet(5);
        if (incoming.get(0)) {
          struct.success = iprot.readString();
          struct.setSuccessIsSet(true);
        }
        if (incoming.get(1)) {
          struct.ire = new org.apache.airavata.model.error.InvalidRequestException();
          struct.ire.read(iprot);
          struct.setIreIsSet(true);
        }
        if (incoming.get(2)) {
          struct.ace = new org.apache.airavata.model.error.AiravataClientException();
          struct.ace.read(iprot);
          struct.setAceIsSet(true);
        }
        if (incoming.get(3)) {
          struct.ase = new org.apache.airavata.model.error.AiravataSystemException();
          struct.ase.read(iprot);
          struct.setAseIsSet(true);
        }
        if (incoming.get(4)) {
          struct.ae = new org.apache.airavata.model.error.AuthorizationException();
          struct.ae.read(iprot);
          struct.setAeIsSet(true);
        }
      }
    }

  }

  public static class getApplicationDeployment_args implements org.apache.thrift.TBase<getApplicationDeployment_args, getApplicationDeployment_args._Fields>, java.io.Serializable, Cloneable, Comparable<getApplicationDeployment_args>   {
    private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("getApplicationDeployment_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 APP_DEPLOYMENT_ID_FIELD_DESC = new org.apache.thrift.protocol.TField("appDeploymentId", org.apache.thrift.protocol.TType.STRING, (short)2);

    private static final Map<Class<? extends IScheme>, SchemeFactory> schemes = new HashMap<Class<? extends IScheme>, SchemeFactory>();
    static {
      schemes.put(StandardScheme.class, new getApplicationDeployment_argsStandardSchemeFactory());
      schemes.put(TupleScheme.class, new getApplicationDeployment_argsTupleSchemeFactory());
    }

    public org.apache.airavata.model.security.AuthzToken authzToken; // required
    public String appDeploymentId; // required

    /** 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"),
      APP_DEPLOYMENT_ID((short)2, "appDeploymentId");

      private static final Map<String, _Fields> byName = new HashMap<String, _Fields>();

      static {
        for (_Fields field : EnumSet.allOf(_Fields.class)) {
          byName.put(field.getFieldName(), field);
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, or null if its not found.
       */
      public static _Fields findByThriftId(int fieldId) {
        switch(fieldId) {
          case 1: // AUTHZ_TOKEN
            return AUTHZ_TOKEN;
          case 2: // APP_DEPLOYMENT_ID
            return APP_DEPLOYMENT_ID;
          default:
            return null;
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, throwing an exception
       * if it is not found.
       */
      public static _Fields findByThriftIdOrThrow(int fieldId) {
        _Fields fields = findByThriftId(fieldId);
        if (fields == null) throw new IllegalArgumentException("Field " + fieldId + " doesn't exist!");
        return fields;
      }

      /**
       * Find the _Fields constant that matches name, or null if its not found.
       */
      public static _Fields findByName(String name) {
        return byName.get(name);
      }

      private final short _thriftId;
      private final String _fieldName;

      _Fields(short thriftId, String fieldName) {
        _thriftId = thriftId;
        _fieldName = fieldName;
      }

      public short getThriftFieldId() {
        return _thriftId;
      }

      public String getFieldName() {
        return _fieldName;
      }
    }

    // isset id assignments
    public static final Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
    static {
      Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new EnumMap<_Fields, org.apache.thrift.meta_data.FieldMetaData>(_Fields.class);
      tmpMap.put(_Fields.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.APP_DEPLOYMENT_ID, new org.apache.thrift.meta_data.FieldMetaData("appDeploymentId", org.apache.thrift.TFieldRequirementType.REQUIRED, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING)));
      metaDataMap = Collections.unmodifiableMap(tmpMap);
      org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(getApplicationDeployment_args.class, metaDataMap);
    }

    public getApplicationDeployment_args() {
    }

    public getApplicationDeployment_args(
      org.apache.airavata.model.security.AuthzToken authzToken,
      String appDeploymentId)
    {
      this();
      this.authzToken = authzToken;
      this.appDeploymentId = appDeploymentId;
    }

    /**
     * Performs a deep copy on <i>other</i>.
     */
    public getApplicationDeployment_args(getApplicationDeployment_args other) {
      if (other.isSetAuthzToken()) {
        this.authzToken = new org.apache.airavata.model.security.AuthzToken(other.authzToken);
      }
      if (other.isSetAppDeploymentId()) {
        this.appDeploymentId = other.appDeploymentId;
      }
    }

    public getApplicationDeployment_args deepCopy() {
      return new getApplicationDeployment_args(this);
    }

    @Override
    public void clear() {
      this.authzToken = null;
      this.appDeploymentId = null;
    }

    public org.apache.airavata.model.security.AuthzToken getAuthzToken() {
      return this.authzToken;
    }

    public getApplicationDeployment_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 String getAppDeploymentId() {
      return this.appDeploymentId;
    }

    public getApplicationDeployment_args setAppDeploymentId(String appDeploymentId) {
      this.appDeploymentId = appDeploymentId;
      return this;
    }

    public void unsetAppDeploymentId() {
      this.appDeploymentId = null;
    }

    /** Returns true if field appDeploymentId is set (has been assigned a value) and false otherwise */
    public boolean isSetAppDeploymentId() {
      return this.appDeploymentId != null;
    }

    public void setAppDeploymentIdIsSet(boolean value) {
      if (!value) {
        this.appDeploymentId = null;
      }
    }

    public void setFieldValue(_Fields field, Object value) {
      switch (field) {
      case AUTHZ_TOKEN:
        if (value == null) {
          unsetAuthzToken();
        } else {
          setAuthzToken((org.apache.airavata.model.security.AuthzToken)value);
        }
        break;

      case APP_DEPLOYMENT_ID:
        if (value == null) {
          unsetAppDeploymentId();
        } else {
          setAppDeploymentId((String)value);
        }
        break;

      }
    }

    public Object getFieldValue(_Fields field) {
      switch (field) {
      case AUTHZ_TOKEN:
        return getAuthzToken();

      case APP_DEPLOYMENT_ID:
        return getAppDeploymentId();

      }
      throw new IllegalStateException();
    }

    /** Returns true if field corresponding to fieldID is set (has been assigned a value) and false otherwise */
    public boolean isSet(_Fields field) {
      if (field == null) {
        throw new IllegalArgumentException();
      }

      switch (field) {
      case AUTHZ_TOKEN:
        return isSetAuthzToken();
      case APP_DEPLOYMENT_ID:
        return isSetAppDeploymentId();
      }
      throw new IllegalStateException();
    }

    @Override
    public boolean equals(Object that) {
      if (that == null)
        return false;
      if (that instanceof getApplicationDeployment_args)
        return this.equals((getApplicationDeployment_args)that);
      return false;
    }

    public boolean equals(getApplicationDeployment_args that) {
      if (that == null)
        return false;

      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_appDeploymentId = true && this.isSetAppDeploymentId();
      boolean that_present_appDeploymentId = true && that.isSetAppDeploymentId();
      if (this_present_appDeploymentId || that_present_appDeploymentId) {
        if (!(this_present_appDeploymentId && that_present_appDeploymentId))
          return false;
        if (!this.appDeploymentId.equals(that.appDeploymentId))
          return false;
      }

      return true;
    }

    @Override
    public int hashCode() {
      List<Object> list = new ArrayList<Object>();

      boolean present_authzToken = true && (isSetAuthzToken());
      list.add(present_authzToken);
      if (present_authzToken)
        list.add(authzToken);

      boolean present_appDeploymentId = true && (isSetAppDeploymentId());
      list.add(present_appDeploymentId);
      if (present_appDeploymentId)
        list.add(appDeploymentId);

      return list.hashCode();
    }

    @Override
    public int compareTo(getApplicationDeployment_args other) {
      if (!getClass().equals(other.getClass())) {
        return getClass().getName().compareTo(other.getClass().getName());
      }

      int lastComparison = 0;

      lastComparison = 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 = Boolean.valueOf(isSetAppDeploymentId()).compareTo(other.isSetAppDeploymentId());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetAppDeploymentId()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.appDeploymentId, other.appDeploymentId);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      return 0;
    }

    public _Fields fieldForId(int fieldId) {
      return _Fields.findByThriftId(fieldId);
    }

    public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
      schemes.get(iprot.getScheme()).getScheme().read(iprot, this);
    }

    public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException {
      schemes.get(oprot.getScheme()).getScheme().write(oprot, this);
    }

    @Override
    public String toString() {
      StringBuilder sb = new StringBuilder("getApplicationDeployment_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("appDeploymentId:");
      if (this.appDeploymentId == null) {
        sb.append("null");
      } else {
        sb.append(this.appDeploymentId);
      }
      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 (appDeploymentId == null) {
        throw new org.apache.thrift.protocol.TProtocolException("Required field 'appDeploymentId' 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, 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 getApplicationDeployment_argsStandardSchemeFactory implements SchemeFactory {
      public getApplicationDeployment_argsStandardScheme getScheme() {
        return new getApplicationDeployment_argsStandardScheme();
      }
    }

    private static class getApplicationDeployment_argsStandardScheme extends StandardScheme<getApplicationDeployment_args> {

      public void read(org.apache.thrift.protocol.TProtocol iprot, getApplicationDeployment_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: // APP_DEPLOYMENT_ID
              if (schemeField.type == org.apache.thrift.protocol.TType.STRING) {
                struct.appDeploymentId = iprot.readString();
                struct.setAppDeploymentIdIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            default:
              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
          }
          iprot.readFieldEnd();
        }
        iprot.readStructEnd();

        // check for required fields of primitive type, which can't be checked in the validate method
        struct.validate();
      }

      public void write(org.apache.thrift.protocol.TProtocol oprot, getApplicationDeployment_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.appDeploymentId != null) {
          oprot.writeFieldBegin(APP_DEPLOYMENT_ID_FIELD_DESC);
          oprot.writeString(struct.appDeploymentId);
          oprot.writeFieldEnd();
        }
        oprot.writeFieldStop();
        oprot.writeStructEnd();
      }

    }

    private static class getApplicationDeployment_argsTupleSchemeFactory implements SchemeFactory {
      public getApplicationDeployment_argsTupleScheme getScheme() {
        return new getApplicationDeployment_argsTupleScheme();
      }
    }

    private static class getApplicationDeployment_argsTupleScheme extends TupleScheme<getApplicationDeployment_args> {

      @Override
      public void write(org.apache.thrift.protocol.TProtocol prot, getApplicationDeployment_args struct) throws org.apache.thrift.TException {
        TTupleProtocol oprot = (TTupleProtocol) prot;
        struct.authzToken.write(oprot);
        oprot.writeString(struct.appDeploymentId);
      }

      @Override
      public void read(org.apache.thrift.protocol.TProtocol prot, getApplicationDeployment_args struct) throws org.apache.thrift.TException {
        TTupleProtocol iprot = (TTupleProtocol) prot;
        struct.authzToken = new org.apache.airavata.model.security.AuthzToken();
        struct.authzToken.read(iprot);
        struct.setAuthzTokenIsSet(true);
        struct.appDeploymentId = iprot.readString();
        struct.setAppDeploymentIdIsSet(true);
      }
    }

  }

  public static class getApplicationDeployment_result implements org.apache.thrift.TBase<getApplicationDeployment_result, getApplicationDeployment_result._Fields>, java.io.Serializable, Cloneable, Comparable<getApplicationDeployment_result>   {
    private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("getApplicationDeployment_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 IRE_FIELD_DESC = new org.apache.thrift.protocol.TField("ire", org.apache.thrift.protocol.TType.STRUCT, (short)1);
    private static final org.apache.thrift.protocol.TField ACE_FIELD_DESC = new org.apache.thrift.protocol.TField("ace", org.apache.thrift.protocol.TType.STRUCT, (short)2);
    private static final org.apache.thrift.protocol.TField ASE_FIELD_DESC = new org.apache.thrift.protocol.TField("ase", org.apache.thrift.protocol.TType.STRUCT, (short)3);
    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)4);

    private static final Map<Class<? extends IScheme>, SchemeFactory> schemes = new HashMap<Class<? extends IScheme>, SchemeFactory>();
    static {
      schemes.put(StandardScheme.class, new getApplicationDeployment_resultStandardSchemeFactory());
      schemes.put(TupleScheme.class, new getApplicationDeployment_resultTupleSchemeFactory());
    }

    public org.apache.airavata.model.appcatalog.appdeployment.ApplicationDeploymentDescription success; // required
    public org.apache.airavata.model.error.InvalidRequestException ire; // required
    public org.apache.airavata.model.error.AiravataClientException ace; // required
    public org.apache.airavata.model.error.AiravataSystemException ase; // 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"),
      IRE((short)1, "ire"),
      ACE((short)2, "ace"),
      ASE((short)3, "ase"),
      AE((short)4, "ae");

      private static final Map<String, _Fields> byName = new HashMap<String, _Fields>();

      static {
        for (_Fields field : EnumSet.allOf(_Fields.class)) {
          byName.put(field.getFieldName(), field);
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, or null if its not found.
       */
      public static _Fields findByThriftId(int fieldId) {
        switch(fieldId) {
          case 0: // SUCCESS
            return SUCCESS;
          case 1: // IRE
            return IRE;
          case 2: // ACE
            return ACE;
          case 3: // ASE
            return ASE;
          case 4: // 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 IllegalArgumentException("Field " + fieldId + " doesn't exist!");
        return fields;
      }

      /**
       * Find the _Fields constant that matches name, or null if its not found.
       */
      public static _Fields findByName(String name) {
        return byName.get(name);
      }

      private final short _thriftId;
      private final String _fieldName;

      _Fields(short thriftId, String fieldName) {
        _thriftId = thriftId;
        _fieldName = fieldName;
      }

      public short getThriftFieldId() {
        return _thriftId;
      }

      public String getFieldName() {
        return _fieldName;
      }
    }

    // isset id assignments
    public static final Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
    static {
      Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new EnumMap<_Fields, org.apache.thrift.meta_data.FieldMetaData>(_Fields.class);
      tmpMap.put(_Fields.SUCCESS, new org.apache.thrift.meta_data.FieldMetaData("success", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.StructMetaData(org.apache.thrift.protocol.TType.STRUCT, org.apache.airavata.model.appcatalog.appdeployment.ApplicationDeploymentDescription.class)));
      tmpMap.put(_Fields.IRE, new org.apache.thrift.meta_data.FieldMetaData("ire", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRUCT)));
      tmpMap.put(_Fields.ACE, new org.apache.thrift.meta_data.FieldMetaData("ace", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRUCT)));
      tmpMap.put(_Fields.ASE, new org.apache.thrift.meta_data.FieldMetaData("ase", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRUCT)));
      tmpMap.put(_Fields.AE, new org.apache.thrift.meta_data.FieldMetaData("ae", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRUCT)));
      metaDataMap = Collections.unmodifiableMap(tmpMap);
      org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(getApplicationDeployment_result.class, metaDataMap);
    }

    public getApplicationDeployment_result() {
    }

    public getApplicationDeployment_result(
      org.apache.airavata.model.appcatalog.appdeployment.ApplicationDeploymentDescription success,
      org.apache.airavata.model.error.InvalidRequestException ire,
      org.apache.airavata.model.error.AiravataClientException ace,
      org.apache.airavata.model.error.AiravataSystemException ase,
      org.apache.airavata.model.error.AuthorizationException ae)
    {
      this();
      this.success = success;
      this.ire = ire;
      this.ace = ace;
      this.ase = ase;
      this.ae = ae;
    }

    /**
     * Performs a deep copy on <i>other</i>.
     */
    public getApplicationDeployment_result(getApplicationDeployment_result other) {
      if (other.isSetSuccess()) {
        this.success = new org.apache.airavata.model.appcatalog.appdeployment.ApplicationDeploymentDescription(other.success);
      }
      if (other.isSetIre()) {
        this.ire = new org.apache.airavata.model.error.InvalidRequestException(other.ire);
      }
      if (other.isSetAce()) {
        this.ace = new org.apache.airavata.model.error.AiravataClientException(other.ace);
      }
      if (other.isSetAse()) {
        this.ase = new org.apache.airavata.model.error.AiravataSystemException(other.ase);
      }
      if (other.isSetAe()) {
        this.ae = new org.apache.airavata.model.error.AuthorizationException(other.ae);
      }
    }

    public getApplicationDeployment_result deepCopy() {
      return new getApplicationDeployment_result(this);
    }

    @Override
    public void clear() {
      this.success = null;
      this.ire = null;
      this.ace = null;
      this.ase = null;
      this.ae = null;
    }

    public org.apache.airavata.model.appcatalog.appdeployment.ApplicationDeploymentDescription getSuccess() {
      return this.success;
    }

    public getApplicationDeployment_result setSuccess(org.apache.airavata.model.appcatalog.appdeployment.ApplicationDeploymentDescription 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.model.error.InvalidRequestException getIre() {
      return this.ire;
    }

    public getApplicationDeployment_result setIre(org.apache.airavata.model.error.InvalidRequestException ire) {
      this.ire = ire;
      return this;
    }

    public void unsetIre() {
      this.ire = null;
    }

    /** Returns true if field ire is set (has been assigned a value) and false otherwise */
    public boolean isSetIre() {
      return this.ire != null;
    }

    public void setIreIsSet(boolean value) {
      if (!value) {
        this.ire = null;
      }
    }

    public org.apache.airavata.model.error.AiravataClientException getAce() {
      return this.ace;
    }

    public getApplicationDeployment_result setAce(org.apache.airavata.model.error.AiravataClientException ace) {
      this.ace = ace;
      return this;
    }

    public void unsetAce() {
      this.ace = null;
    }

    /** Returns true if field ace is set (has been assigned a value) and false otherwise */
    public boolean isSetAce() {
      return this.ace != null;
    }

    public void setAceIsSet(boolean value) {
      if (!value) {
        this.ace = null;
      }
    }

    public org.apache.airavata.model.error.AiravataSystemException getAse() {
      return this.ase;
    }

    public getApplicationDeployment_result setAse(org.apache.airavata.model.error.AiravataSystemException ase) {
      this.ase = ase;
      return this;
    }

    public void unsetAse() {
      this.ase = null;
    }

    /** Returns true if field ase is set (has been assigned a value) and false otherwise */
    public boolean isSetAse() {
      return this.ase != null;
    }

    public void setAseIsSet(boolean value) {
      if (!value) {
        this.ase = null;
      }
    }

    public org.apache.airavata.model.error.AuthorizationException getAe() {
      return this.ae;
    }

    public getApplicationDeployment_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, Object value) {
      switch (field) {
      case SUCCESS:
        if (value == null) {
          unsetSuccess();
        } else {
          setSuccess((org.apache.airavata.model.appcatalog.appdeployment.ApplicationDeploymentDescription)value);
        }
        break;

      case IRE:
        if (value == null) {
          unsetIre();
        } else {
          setIre((org.apache.airavata.model.error.InvalidRequestException)value);
        }
        break;

      case ACE:
        if (value == null) {
          unsetAce();
        } else {
          setAce((org.apache.airavata.model.error.AiravataClientException)value);
        }
        break;

      case ASE:
        if (value == null) {
          unsetAse();
        } else {
          setAse((org.apache.airavata.model.error.AiravataSystemException)value);
        }
        break;

      case AE:
        if (value == null) {
          unsetAe();
        } else {
          setAe((org.apache.airavata.model.error.AuthorizationException)value);
        }
        break;

      }
    }

    public Object getFieldValue(_Fields field) {
      switch (field) {
      case SUCCESS:
        return getSuccess();

      case IRE:
        return getIre();

      case ACE:
        return getAce();

      case ASE:
        return getAse();

      case AE:
        return getAe();

      }
      throw new IllegalStateException();
    }

    /** Returns true if field corresponding to fieldID is set (has been assigned a value) and false otherwise */
    public boolean isSet(_Fields field) {
      if (field == null) {
        throw new IllegalArgumentException();
      }

      switch (field) {
      case SUCCESS:
        return isSetSuccess();
      case IRE:
        return isSetIre();
      case ACE:
        return isSetAce();
      case ASE:
        return isSetAse();
      case AE:
        return isSetAe();
      }
      throw new IllegalStateException();
    }

    @Override
    public boolean equals(Object that) {
      if (that == null)
        return false;
      if (that instanceof getApplicationDeployment_result)
        return this.equals((getApplicationDeployment_result)that);
      return false;
    }

    public boolean equals(getApplicationDeployment_result that) {
      if (that == null)
        return false;

      boolean this_present_success = true && this.isSetSuccess();
      boolean that_present_success = true && that.isSetSuccess();
      if (this_present_success || that_present_success) {
        if (!(this_present_success && that_present_success))
          return false;
        if (!this.success.equals(that.success))
          return false;
      }

      boolean this_present_ire = true && this.isSetIre();
      boolean that_present_ire = true && that.isSetIre();
      if (this_present_ire || that_present_ire) {
        if (!(this_present_ire && that_present_ire))
          return false;
        if (!this.ire.equals(that.ire))
          return false;
      }

      boolean this_present_ace = true && this.isSetAce();
      boolean that_present_ace = true && that.isSetAce();
      if (this_present_ace || that_present_ace) {
        if (!(this_present_ace && that_present_ace))
          return false;
        if (!this.ace.equals(that.ace))
          return false;
      }

      boolean this_present_ase = true && this.isSetAse();
      boolean that_present_ase = true && that.isSetAse();
      if (this_present_ase || that_present_ase) {
        if (!(this_present_ase && that_present_ase))
          return false;
        if (!this.ase.equals(that.ase))
          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() {
      List<Object> list = new ArrayList<Object>();

      boolean present_success = true && (isSetSuccess());
      list.add(present_success);
      if (present_success)
        list.add(success);

      boolean present_ire = true && (isSetIre());
      list.add(present_ire);
      if (present_ire)
        list.add(ire);

      boolean present_ace = true && (isSetAce());
      list.add(present_ace);
      if (present_ace)
        list.add(ace);

      boolean present_ase = true && (isSetAse());
      list.add(present_ase);
      if (present_ase)
        list.add(ase);

      boolean present_ae = true && (isSetAe());
      list.add(present_ae);
      if (present_ae)
        list.add(ae);

      return list.hashCode();
    }

    @Override
    public int compareTo(getApplicationDeployment_result other) {
      if (!getClass().equals(other.getClass())) {
        return getClass().getName().compareTo(other.getClass().getName());
      }

      int lastComparison = 0;

      lastComparison = Boolean.valueOf(isSetSuccess()).compareTo(other.isSetSuccess());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetSuccess()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.success, other.success);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = Boolean.valueOf(isSetIre()).compareTo(other.isSetIre());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetIre()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.ire, other.ire);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = Boolean.valueOf(isSetAce()).compareTo(other.isSetAce());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetAce()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.ace, other.ace);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = Boolean.valueOf(isSetAse()).compareTo(other.isSetAse());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetAse()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.ase, other.ase);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = 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 {
      schemes.get(iprot.getScheme()).getScheme().read(iprot, this);
    }

    public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException {
      schemes.get(oprot.getScheme()).getScheme().write(oprot, this);
      }

    @Override
    public String toString() {
      StringBuilder sb = new StringBuilder("getApplicationDeployment_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("ire:");
      if (this.ire == null) {
        sb.append("null");
      } else {
        sb.append(this.ire);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("ace:");
      if (this.ace == null) {
        sb.append("null");
      } else {
        sb.append(this.ace);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("ase:");
      if (this.ase == null) {
        sb.append("null");
      } else {
        sb.append(this.ase);
      }
      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, 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 getApplicationDeployment_resultStandardSchemeFactory implements SchemeFactory {
      public getApplicationDeployment_resultStandardScheme getScheme() {
        return new getApplicationDeployment_resultStandardScheme();
      }
    }

    private static class getApplicationDeployment_resultStandardScheme extends StandardScheme<getApplicationDeployment_result> {

      public void read(org.apache.thrift.protocol.TProtocol iprot, getApplicationDeployment_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.appcatalog.appdeployment.ApplicationDeploymentDescription();
                struct.success.read(iprot);
                struct.setSuccessIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 1: // IRE
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.ire = new org.apache.airavata.model.error.InvalidRequestException();
                struct.ire.read(iprot);
                struct.setIreIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 2: // ACE
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.ace = new org.apache.airavata.model.error.AiravataClientException();
                struct.ace.read(iprot);
                struct.setAceIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 3: // ASE
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.ase = new org.apache.airavata.model.error.AiravataSystemException();
                struct.ase.read(iprot);
                struct.setAseIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 4: // 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, getApplicationDeployment_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.ire != null) {
          oprot.writeFieldBegin(IRE_FIELD_DESC);
          struct.ire.write(oprot);
          oprot.writeFieldEnd();
        }
        if (struct.ace != null) {
          oprot.writeFieldBegin(ACE_FIELD_DESC);
          struct.ace.write(oprot);
          oprot.writeFieldEnd();
        }
        if (struct.ase != null) {
          oprot.writeFieldBegin(ASE_FIELD_DESC);
          struct.ase.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 getApplicationDeployment_resultTupleSchemeFactory implements SchemeFactory {
      public getApplicationDeployment_resultTupleScheme getScheme() {
        return new getApplicationDeployment_resultTupleScheme();
      }
    }

    private static class getApplicationDeployment_resultTupleScheme extends TupleScheme<getApplicationDeployment_result> {

      @Override
      public void write(org.apache.thrift.protocol.TProtocol prot, getApplicationDeployment_result struct) throws org.apache.thrift.TException {
        TTupleProtocol oprot = (TTupleProtocol) prot;
        BitSet optionals = new BitSet();
        if (struct.isSetSuccess()) {
          optionals.set(0);
        }
        if (struct.isSetIre()) {
          optionals.set(1);
        }
        if (struct.isSetAce()) {
          optionals.set(2);
        }
        if (struct.isSetAse()) {
          optionals.set(3);
        }
        if (struct.isSetAe()) {
          optionals.set(4);
        }
        oprot.writeBitSet(optionals, 5);
        if (struct.isSetSuccess()) {
          struct.success.write(oprot);
        }
        if (struct.isSetIre()) {
          struct.ire.write(oprot);
        }
        if (struct.isSetAce()) {
          struct.ace.write(oprot);
        }
        if (struct.isSetAse()) {
          struct.ase.write(oprot);
        }
        if (struct.isSetAe()) {
          struct.ae.write(oprot);
        }
      }

      @Override
      public void read(org.apache.thrift.protocol.TProtocol prot, getApplicationDeployment_result struct) throws org.apache.thrift.TException {
        TTupleProtocol iprot = (TTupleProtocol) prot;
        BitSet incoming = iprot.readBitSet(5);
        if (incoming.get(0)) {
          struct.success = new org.apache.airavata.model.appcatalog.appdeployment.ApplicationDeploymentDescription();
          struct.success.read(iprot);
          struct.setSuccessIsSet(true);
        }
        if (incoming.get(1)) {
          struct.ire = new org.apache.airavata.model.error.InvalidRequestException();
          struct.ire.read(iprot);
          struct.setIreIsSet(true);
        }
        if (incoming.get(2)) {
          struct.ace = new org.apache.airavata.model.error.AiravataClientException();
          struct.ace.read(iprot);
          struct.setAceIsSet(true);
        }
        if (incoming.get(3)) {
          struct.ase = new org.apache.airavata.model.error.AiravataSystemException();
          struct.ase.read(iprot);
          struct.setAseIsSet(true);
        }
        if (incoming.get(4)) {
          struct.ae = new org.apache.airavata.model.error.AuthorizationException();
          struct.ae.read(iprot);
          struct.setAeIsSet(true);
        }
      }
    }

  }

  public static class updateApplicationDeployment_args implements org.apache.thrift.TBase<updateApplicationDeployment_args, updateApplicationDeployment_args._Fields>, java.io.Serializable, Cloneable, Comparable<updateApplicationDeployment_args>   {
    private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("updateApplicationDeployment_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 APP_DEPLOYMENT_ID_FIELD_DESC = new org.apache.thrift.protocol.TField("appDeploymentId", org.apache.thrift.protocol.TType.STRING, (short)2);
    private static final org.apache.thrift.protocol.TField APPLICATION_DEPLOYMENT_FIELD_DESC = new org.apache.thrift.protocol.TField("applicationDeployment", org.apache.thrift.protocol.TType.STRUCT, (short)3);

    private static final Map<Class<? extends IScheme>, SchemeFactory> schemes = new HashMap<Class<? extends IScheme>, SchemeFactory>();
    static {
      schemes.put(StandardScheme.class, new updateApplicationDeployment_argsStandardSchemeFactory());
      schemes.put(TupleScheme.class, new updateApplicationDeployment_argsTupleSchemeFactory());
    }

    public org.apache.airavata.model.security.AuthzToken authzToken; // required
    public String appDeploymentId; // required
    public org.apache.airavata.model.appcatalog.appdeployment.ApplicationDeploymentDescription applicationDeployment; // required

    /** 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"),
      APP_DEPLOYMENT_ID((short)2, "appDeploymentId"),
      APPLICATION_DEPLOYMENT((short)3, "applicationDeployment");

      private static final Map<String, _Fields> byName = new HashMap<String, _Fields>();

      static {
        for (_Fields field : EnumSet.allOf(_Fields.class)) {
          byName.put(field.getFieldName(), field);
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, or null if its not found.
       */
      public static _Fields findByThriftId(int fieldId) {
        switch(fieldId) {
          case 1: // AUTHZ_TOKEN
            return AUTHZ_TOKEN;
          case 2: // APP_DEPLOYMENT_ID
            return APP_DEPLOYMENT_ID;
          case 3: // APPLICATION_DEPLOYMENT
            return APPLICATION_DEPLOYMENT;
          default:
            return null;
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, throwing an exception
       * if it is not found.
       */
      public static _Fields findByThriftIdOrThrow(int fieldId) {
        _Fields fields = findByThriftId(fieldId);
        if (fields == null) throw new IllegalArgumentException("Field " + fieldId + " doesn't exist!");
        return fields;
      }

      /**
       * Find the _Fields constant that matches name, or null if its not found.
       */
      public static _Fields findByName(String name) {
        return byName.get(name);
      }

      private final short _thriftId;
      private final String _fieldName;

      _Fields(short thriftId, String fieldName) {
        _thriftId = thriftId;
        _fieldName = fieldName;
      }

      public short getThriftFieldId() {
        return _thriftId;
      }

      public String getFieldName() {
        return _fieldName;
      }
    }

    // isset id assignments
    public static final Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
    static {
      Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new EnumMap<_Fields, org.apache.thrift.meta_data.FieldMetaData>(_Fields.class);
      tmpMap.put(_Fields.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.APP_DEPLOYMENT_ID, new org.apache.thrift.meta_data.FieldMetaData("appDeploymentId", org.apache.thrift.TFieldRequirementType.REQUIRED, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING)));
      tmpMap.put(_Fields.APPLICATION_DEPLOYMENT, new org.apache.thrift.meta_data.FieldMetaData("applicationDeployment", org.apache.thrift.TFieldRequirementType.REQUIRED, 
          new org.apache.thrift.meta_data.StructMetaData(org.apache.thrift.protocol.TType.STRUCT, org.apache.airavata.model.appcatalog.appdeployment.ApplicationDeploymentDescription.class)));
      metaDataMap = Collections.unmodifiableMap(tmpMap);
      org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(updateApplicationDeployment_args.class, metaDataMap);
    }

    public updateApplicationDeployment_args() {
    }

    public updateApplicationDeployment_args(
      org.apache.airavata.model.security.AuthzToken authzToken,
      String appDeploymentId,
      org.apache.airavata.model.appcatalog.appdeployment.ApplicationDeploymentDescription applicationDeployment)
    {
      this();
      this.authzToken = authzToken;
      this.appDeploymentId = appDeploymentId;
      this.applicationDeployment = applicationDeployment;
    }

    /**
     * Performs a deep copy on <i>other</i>.
     */
    public updateApplicationDeployment_args(updateApplicationDeployment_args other) {
      if (other.isSetAuthzToken()) {
        this.authzToken = new org.apache.airavata.model.security.AuthzToken(other.authzToken);
      }
      if (other.isSetAppDeploymentId()) {
        this.appDeploymentId = other.appDeploymentId;
      }
      if (other.isSetApplicationDeployment()) {
        this.applicationDeployment = new org.apache.airavata.model.appcatalog.appdeployment.ApplicationDeploymentDescription(other.applicationDeployment);
      }
    }

    public updateApplicationDeployment_args deepCopy() {
      return new updateApplicationDeployment_args(this);
    }

    @Override
    public void clear() {
      this.authzToken = null;
      this.appDeploymentId = null;
      this.applicationDeployment = null;
    }

    public org.apache.airavata.model.security.AuthzToken getAuthzToken() {
      return this.authzToken;
    }

    public updateApplicationDeployment_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 String getAppDeploymentId() {
      return this.appDeploymentId;
    }

    public updateApplicationDeployment_args setAppDeploymentId(String appDeploymentId) {
      this.appDeploymentId = appDeploymentId;
      return this;
    }

    public void unsetAppDeploymentId() {
      this.appDeploymentId = null;
    }

    /** Returns true if field appDeploymentId is set (has been assigned a value) and false otherwise */
    public boolean isSetAppDeploymentId() {
      return this.appDeploymentId != null;
    }

    public void setAppDeploymentIdIsSet(boolean value) {
      if (!value) {
        this.appDeploymentId = null;
      }
    }

    public org.apache.airavata.model.appcatalog.appdeployment.ApplicationDeploymentDescription getApplicationDeployment() {
      return this.applicationDeployment;
    }

    public updateApplicationDeployment_args setApplicationDeployment(org.apache.airavata.model.appcatalog.appdeployment.ApplicationDeploymentDescription applicationDeployment) {
      this.applicationDeployment = applicationDeployment;
      return this;
    }

    public void unsetApplicationDeployment() {
      this.applicationDeployment = null;
    }

    /** Returns true if field applicationDeployment is set (has been assigned a value) and false otherwise */
    public boolean isSetApplicationDeployment() {
      return this.applicationDeployment != null;
    }

    public void setApplicationDeploymentIsSet(boolean value) {
      if (!value) {
        this.applicationDeployment = null;
      }
    }

    public void setFieldValue(_Fields field, Object value) {
      switch (field) {
      case AUTHZ_TOKEN:
        if (value == null) {
          unsetAuthzToken();
        } else {
          setAuthzToken((org.apache.airavata.model.security.AuthzToken)value);
        }
        break;

      case APP_DEPLOYMENT_ID:
        if (value == null) {
          unsetAppDeploymentId();
        } else {
          setAppDeploymentId((String)value);
        }
        break;

      case APPLICATION_DEPLOYMENT:
        if (value == null) {
          unsetApplicationDeployment();
        } else {
          setApplicationDeployment((org.apache.airavata.model.appcatalog.appdeployment.ApplicationDeploymentDescription)value);
        }
        break;

      }
    }

    public Object getFieldValue(_Fields field) {
      switch (field) {
      case AUTHZ_TOKEN:
        return getAuthzToken();

      case APP_DEPLOYMENT_ID:
        return getAppDeploymentId();

      case APPLICATION_DEPLOYMENT:
        return getApplicationDeployment();

      }
      throw new IllegalStateException();
    }

    /** Returns true if field corresponding to fieldID is set (has been assigned a value) and false otherwise */
    public boolean isSet(_Fields field) {
      if (field == null) {
        throw new IllegalArgumentException();
      }

      switch (field) {
      case AUTHZ_TOKEN:
        return isSetAuthzToken();
      case APP_DEPLOYMENT_ID:
        return isSetAppDeploymentId();
      case APPLICATION_DEPLOYMENT:
        return isSetApplicationDeployment();
      }
      throw new IllegalStateException();
    }

    @Override
    public boolean equals(Object that) {
      if (that == null)
        return false;
      if (that instanceof updateApplicationDeployment_args)
        return this.equals((updateApplicationDeployment_args)that);
      return false;
    }

    public boolean equals(updateApplicationDeployment_args that) {
      if (that == null)
        return false;

      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_appDeploymentId = true && this.isSetAppDeploymentId();
      boolean that_present_appDeploymentId = true && that.isSetAppDeploymentId();
      if (this_present_appDeploymentId || that_present_appDeploymentId) {
        if (!(this_present_appDeploymentId && that_present_appDeploymentId))
          return false;
        if (!this.appDeploymentId.equals(that.appDeploymentId))
          return false;
      }

      boolean this_present_applicationDeployment = true && this.isSetApplicationDeployment();
      boolean that_present_applicationDeployment = true && that.isSetApplicationDeployment();
      if (this_present_applicationDeployment || that_present_applicationDeployment) {
        if (!(this_present_applicationDeployment && that_present_applicationDeployment))
          return false;
        if (!this.applicationDeployment.equals(that.applicationDeployment))
          return false;
      }

      return true;
    }

    @Override
    public int hashCode() {
      List<Object> list = new ArrayList<Object>();

      boolean present_authzToken = true && (isSetAuthzToken());
      list.add(present_authzToken);
      if (present_authzToken)
        list.add(authzToken);

      boolean present_appDeploymentId = true && (isSetAppDeploymentId());
      list.add(present_appDeploymentId);
      if (present_appDeploymentId)
        list.add(appDeploymentId);

      boolean present_applicationDeployment = true && (isSetApplicationDeployment());
      list.add(present_applicationDeployment);
      if (present_applicationDeployment)
        list.add(applicationDeployment);

      return list.hashCode();
    }

    @Override
    public int compareTo(updateApplicationDeployment_args other) {
      if (!getClass().equals(other.getClass())) {
        return getClass().getName().compareTo(other.getClass().getName());
      }

      int lastComparison = 0;

      lastComparison = 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 = Boolean.valueOf(isSetAppDeploymentId()).compareTo(other.isSetAppDeploymentId());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetAppDeploymentId()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.appDeploymentId, other.appDeploymentId);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = Boolean.valueOf(isSetApplicationDeployment()).compareTo(other.isSetApplicationDeployment());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetApplicationDeployment()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.applicationDeployment, other.applicationDeployment);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      return 0;
    }

    public _Fields fieldForId(int fieldId) {
      return _Fields.findByThriftId(fieldId);
    }

    public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
      schemes.get(iprot.getScheme()).getScheme().read(iprot, this);
    }

    public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException {
      schemes.get(oprot.getScheme()).getScheme().write(oprot, this);
    }

    @Override
    public String toString() {
      StringBuilder sb = new StringBuilder("updateApplicationDeployment_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("appDeploymentId:");
      if (this.appDeploymentId == null) {
        sb.append("null");
      } else {
        sb.append(this.appDeploymentId);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("applicationDeployment:");
      if (this.applicationDeployment == null) {
        sb.append("null");
      } else {
        sb.append(this.applicationDeployment);
      }
      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 (appDeploymentId == null) {
        throw new org.apache.thrift.protocol.TProtocolException("Required field 'appDeploymentId' was not present! Struct: " + toString());
      }
      if (applicationDeployment == null) {
        throw new org.apache.thrift.protocol.TProtocolException("Required field 'applicationDeployment' was not present! Struct: " + toString());
      }
      // check for sub-struct validity
      if (authzToken != null) {
        authzToken.validate();
      }
      if (applicationDeployment != null) {
        applicationDeployment.validate();
      }
    }

    private void writeObject(java.io.ObjectOutputStream out) throws java.io.IOException {
      try {
        write(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(out)));
      } catch (org.apache.thrift.TException te) {
        throw new java.io.IOException(te);
      }
    }

    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, ClassNotFoundException {
      try {
        read(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(in)));
      } catch (org.apache.thrift.TException te) {
        throw new java.io.IOException(te);
      }
    }

    private static class updateApplicationDeployment_argsStandardSchemeFactory implements SchemeFactory {
      public updateApplicationDeployment_argsStandardScheme getScheme() {
        return new updateApplicationDeployment_argsStandardScheme();
      }
    }

    private static class updateApplicationDeployment_argsStandardScheme extends StandardScheme<updateApplicationDeployment_args> {

      public void read(org.apache.thrift.protocol.TProtocol iprot, updateApplicationDeployment_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: // APP_DEPLOYMENT_ID
              if (schemeField.type == org.apache.thrift.protocol.TType.STRING) {
                struct.appDeploymentId = iprot.readString();
                struct.setAppDeploymentIdIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 3: // APPLICATION_DEPLOYMENT
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.applicationDeployment = new org.apache.airavata.model.appcatalog.appdeployment.ApplicationDeploymentDescription();
                struct.applicationDeployment.read(iprot);
                struct.setApplicationDeploymentIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            default:
              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
          }
          iprot.readFieldEnd();
        }
        iprot.readStructEnd();

        // check for required fields of primitive type, which can't be checked in the validate method
        struct.validate();
      }

      public void write(org.apache.thrift.protocol.TProtocol oprot, updateApplicationDeployment_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.appDeploymentId != null) {
          oprot.writeFieldBegin(APP_DEPLOYMENT_ID_FIELD_DESC);
          oprot.writeString(struct.appDeploymentId);
          oprot.writeFieldEnd();
        }
        if (struct.applicationDeployment != null) {
          oprot.writeFieldBegin(APPLICATION_DEPLOYMENT_FIELD_DESC);
          struct.applicationDeployment.write(oprot);
          oprot.writeFieldEnd();
        }
        oprot.writeFieldStop();
        oprot.writeStructEnd();
      }

    }

    private static class updateApplicationDeployment_argsTupleSchemeFactory implements SchemeFactory {
      public updateApplicationDeployment_argsTupleScheme getScheme() {
        return new updateApplicationDeployment_argsTupleScheme();
      }
    }

    private static class updateApplicationDeployment_argsTupleScheme extends TupleScheme<updateApplicationDeployment_args> {

      @Override
      public void write(org.apache.thrift.protocol.TProtocol prot, updateApplicationDeployment_args struct) throws org.apache.thrift.TException {
        TTupleProtocol oprot = (TTupleProtocol) prot;
        struct.authzToken.write(oprot);
        oprot.writeString(struct.appDeploymentId);
        struct.applicationDeployment.write(oprot);
      }

      @Override
      public void read(org.apache.thrift.protocol.TProtocol prot, updateApplicationDeployment_args struct) throws org.apache.thrift.TException {
        TTupleProtocol iprot = (TTupleProtocol) prot;
        struct.authzToken = new org.apache.airavata.model.security.AuthzToken();
        struct.authzToken.read(iprot);
        struct.setAuthzTokenIsSet(true);
        struct.appDeploymentId = iprot.readString();
        struct.setAppDeploymentIdIsSet(true);
        struct.applicationDeployment = new org.apache.airavata.model.appcatalog.appdeployment.ApplicationDeploymentDescription();
        struct.applicationDeployment.read(iprot);
        struct.setApplicationDeploymentIsSet(true);
      }
    }

  }

  public static class updateApplicationDeployment_result implements org.apache.thrift.TBase<updateApplicationDeployment_result, updateApplicationDeployment_result._Fields>, java.io.Serializable, Cloneable, Comparable<updateApplicationDeployment_result>   {
    private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("updateApplicationDeployment_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 IRE_FIELD_DESC = new org.apache.thrift.protocol.TField("ire", org.apache.thrift.protocol.TType.STRUCT, (short)1);
    private static final org.apache.thrift.protocol.TField ACE_FIELD_DESC = new org.apache.thrift.protocol.TField("ace", org.apache.thrift.protocol.TType.STRUCT, (short)2);
    private static final org.apache.thrift.protocol.TField ASE_FIELD_DESC = new org.apache.thrift.protocol.TField("ase", org.apache.thrift.protocol.TType.STRUCT, (short)3);
    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)4);

    private static final Map<Class<? extends IScheme>, SchemeFactory> schemes = new HashMap<Class<? extends IScheme>, SchemeFactory>();
    static {
      schemes.put(StandardScheme.class, new updateApplicationDeployment_resultStandardSchemeFactory());
      schemes.put(TupleScheme.class, new updateApplicationDeployment_resultTupleSchemeFactory());
    }

    public boolean success; // required
    public org.apache.airavata.model.error.InvalidRequestException ire; // required
    public org.apache.airavata.model.error.AiravataClientException ace; // required
    public org.apache.airavata.model.error.AiravataSystemException ase; // 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"),
      IRE((short)1, "ire"),
      ACE((short)2, "ace"),
      ASE((short)3, "ase"),
      AE((short)4, "ae");

      private static final Map<String, _Fields> byName = new HashMap<String, _Fields>();

      static {
        for (_Fields field : EnumSet.allOf(_Fields.class)) {
          byName.put(field.getFieldName(), field);
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, or null if its not found.
       */
      public static _Fields findByThriftId(int fieldId) {
        switch(fieldId) {
          case 0: // SUCCESS
            return SUCCESS;
          case 1: // IRE
            return IRE;
          case 2: // ACE
            return ACE;
          case 3: // ASE
            return ASE;
          case 4: // 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 IllegalArgumentException("Field " + fieldId + " doesn't exist!");
        return fields;
      }

      /**
       * Find the _Fields constant that matches name, or null if its not found.
       */
      public static _Fields findByName(String name) {
        return byName.get(name);
      }

      private final short _thriftId;
      private final String _fieldName;

      _Fields(short thriftId, String fieldName) {
        _thriftId = thriftId;
        _fieldName = fieldName;
      }

      public short getThriftFieldId() {
        return _thriftId;
      }

      public String getFieldName() {
        return _fieldName;
      }
    }

    // isset id assignments
    private static final int __SUCCESS_ISSET_ID = 0;
    private byte __isset_bitfield = 0;
    public static final Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
    static {
      Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new EnumMap<_Fields, org.apache.thrift.meta_data.FieldMetaData>(_Fields.class);
      tmpMap.put(_Fields.SUCCESS, new org.apache.thrift.meta_data.FieldMetaData("success", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.BOOL)));
      tmpMap.put(_Fields.IRE, new org.apache.thrift.meta_data.FieldMetaData("ire", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRUCT)));
      tmpMap.put(_Fields.ACE, new org.apache.thrift.meta_data.FieldMetaData("ace", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRUCT)));
      tmpMap.put(_Fields.ASE, new org.apache.thrift.meta_data.FieldMetaData("ase", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRUCT)));
      tmpMap.put(_Fields.AE, new org.apache.thrift.meta_data.FieldMetaData("ae", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRUCT)));
      metaDataMap = Collections.unmodifiableMap(tmpMap);
      org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(updateApplicationDeployment_result.class, metaDataMap);
    }

    public updateApplicationDeployment_result() {
    }

    public updateApplicationDeployment_result(
      boolean success,
      org.apache.airavata.model.error.InvalidRequestException ire,
      org.apache.airavata.model.error.AiravataClientException ace,
      org.apache.airavata.model.error.AiravataSystemException ase,
      org.apache.airavata.model.error.AuthorizationException ae)
    {
      this();
      this.success = success;
      setSuccessIsSet(true);
      this.ire = ire;
      this.ace = ace;
      this.ase = ase;
      this.ae = ae;
    }

    /**
     * Performs a deep copy on <i>other</i>.
     */
    public updateApplicationDeployment_result(updateApplicationDeployment_result other) {
      __isset_bitfield = other.__isset_bitfield;
      this.success = other.success;
      if (other.isSetIre()) {
        this.ire = new org.apache.airavata.model.error.InvalidRequestException(other.ire);
      }
      if (other.isSetAce()) {
        this.ace = new org.apache.airavata.model.error.AiravataClientException(other.ace);
      }
      if (other.isSetAse()) {
        this.ase = new org.apache.airavata.model.error.AiravataSystemException(other.ase);
      }
      if (other.isSetAe()) {
        this.ae = new org.apache.airavata.model.error.AuthorizationException(other.ae);
      }
    }

    public updateApplicationDeployment_result deepCopy() {
      return new updateApplicationDeployment_result(this);
    }

    @Override
    public void clear() {
      setSuccessIsSet(false);
      this.success = false;
      this.ire = null;
      this.ace = null;
      this.ase = null;
      this.ae = null;
    }

    public boolean isSuccess() {
      return this.success;
    }

    public updateApplicationDeployment_result setSuccess(boolean success) {
      this.success = success;
      setSuccessIsSet(true);
      return this;
    }

    public void unsetSuccess() {
      __isset_bitfield = EncodingUtils.clearBit(__isset_bitfield, __SUCCESS_ISSET_ID);
    }

    /** Returns true if field success is set (has been assigned a value) and false otherwise */
    public boolean isSetSuccess() {
      return EncodingUtils.testBit(__isset_bitfield, __SUCCESS_ISSET_ID);
    }

    public void setSuccessIsSet(boolean value) {
      __isset_bitfield = EncodingUtils.setBit(__isset_bitfield, __SUCCESS_ISSET_ID, value);
    }

    public org.apache.airavata.model.error.InvalidRequestException getIre() {
      return this.ire;
    }

    public updateApplicationDeployment_result setIre(org.apache.airavata.model.error.InvalidRequestException ire) {
      this.ire = ire;
      return this;
    }

    public void unsetIre() {
      this.ire = null;
    }

    /** Returns true if field ire is set (has been assigned a value) and false otherwise */
    public boolean isSetIre() {
      return this.ire != null;
    }

    public void setIreIsSet(boolean value) {
      if (!value) {
        this.ire = null;
      }
    }

    public org.apache.airavata.model.error.AiravataClientException getAce() {
      return this.ace;
    }

    public updateApplicationDeployment_result setAce(org.apache.airavata.model.error.AiravataClientException ace) {
      this.ace = ace;
      return this;
    }

    public void unsetAce() {
      this.ace = null;
    }

    /** Returns true if field ace is set (has been assigned a value) and false otherwise */
    public boolean isSetAce() {
      return this.ace != null;
    }

    public void setAceIsSet(boolean value) {
      if (!value) {
        this.ace = null;
      }
    }

    public org.apache.airavata.model.error.AiravataSystemException getAse() {
      return this.ase;
    }

    public updateApplicationDeployment_result setAse(org.apache.airavata.model.error.AiravataSystemException ase) {
      this.ase = ase;
      return this;
    }

    public void unsetAse() {
      this.ase = null;
    }

    /** Returns true if field ase is set (has been assigned a value) and false otherwise */
    public boolean isSetAse() {
      return this.ase != null;
    }

    public void setAseIsSet(boolean value) {
      if (!value) {
        this.ase = null;
      }
    }

    public org.apache.airavata.model.error.AuthorizationException getAe() {
      return this.ae;
    }

    public updateApplicationDeployment_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, Object value) {
      switch (field) {
      case SUCCESS:
        if (value == null) {
          unsetSuccess();
        } else {
          setSuccess((Boolean)value);
        }
        break;

      case IRE:
        if (value == null) {
          unsetIre();
        } else {
          setIre((org.apache.airavata.model.error.InvalidRequestException)value);
        }
        break;

      case ACE:
        if (value == null) {
          unsetAce();
        } else {
          setAce((org.apache.airavata.model.error.AiravataClientException)value);
        }
        break;

      case ASE:
        if (value == null) {
          unsetAse();
        } else {
          setAse((org.apache.airavata.model.error.AiravataSystemException)value);
        }
        break;

      case AE:
        if (value == null) {
          unsetAe();
        } else {
          setAe((org.apache.airavata.model.error.AuthorizationException)value);
        }
        break;

      }
    }

    public Object getFieldValue(_Fields field) {
      switch (field) {
      case SUCCESS:
        return Boolean.valueOf(isSuccess());

      case IRE:
        return getIre();

      case ACE:
        return getAce();

      case ASE:
        return getAse();

      case AE:
        return getAe();

      }
      throw new IllegalStateException();
    }

    /** Returns true if field corresponding to fieldID is set (has been assigned a value) and false otherwise */
    public boolean isSet(_Fields field) {
      if (field == null) {
        throw new IllegalArgumentException();
      }

      switch (field) {
      case SUCCESS:
        return isSetSuccess();
      case IRE:
        return isSetIre();
      case ACE:
        return isSetAce();
      case ASE:
        return isSetAse();
      case AE:
        return isSetAe();
      }
      throw new IllegalStateException();
    }

    @Override
    public boolean equals(Object that) {
      if (that == null)
        return false;
      if (that instanceof updateApplicationDeployment_result)
        return this.equals((updateApplicationDeployment_result)that);
      return false;
    }

    public boolean equals(updateApplicationDeployment_result that) {
      if (that == null)
        return false;

      boolean this_present_success = true;
      boolean that_present_success = true;
      if (this_present_success || that_present_success) {
        if (!(this_present_success && that_present_success))
          return false;
        if (this.success != that.success)
          return false;
      }

      boolean this_present_ire = true && this.isSetIre();
      boolean that_present_ire = true && that.isSetIre();
      if (this_present_ire || that_present_ire) {
        if (!(this_present_ire && that_present_ire))
          return false;
        if (!this.ire.equals(that.ire))
          return false;
      }

      boolean this_present_ace = true && this.isSetAce();
      boolean that_present_ace = true && that.isSetAce();
      if (this_present_ace || that_present_ace) {
        if (!(this_present_ace && that_present_ace))
          return false;
        if (!this.ace.equals(that.ace))
          return false;
      }

      boolean this_present_ase = true && this.isSetAse();
      boolean that_present_ase = true && that.isSetAse();
      if (this_present_ase || that_present_ase) {
        if (!(this_present_ase && that_present_ase))
          return false;
        if (!this.ase.equals(that.ase))
          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() {
      List<Object> list = new ArrayList<Object>();

      boolean present_success = true;
      list.add(present_success);
      if (present_success)
        list.add(success);

      boolean present_ire = true && (isSetIre());
      list.add(present_ire);
      if (present_ire)
        list.add(ire);

      boolean present_ace = true && (isSetAce());
      list.add(present_ace);
      if (present_ace)
        list.add(ace);

      boolean present_ase = true && (isSetAse());
      list.add(present_ase);
      if (present_ase)
        list.add(ase);

      boolean present_ae = true && (isSetAe());
      list.add(present_ae);
      if (present_ae)
        list.add(ae);

      return list.hashCode();
    }

    @Override
    public int compareTo(updateApplicationDeployment_result other) {
      if (!getClass().equals(other.getClass())) {
        return getClass().getName().compareTo(other.getClass().getName());
      }

      int lastComparison = 0;

      lastComparison = Boolean.valueOf(isSetSuccess()).compareTo(other.isSetSuccess());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetSuccess()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.success, other.success);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = Boolean.valueOf(isSetIre()).compareTo(other.isSetIre());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetIre()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.ire, other.ire);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = Boolean.valueOf(isSetAce()).compareTo(other.isSetAce());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetAce()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.ace, other.ace);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = Boolean.valueOf(isSetAse()).compareTo(other.isSetAse());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetAse()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.ase, other.ase);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = 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 {
      schemes.get(iprot.getScheme()).getScheme().read(iprot, this);
    }

    public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException {
      schemes.get(oprot.getScheme()).getScheme().write(oprot, this);
      }

    @Override
    public String toString() {
      StringBuilder sb = new StringBuilder("updateApplicationDeployment_result(");
      boolean first = true;

      sb.append("success:");
      sb.append(this.success);
      first = false;
      if (!first) sb.append(", ");
      sb.append("ire:");
      if (this.ire == null) {
        sb.append("null");
      } else {
        sb.append(this.ire);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("ace:");
      if (this.ace == null) {
        sb.append("null");
      } else {
        sb.append(this.ace);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("ase:");
      if (this.ase == null) {
        sb.append("null");
      } else {
        sb.append(this.ase);
      }
      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, 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 updateApplicationDeployment_resultStandardSchemeFactory implements SchemeFactory {
      public updateApplicationDeployment_resultStandardScheme getScheme() {
        return new updateApplicationDeployment_resultStandardScheme();
      }
    }

    private static class updateApplicationDeployment_resultStandardScheme extends StandardScheme<updateApplicationDeployment_result> {

      public void read(org.apache.thrift.protocol.TProtocol iprot, updateApplicationDeployment_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: // IRE
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.ire = new org.apache.airavata.model.error.InvalidRequestException();
                struct.ire.read(iprot);
                struct.setIreIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 2: // ACE
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.ace = new org.apache.airavata.model.error.AiravataClientException();
                struct.ace.read(iprot);
                struct.setAceIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 3: // ASE
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.ase = new org.apache.airavata.model.error.AiravataSystemException();
                struct.ase.read(iprot);
                struct.setAseIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 4: // 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, updateApplicationDeployment_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.ire != null) {
          oprot.writeFieldBegin(IRE_FIELD_DESC);
          struct.ire.write(oprot);
          oprot.writeFieldEnd();
        }
        if (struct.ace != null) {
          oprot.writeFieldBegin(ACE_FIELD_DESC);
          struct.ace.write(oprot);
          oprot.writeFieldEnd();
        }
        if (struct.ase != null) {
          oprot.writeFieldBegin(ASE_FIELD_DESC);
          struct.ase.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 updateApplicationDeployment_resultTupleSchemeFactory implements SchemeFactory {
      public updateApplicationDeployment_resultTupleScheme getScheme() {
        return new updateApplicationDeployment_resultTupleScheme();
      }
    }

    private static class updateApplicationDeployment_resultTupleScheme extends TupleScheme<updateApplicationDeployment_result> {

      @Override
      public void write(org.apache.thrift.protocol.TProtocol prot, updateApplicationDeployment_result struct) throws org.apache.thrift.TException {
        TTupleProtocol oprot = (TTupleProtocol) prot;
        BitSet optionals = new BitSet();
        if (struct.isSetSuccess()) {
          optionals.set(0);
        }
        if (struct.isSetIre()) {
          optionals.set(1);
        }
        if (struct.isSetAce()) {
          optionals.set(2);
        }
        if (struct.isSetAse()) {
          optionals.set(3);
        }
        if (struct.isSetAe()) {
          optionals.set(4);
        }
        oprot.writeBitSet(optionals, 5);
        if (struct.isSetSuccess()) {
          oprot.writeBool(struct.success);
        }
        if (struct.isSetIre()) {
          struct.ire.write(oprot);
        }
        if (struct.isSetAce()) {
          struct.ace.write(oprot);
        }
        if (struct.isSetAse()) {
          struct.ase.write(oprot);
        }
        if (struct.isSetAe()) {
          struct.ae.write(oprot);
        }
      }

      @Override
      public void read(org.apache.thrift.protocol.TProtocol prot, updateApplicationDeployment_result struct) throws org.apache.thrift.TException {
        TTupleProtocol iprot = (TTupleProtocol) prot;
        BitSet incoming = iprot.readBitSet(5);
        if (incoming.get(0)) {
          struct.success = iprot.readBool();
          struct.setSuccessIsSet(true);
        }
        if (incoming.get(1)) {
          struct.ire = new org.apache.airavata.model.error.InvalidRequestException();
          struct.ire.read(iprot);
          struct.setIreIsSet(true);
        }
        if (incoming.get(2)) {
          struct.ace = new org.apache.airavata.model.error.AiravataClientException();
          struct.ace.read(iprot);
          struct.setAceIsSet(true);
        }
        if (incoming.get(3)) {
          struct.ase = new org.apache.airavata.model.error.AiravataSystemException();
          struct.ase.read(iprot);
          struct.setAseIsSet(true);
        }
        if (incoming.get(4)) {
          struct.ae = new org.apache.airavata.model.error.AuthorizationException();
          struct.ae.read(iprot);
          struct.setAeIsSet(true);
        }
      }
    }

  }

  public static class deleteApplicationDeployment_args implements org.apache.thrift.TBase<deleteApplicationDeployment_args, deleteApplicationDeployment_args._Fields>, java.io.Serializable, Cloneable, Comparable<deleteApplicationDeployment_args>   {
    private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("deleteApplicationDeployment_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 APP_DEPLOYMENT_ID_FIELD_DESC = new org.apache.thrift.protocol.TField("appDeploymentId", org.apache.thrift.protocol.TType.STRING, (short)2);

    private static final Map<Class<? extends IScheme>, SchemeFactory> schemes = new HashMap<Class<? extends IScheme>, SchemeFactory>();
    static {
      schemes.put(StandardScheme.class, new deleteApplicationDeployment_argsStandardSchemeFactory());
      schemes.put(TupleScheme.class, new deleteApplicationDeployment_argsTupleSchemeFactory());
    }

    public org.apache.airavata.model.security.AuthzToken authzToken; // required
    public String appDeploymentId; // required

    /** 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"),
      APP_DEPLOYMENT_ID((short)2, "appDeploymentId");

      private static final Map<String, _Fields> byName = new HashMap<String, _Fields>();

      static {
        for (_Fields field : EnumSet.allOf(_Fields.class)) {
          byName.put(field.getFieldName(), field);
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, or null if its not found.
       */
      public static _Fields findByThriftId(int fieldId) {
        switch(fieldId) {
          case 1: // AUTHZ_TOKEN
            return AUTHZ_TOKEN;
          case 2: // APP_DEPLOYMENT_ID
            return APP_DEPLOYMENT_ID;
          default:
            return null;
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, throwing an exception
       * if it is not found.
       */
      public static _Fields findByThriftIdOrThrow(int fieldId) {
        _Fields fields = findByThriftId(fieldId);
        if (fields == null) throw new IllegalArgumentException("Field " + fieldId + " doesn't exist!");
        return fields;
      }

      /**
       * Find the _Fields constant that matches name, or null if its not found.
       */
      public static _Fields findByName(String name) {
        return byName.get(name);
      }

      private final short _thriftId;
      private final String _fieldName;

      _Fields(short thriftId, String fieldName) {
        _thriftId = thriftId;
        _fieldName = fieldName;
      }

      public short getThriftFieldId() {
        return _thriftId;
      }

      public String getFieldName() {
        return _fieldName;
      }
    }

    // isset id assignments
    public static final Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
    static {
      Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new EnumMap<_Fields, org.apache.thrift.meta_data.FieldMetaData>(_Fields.class);
      tmpMap.put(_Fields.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.APP_DEPLOYMENT_ID, new org.apache.thrift.meta_data.FieldMetaData("appDeploymentId", org.apache.thrift.TFieldRequirementType.REQUIRED, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING)));
      metaDataMap = Collections.unmodifiableMap(tmpMap);
      org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(deleteApplicationDeployment_args.class, metaDataMap);
    }

    public deleteApplicationDeployment_args() {
    }

    public deleteApplicationDeployment_args(
      org.apache.airavata.model.security.AuthzToken authzToken,
      String appDeploymentId)
    {
      this();
      this.authzToken = authzToken;
      this.appDeploymentId = appDeploymentId;
    }

    /**
     * Performs a deep copy on <i>other</i>.
     */
    public deleteApplicationDeployment_args(deleteApplicationDeployment_args other) {
      if (other.isSetAuthzToken()) {
        this.authzToken = new org.apache.airavata.model.security.AuthzToken(other.authzToken);
      }
      if (other.isSetAppDeploymentId()) {
        this.appDeploymentId = other.appDeploymentId;
      }
    }

    public deleteApplicationDeployment_args deepCopy() {
      return new deleteApplicationDeployment_args(this);
    }

    @Override
    public void clear() {
      this.authzToken = null;
      this.appDeploymentId = null;
    }

    public org.apache.airavata.model.security.AuthzToken getAuthzToken() {
      return this.authzToken;
    }

    public deleteApplicationDeployment_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 String getAppDeploymentId() {
      return this.appDeploymentId;
    }

    public deleteApplicationDeployment_args setAppDeploymentId(String appDeploymentId) {
      this.appDeploymentId = appDeploymentId;
      return this;
    }

    public void unsetAppDeploymentId() {
      this.appDeploymentId = null;
    }

    /** Returns true if field appDeploymentId is set (has been assigned a value) and false otherwise */
    public boolean isSetAppDeploymentId() {
      return this.appDeploymentId != null;
    }

    public void setAppDeploymentIdIsSet(boolean value) {
      if (!value) {
        this.appDeploymentId = null;
      }
    }

    public void setFieldValue(_Fields field, Object value) {
      switch (field) {
      case AUTHZ_TOKEN:
        if (value == null) {
          unsetAuthzToken();
        } else {
          setAuthzToken((org.apache.airavata.model.security.AuthzToken)value);
        }
        break;

      case APP_DEPLOYMENT_ID:
        if (value == null) {
          unsetAppDeploymentId();
        } else {
          setAppDeploymentId((String)value);
        }
        break;

      }
    }

    public Object getFieldValue(_Fields field) {
      switch (field) {
      case AUTHZ_TOKEN:
        return getAuthzToken();

      case APP_DEPLOYMENT_ID:
        return getAppDeploymentId();

      }
      throw new IllegalStateException();
    }

    /** Returns true if field corresponding to fieldID is set (has been assigned a value) and false otherwise */
    public boolean isSet(_Fields field) {
      if (field == null) {
        throw new IllegalArgumentException();
      }

      switch (field) {
      case AUTHZ_TOKEN:
        return isSetAuthzToken();
      case APP_DEPLOYMENT_ID:
        return isSetAppDeploymentId();
      }
      throw new IllegalStateException();
    }

    @Override
    public boolean equals(Object that) {
      if (that == null)
        return false;
      if (that instanceof deleteApplicationDeployment_args)
        return this.equals((deleteApplicationDeployment_args)that);
      return false;
    }

    public boolean equals(deleteApplicationDeployment_args that) {
      if (that == null)
        return false;

      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_appDeploymentId = true && this.isSetAppDeploymentId();
      boolean that_present_appDeploymentId = true && that.isSetAppDeploymentId();
      if (this_present_appDeploymentId || that_present_appDeploymentId) {
        if (!(this_present_appDeploymentId && that_present_appDeploymentId))
          return false;
        if (!this.appDeploymentId.equals(that.appDeploymentId))
          return false;
      }

      return true;
    }

    @Override
    public int hashCode() {
      List<Object> list = new ArrayList<Object>();

      boolean present_authzToken = true && (isSetAuthzToken());
      list.add(present_authzToken);
      if (present_authzToken)
        list.add(authzToken);

      boolean present_appDeploymentId = true && (isSetAppDeploymentId());
      list.add(present_appDeploymentId);
      if (present_appDeploymentId)
        list.add(appDeploymentId);

      return list.hashCode();
    }

    @Override
    public int compareTo(deleteApplicationDeployment_args other) {
      if (!getClass().equals(other.getClass())) {
        return getClass().getName().compareTo(other.getClass().getName());
      }

      int lastComparison = 0;

      lastComparison = 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 = Boolean.valueOf(isSetAppDeploymentId()).compareTo(other.isSetAppDeploymentId());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetAppDeploymentId()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.appDeploymentId, other.appDeploymentId);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      return 0;
    }

    public _Fields fieldForId(int fieldId) {
      return _Fields.findByThriftId(fieldId);
    }

    public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
      schemes.get(iprot.getScheme()).getScheme().read(iprot, this);
    }

    public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException {
      schemes.get(oprot.getScheme()).getScheme().write(oprot, this);
    }

    @Override
    public String toString() {
      StringBuilder sb = new StringBuilder("deleteApplicationDeployment_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("appDeploymentId:");
      if (this.appDeploymentId == null) {
        sb.append("null");
      } else {
        sb.append(this.appDeploymentId);
      }
      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 (appDeploymentId == null) {
        throw new org.apache.thrift.protocol.TProtocolException("Required field 'appDeploymentId' 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, 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 deleteApplicationDeployment_argsStandardSchemeFactory implements SchemeFactory {
      public deleteApplicationDeployment_argsStandardScheme getScheme() {
        return new deleteApplicationDeployment_argsStandardScheme();
      }
    }

    private static class deleteApplicationDeployment_argsStandardScheme extends StandardScheme<deleteApplicationDeployment_args> {

      public void read(org.apache.thrift.protocol.TProtocol iprot, deleteApplicationDeployment_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: // APP_DEPLOYMENT_ID
              if (schemeField.type == org.apache.thrift.protocol.TType.STRING) {
                struct.appDeploymentId = iprot.readString();
                struct.setAppDeploymentIdIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            default:
              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
          }
          iprot.readFieldEnd();
        }
        iprot.readStructEnd();

        // check for required fields of primitive type, which can't be checked in the validate method
        struct.validate();
      }

      public void write(org.apache.thrift.protocol.TProtocol oprot, deleteApplicationDeployment_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.appDeploymentId != null) {
          oprot.writeFieldBegin(APP_DEPLOYMENT_ID_FIELD_DESC);
          oprot.writeString(struct.appDeploymentId);
          oprot.writeFieldEnd();
        }
        oprot.writeFieldStop();
        oprot.writeStructEnd();
      }

    }

    private static class deleteApplicationDeployment_argsTupleSchemeFactory implements SchemeFactory {
      public deleteApplicationDeployment_argsTupleScheme getScheme() {
        return new deleteApplicationDeployment_argsTupleScheme();
      }
    }

    private static class deleteApplicationDeployment_argsTupleScheme extends TupleScheme<deleteApplicationDeployment_args> {

      @Override
      public void write(org.apache.thrift.protocol.TProtocol prot, deleteApplicationDeployment_args struct) throws org.apache.thrift.TException {
        TTupleProtocol oprot = (TTupleProtocol) prot;
        struct.authzToken.write(oprot);
        oprot.writeString(struct.appDeploymentId);
      }

      @Override
      public void read(org.apache.thrift.protocol.TProtocol prot, deleteApplicationDeployment_args struct) throws org.apache.thrift.TException {
        TTupleProtocol iprot = (TTupleProtocol) prot;
        struct.authzToken = new org.apache.airavata.model.security.AuthzToken();
        struct.authzToken.read(iprot);
        struct.setAuthzTokenIsSet(true);
        struct.appDeploymentId = iprot.readString();
        struct.setAppDeploymentIdIsSet(true);
      }
    }

  }

  public static class deleteApplicationDeployment_result implements org.apache.thrift.TBase<deleteApplicationDeployment_result, deleteApplicationDeployment_result._Fields>, java.io.Serializable, Cloneable, Comparable<deleteApplicationDeployment_result>   {
    private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("deleteApplicationDeployment_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 IRE_FIELD_DESC = new org.apache.thrift.protocol.TField("ire", org.apache.thrift.protocol.TType.STRUCT, (short)1);
    private static final org.apache.thrift.protocol.TField ACE_FIELD_DESC = new org.apache.thrift.protocol.TField("ace", org.apache.thrift.protocol.TType.STRUCT, (short)2);
    private static final org.apache.thrift.protocol.TField ASE_FIELD_DESC = new org.apache.thrift.protocol.TField("ase", org.apache.thrift.protocol.TType.STRUCT, (short)3);
    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)4);

    private static final Map<Class<? extends IScheme>, SchemeFactory> schemes = new HashMap<Class<? extends IScheme>, SchemeFactory>();
    static {
      schemes.put(StandardScheme.class, new deleteApplicationDeployment_resultStandardSchemeFactory());
      schemes.put(TupleScheme.class, new deleteApplicationDeployment_resultTupleSchemeFactory());
    }

    public boolean success; // required
    public org.apache.airavata.model.error.InvalidRequestException ire; // required
    public org.apache.airavata.model.error.AiravataClientException ace; // required
    public org.apache.airavata.model.error.AiravataSystemException ase; // 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"),
      IRE((short)1, "ire"),
      ACE((short)2, "ace"),
      ASE((short)3, "ase"),
      AE((short)4, "ae");

      private static final Map<String, _Fields> byName = new HashMap<String, _Fields>();

      static {
        for (_Fields field : EnumSet.allOf(_Fields.class)) {
          byName.put(field.getFieldName(), field);
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, or null if its not found.
       */
      public static _Fields findByThriftId(int fieldId) {
        switch(fieldId) {
          case 0: // SUCCESS
            return SUCCESS;
          case 1: // IRE
            return IRE;
          case 2: // ACE
            return ACE;
          case 3: // ASE
            return ASE;
          case 4: // 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 IllegalArgumentException("Field " + fieldId + " doesn't exist!");
        return fields;
      }

      /**
       * Find the _Fields constant that matches name, or null if its not found.
       */
      public static _Fields findByName(String name) {
        return byName.get(name);
      }

      private final short _thriftId;
      private final String _fieldName;

      _Fields(short thriftId, String fieldName) {
        _thriftId = thriftId;
        _fieldName = fieldName;
      }

      public short getThriftFieldId() {
        return _thriftId;
      }

      public String getFieldName() {
        return _fieldName;
      }
    }

    // isset id assignments
    private static final int __SUCCESS_ISSET_ID = 0;
    private byte __isset_bitfield = 0;
    public static final Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
    static {
      Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new EnumMap<_Fields, org.apache.thrift.meta_data.FieldMetaData>(_Fields.class);
      tmpMap.put(_Fields.SUCCESS, new org.apache.thrift.meta_data.FieldMetaData("success", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.BOOL)));
      tmpMap.put(_Fields.IRE, new org.apache.thrift.meta_data.FieldMetaData("ire", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRUCT)));
      tmpMap.put(_Fields.ACE, new org.apache.thrift.meta_data.FieldMetaData("ace", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRUCT)));
      tmpMap.put(_Fields.ASE, new org.apache.thrift.meta_data.FieldMetaData("ase", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRUCT)));
      tmpMap.put(_Fields.AE, new org.apache.thrift.meta_data.FieldMetaData("ae", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRUCT)));
      metaDataMap = Collections.unmodifiableMap(tmpMap);
      org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(deleteApplicationDeployment_result.class, metaDataMap);
    }

    public deleteApplicationDeployment_result() {
    }

    public deleteApplicationDeployment_result(
      boolean success,
      org.apache.airavata.model.error.InvalidRequestException ire,
      org.apache.airavata.model.error.AiravataClientException ace,
      org.apache.airavata.model.error.AiravataSystemException ase,
      org.apache.airavata.model.error.AuthorizationException ae)
    {
      this();
      this.success = success;
      setSuccessIsSet(true);
      this.ire = ire;
      this.ace = ace;
      this.ase = ase;
      this.ae = ae;
    }

    /**
     * Performs a deep copy on <i>other</i>.
     */
    public deleteApplicationDeployment_result(deleteApplicationDeployment_result other) {
      __isset_bitfield = other.__isset_bitfield;
      this.success = other.success;
      if (other.isSetIre()) {
        this.ire = new org.apache.airavata.model.error.InvalidRequestException(other.ire);
      }
      if (other.isSetAce()) {
        this.ace = new org.apache.airavata.model.error.AiravataClientException(other.ace);
      }
      if (other.isSetAse()) {
        this.ase = new org.apache.airavata.model.error.AiravataSystemException(other.ase);
      }
      if (other.isSetAe()) {
        this.ae = new org.apache.airavata.model.error.AuthorizationException(other.ae);
      }
    }

    public deleteApplicationDeployment_result deepCopy() {
      return new deleteApplicationDeployment_result(this);
    }

    @Override
    public void clear() {
      setSuccessIsSet(false);
      this.success = false;
      this.ire = null;
      this.ace = null;
      this.ase = null;
      this.ae = null;
    }

    public boolean isSuccess() {
      return this.success;
    }

    public deleteApplicationDeployment_result setSuccess(boolean success) {
      this.success = success;
      setSuccessIsSet(true);
      return this;
    }

    public void unsetSuccess() {
      __isset_bitfield = EncodingUtils.clearBit(__isset_bitfield, __SUCCESS_ISSET_ID);
    }

    /** Returns true if field success is set (has been assigned a value) and false otherwise */
    public boolean isSetSuccess() {
      return EncodingUtils.testBit(__isset_bitfield, __SUCCESS_ISSET_ID);
    }

    public void setSuccessIsSet(boolean value) {
      __isset_bitfield = EncodingUtils.setBit(__isset_bitfield, __SUCCESS_ISSET_ID, value);
    }

    public org.apache.airavata.model.error.InvalidRequestException getIre() {
      return this.ire;
    }

    public deleteApplicationDeployment_result setIre(org.apache.airavata.model.error.InvalidRequestException ire) {
      this.ire = ire;
      return this;
    }

    public void unsetIre() {
      this.ire = null;
    }

    /** Returns true if field ire is set (has been assigned a value) and false otherwise */
    public boolean isSetIre() {
      return this.ire != null;
    }

    public void setIreIsSet(boolean value) {
      if (!value) {
        this.ire = null;
      }
    }

    public org.apache.airavata.model.error.AiravataClientException getAce() {
      return this.ace;
    }

    public deleteApplicationDeployment_result setAce(org.apache.airavata.model.error.AiravataClientException ace) {
      this.ace = ace;
      return this;
    }

    public void unsetAce() {
      this.ace = null;
    }

    /** Returns true if field ace is set (has been assigned a value) and false otherwise */
    public boolean isSetAce() {
      return this.ace != null;
    }

    public void setAceIsSet(boolean value) {
      if (!value) {
        this.ace = null;
      }
    }

    public org.apache.airavata.model.error.AiravataSystemException getAse() {
      return this.ase;
    }

    public deleteApplicationDeployment_result setAse(org.apache.airavata.model.error.AiravataSystemException ase) {
      this.ase = ase;
      return this;
    }

    public void unsetAse() {
      this.ase = null;
    }

    /** Returns true if field ase is set (has been assigned a value) and false otherwise */
    public boolean isSetAse() {
      return this.ase != null;
    }

    public void setAseIsSet(boolean value) {
      if (!value) {
        this.ase = null;
      }
    }

    public org.apache.airavata.model.error.AuthorizationException getAe() {
      return this.ae;
    }

    public deleteApplicationDeployment_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, Object value) {
      switch (field) {
      case SUCCESS:
        if (value == null) {
          unsetSuccess();
        } else {
          setSuccess((Boolean)value);
        }
        break;

      case IRE:
        if (value == null) {
          unsetIre();
        } else {
          setIre((org.apache.airavata.model.error.InvalidRequestException)value);
        }
        break;

      case ACE:
        if (value == null) {
          unsetAce();
        } else {
          setAce((org.apache.airavata.model.error.AiravataClientException)value);
        }
        break;

      case ASE:
        if (value == null) {
          unsetAse();
        } else {
          setAse((org.apache.airavata.model.error.AiravataSystemException)value);
        }
        break;

      case AE:
        if (value == null) {
          unsetAe();
        } else {
          setAe((org.apache.airavata.model.error.AuthorizationException)value);
        }
        break;

      }
    }

    public Object getFieldValue(_Fields field) {
      switch (field) {
      case SUCCESS:
        return Boolean.valueOf(isSuccess());

      case IRE:
        return getIre();

      case ACE:
        return getAce();

      case ASE:
        return getAse();

      case AE:
        return getAe();

      }
      throw new IllegalStateException();
    }

    /** Returns true if field corresponding to fieldID is set (has been assigned a value) and false otherwise */
    public boolean isSet(_Fields field) {
      if (field == null) {
        throw new IllegalArgumentException();
      }

      switch (field) {
      case SUCCESS:
        return isSetSuccess();
      case IRE:
        return isSetIre();
      case ACE:
        return isSetAce();
      case ASE:
        return isSetAse();
      case AE:
        return isSetAe();
      }
      throw new IllegalStateException();
    }

    @Override
    public boolean equals(Object that) {
      if (that == null)
        return false;
      if (that instanceof deleteApplicationDeployment_result)
        return this.equals((deleteApplicationDeployment_result)that);
      return false;
    }

    public boolean equals(deleteApplicationDeployment_result that) {
      if (that == null)
        return false;

      boolean this_present_success = true;
      boolean that_present_success = true;
      if (this_present_success || that_present_success) {
        if (!(this_present_success && that_present_success))
          return false;
        if (this.success != that.success)
          return false;
      }

      boolean this_present_ire = true && this.isSetIre();
      boolean that_present_ire = true && that.isSetIre();
      if (this_present_ire || that_present_ire) {
        if (!(this_present_ire && that_present_ire))
          return false;
        if (!this.ire.equals(that.ire))
          return false;
      }

      boolean this_present_ace = true && this.isSetAce();
      boolean that_present_ace = true && that.isSetAce();
      if (this_present_ace || that_present_ace) {
        if (!(this_present_ace && that_present_ace))
          return false;
        if (!this.ace.equals(that.ace))
          return false;
      }

      boolean this_present_ase = true && this.isSetAse();
      boolean that_present_ase = true && that.isSetAse();
      if (this_present_ase || that_present_ase) {
        if (!(this_present_ase && that_present_ase))
          return false;
        if (!this.ase.equals(that.ase))
          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() {
      List<Object> list = new ArrayList<Object>();

      boolean present_success = true;
      list.add(present_success);
      if (present_success)
        list.add(success);

      boolean present_ire = true && (isSetIre());
      list.add(present_ire);
      if (present_ire)
        list.add(ire);

      boolean present_ace = true && (isSetAce());
      list.add(present_ace);
      if (present_ace)
        list.add(ace);

      boolean present_ase = true && (isSetAse());
      list.add(present_ase);
      if (present_ase)
        list.add(ase);

      boolean present_ae = true && (isSetAe());
      list.add(present_ae);
      if (present_ae)
        list.add(ae);

      return list.hashCode();
    }

    @Override
    public int compareTo(deleteApplicationDeployment_result other) {
      if (!getClass().equals(other.getClass())) {
        return getClass().getName().compareTo(other.getClass().getName());
      }

      int lastComparison = 0;

      lastComparison = Boolean.valueOf(isSetSuccess()).compareTo(other.isSetSuccess());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetSuccess()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.success, other.success);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = Boolean.valueOf(isSetIre()).compareTo(other.isSetIre());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetIre()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.ire, other.ire);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = Boolean.valueOf(isSetAce()).compareTo(other.isSetAce());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetAce()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.ace, other.ace);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = Boolean.valueOf(isSetAse()).compareTo(other.isSetAse());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetAse()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.ase, other.ase);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = 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 {
      schemes.get(iprot.getScheme()).getScheme().read(iprot, this);
    }

    public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException {
      schemes.get(oprot.getScheme()).getScheme().write(oprot, this);
      }

    @Override
    public String toString() {
      StringBuilder sb = new StringBuilder("deleteApplicationDeployment_result(");
      boolean first = true;

      sb.append("success:");
      sb.append(this.success);
      first = false;
      if (!first) sb.append(", ");
      sb.append("ire:");
      if (this.ire == null) {
        sb.append("null");
      } else {
        sb.append(this.ire);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("ace:");
      if (this.ace == null) {
        sb.append("null");
      } else {
        sb.append(this.ace);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("ase:");
      if (this.ase == null) {
        sb.append("null");
      } else {
        sb.append(this.ase);
      }
      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, 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 deleteApplicationDeployment_resultStandardSchemeFactory implements SchemeFactory {
      public deleteApplicationDeployment_resultStandardScheme getScheme() {
        return new deleteApplicationDeployment_resultStandardScheme();
      }
    }

    private static class deleteApplicationDeployment_resultStandardScheme extends StandardScheme<deleteApplicationDeployment_result> {

      public void read(org.apache.thrift.protocol.TProtocol iprot, deleteApplicationDeployment_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: // IRE
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.ire = new org.apache.airavata.model.error.InvalidRequestException();
                struct.ire.read(iprot);
                struct.setIreIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 2: // ACE
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.ace = new org.apache.airavata.model.error.AiravataClientException();
                struct.ace.read(iprot);
                struct.setAceIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 3: // ASE
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.ase = new org.apache.airavata.model.error.AiravataSystemException();
                struct.ase.read(iprot);
                struct.setAseIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 4: // 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, deleteApplicationDeployment_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.ire != null) {
          oprot.writeFieldBegin(IRE_FIELD_DESC);
          struct.ire.write(oprot);
          oprot.writeFieldEnd();
        }
        if (struct.ace != null) {
          oprot.writeFieldBegin(ACE_FIELD_DESC);
          struct.ace.write(oprot);
          oprot.writeFieldEnd();
        }
        if (struct.ase != null) {
          oprot.writeFieldBegin(ASE_FIELD_DESC);
          struct.ase.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 deleteApplicationDeployment_resultTupleSchemeFactory implements SchemeFactory {
      public deleteApplicationDeployment_resultTupleScheme getScheme() {
        return new deleteApplicationDeployment_resultTupleScheme();
      }
    }

    private static class deleteApplicationDeployment_resultTupleScheme extends TupleScheme<deleteApplicationDeployment_result> {

      @Override
      public void write(org.apache.thrift.protocol.TProtocol prot, deleteApplicationDeployment_result struct) throws org.apache.thrift.TException {
        TTupleProtocol oprot = (TTupleProtocol) prot;
        BitSet optionals = new BitSet();
        if (struct.isSetSuccess()) {
          optionals.set(0);
        }
        if (struct.isSetIre()) {
          optionals.set(1);
        }
        if (struct.isSetAce()) {
          optionals.set(2);
        }
        if (struct.isSetAse()) {
          optionals.set(3);
        }
        if (struct.isSetAe()) {
          optionals.set(4);
        }
        oprot.writeBitSet(optionals, 5);
        if (struct.isSetSuccess()) {
          oprot.writeBool(struct.success);
        }
        if (struct.isSetIre()) {
          struct.ire.write(oprot);
        }
        if (struct.isSetAce()) {
          struct.ace.write(oprot);
        }
        if (struct.isSetAse()) {
          struct.ase.write(oprot);
        }
        if (struct.isSetAe()) {
          struct.ae.write(oprot);
        }
      }

      @Override
      public void read(org.apache.thrift.protocol.TProtocol prot, deleteApplicationDeployment_result struct) throws org.apache.thrift.TException {
        TTupleProtocol iprot = (TTupleProtocol) prot;
        BitSet incoming = iprot.readBitSet(5);
        if (incoming.get(0)) {
          struct.success = iprot.readBool();
          struct.setSuccessIsSet(true);
        }
        if (incoming.get(1)) {
          struct.ire = new org.apache.airavata.model.error.InvalidRequestException();
          struct.ire.read(iprot);
          struct.setIreIsSet(true);
        }
        if (incoming.get(2)) {
          struct.ace = new org.apache.airavata.model.error.AiravataClientException();
          struct.ace.read(iprot);
          struct.setAceIsSet(true);
        }
        if (incoming.get(3)) {
          struct.ase = new org.apache.airavata.model.error.AiravataSystemException();
          struct.ase.read(iprot);
          struct.setAseIsSet(true);
        }
        if (incoming.get(4)) {
          struct.ae = new org.apache.airavata.model.error.AuthorizationException();
          struct.ae.read(iprot);
          struct.setAeIsSet(true);
        }
      }
    }

  }

  public static class getAllApplicationDeployments_args implements org.apache.thrift.TBase<getAllApplicationDeployments_args, getAllApplicationDeployments_args._Fields>, java.io.Serializable, Cloneable, Comparable<getAllApplicationDeployments_args>   {
    private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("getAllApplicationDeployments_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 Map<Class<? extends IScheme>, SchemeFactory> schemes = new HashMap<Class<? extends IScheme>, SchemeFactory>();
    static {
      schemes.put(StandardScheme.class, new getAllApplicationDeployments_argsStandardSchemeFactory());
      schemes.put(TupleScheme.class, new getAllApplicationDeployments_argsTupleSchemeFactory());
    }

    public org.apache.airavata.model.security.AuthzToken authzToken; // required
    public 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 Map<String, _Fields> byName = new HashMap<String, _Fields>();

      static {
        for (_Fields field : EnumSet.allOf(_Fields.class)) {
          byName.put(field.getFieldName(), field);
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, or null if its not found.
       */
      public static _Fields findByThriftId(int fieldId) {
        switch(fieldId) {
          case 1: // 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 IllegalArgumentException("Field " + fieldId + " doesn't exist!");
        return fields;
      }

      /**
       * Find the _Fields constant that matches name, or null if its not found.
       */
      public static _Fields findByName(String name) {
        return byName.get(name);
      }

      private final short _thriftId;
      private final String _fieldName;

      _Fields(short thriftId, String fieldName) {
        _thriftId = thriftId;
        _fieldName = fieldName;
      }

      public short getThriftFieldId() {
        return _thriftId;
      }

      public String getFieldName() {
        return _fieldName;
      }
    }

    // isset id assignments
    public static final Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
    static {
      Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new EnumMap<_Fields, org.apache.thrift.meta_data.FieldMetaData>(_Fields.class);
      tmpMap.put(_Fields.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 = Collections.unmodifiableMap(tmpMap);
      org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(getAllApplicationDeployments_args.class, metaDataMap);
    }

    public getAllApplicationDeployments_args() {
    }

    public getAllApplicationDeployments_args(
      org.apache.airavata.model.security.AuthzToken authzToken,
      String gatewayId)
    {
      this();
      this.authzToken = authzToken;
      this.gatewayId = gatewayId;
    }

    /**
     * Performs a deep copy on <i>other</i>.
     */
    public getAllApplicationDeployments_args(getAllApplicationDeployments_args other) {
      if (other.isSetAuthzToken()) {
        this.authzToken = new org.apache.airavata.model.security.AuthzToken(other.authzToken);
      }
      if (other.isSetGatewayId()) {
        this.gatewayId = other.gatewayId;
      }
    }

    public getAllApplicationDeployments_args deepCopy() {
      return new getAllApplicationDeployments_args(this);
    }

    @Override
    public void clear() {
      this.authzToken = null;
      this.gatewayId = null;
    }

    public org.apache.airavata.model.security.AuthzToken getAuthzToken() {
      return this.authzToken;
    }

    public getAllApplicationDeployments_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 String getGatewayId() {
      return this.gatewayId;
    }

    public getAllApplicationDeployments_args setGatewayId(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, 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((String)value);
        }
        break;

      }
    }

    public Object getFieldValue(_Fields field) {
      switch (field) {
      case AUTHZ_TOKEN:
        return getAuthzToken();

      case GATEWAY_ID:
        return getGatewayId();

      }
      throw new IllegalStateException();
    }

    /** Returns true if field corresponding to fieldID is set (has been assigned a value) and false otherwise */
    public boolean isSet(_Fields field) {
      if (field == null) {
        throw new IllegalArgumentException();
      }

      switch (field) {
      case AUTHZ_TOKEN:
        return isSetAuthzToken();
      case GATEWAY_ID:
        return isSetGatewayId();
      }
      throw new IllegalStateException();
    }

    @Override
    public boolean equals(Object that) {
      if (that == null)
        return false;
      if (that instanceof getAllApplicationDeployments_args)
        return this.equals((getAllApplicationDeployments_args)that);
      return false;
    }

    public boolean equals(getAllApplicationDeployments_args that) {
      if (that == null)
        return false;

      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() {
      List<Object> list = new ArrayList<Object>();

      boolean present_authzToken = true && (isSetAuthzToken());
      list.add(present_authzToken);
      if (present_authzToken)
        list.add(authzToken);

      boolean present_gatewayId = true && (isSetGatewayId());
      list.add(present_gatewayId);
      if (present_gatewayId)
        list.add(gatewayId);

      return list.hashCode();
    }

    @Override
    public int compareTo(getAllApplicationDeployments_args other) {
      if (!getClass().equals(other.getClass())) {
        return getClass().getName().compareTo(other.getClass().getName());
      }

      int lastComparison = 0;

      lastComparison = 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 = 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 {
      schemes.get(iprot.getScheme()).getScheme().read(iprot, this);
    }

    public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException {
      schemes.get(oprot.getScheme()).getScheme().write(oprot, this);
    }

    @Override
    public String toString() {
      StringBuilder sb = new StringBuilder("getAllApplicationDeployments_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, 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 getAllApplicationDeployments_argsStandardSchemeFactory implements SchemeFactory {
      public getAllApplicationDeployments_argsStandardScheme getScheme() {
        return new getAllApplicationDeployments_argsStandardScheme();
      }
    }

    private static class getAllApplicationDeployments_argsStandardScheme extends StandardScheme<getAllApplicationDeployments_args> {

      public void read(org.apache.thrift.protocol.TProtocol iprot, getAllApplicationDeployments_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, getAllApplicationDeployments_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 getAllApplicationDeployments_argsTupleSchemeFactory implements SchemeFactory {
      public getAllApplicationDeployments_argsTupleScheme getScheme() {
        return new getAllApplicationDeployments_argsTupleScheme();
      }
    }

    private static class getAllApplicationDeployments_argsTupleScheme extends TupleScheme<getAllApplicationDeployments_args> {

      @Override
      public void write(org.apache.thrift.protocol.TProtocol prot, getAllApplicationDeployments_args struct) throws org.apache.thrift.TException {
        TTupleProtocol oprot = (TTupleProtocol) prot;
        struct.authzToken.write(oprot);
        oprot.writeString(struct.gatewayId);
      }

      @Override
      public void read(org.apache.thrift.protocol.TProtocol prot, getAllApplicationDeployments_args struct) throws org.apache.thrift.TException {
        TTupleProtocol iprot = (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);
      }
    }

  }

  public static class getAllApplicationDeployments_result implements org.apache.thrift.TBase<getAllApplicationDeployments_result, getAllApplicationDeployments_result._Fields>, java.io.Serializable, Cloneable, Comparable<getAllApplicationDeployments_result>   {
    private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("getAllApplicationDeployments_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 IRE_FIELD_DESC = new org.apache.thrift.protocol.TField("ire", org.apache.thrift.protocol.TType.STRUCT, (short)1);
    private static final org.apache.thrift.protocol.TField ACE_FIELD_DESC = new org.apache.thrift.protocol.TField("ace", org.apache.thrift.protocol.TType.STRUCT, (short)2);
    private static final org.apache.thrift.protocol.TField ASE_FIELD_DESC = new org.apache.thrift.protocol.TField("ase", org.apache.thrift.protocol.TType.STRUCT, (short)3);
    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)4);

    private static final Map<Class<? extends IScheme>, SchemeFactory> schemes = new HashMap<Class<? extends IScheme>, SchemeFactory>();
    static {
      schemes.put(StandardScheme.class, new getAllApplicationDeployments_resultStandardSchemeFactory());
      schemes.put(TupleScheme.class, new getAllApplicationDeployments_resultTupleSchemeFactory());
    }

    public List<org.apache.airavata.model.appcatalog.appdeployment.ApplicationDeploymentDescription> success; // required
    public org.apache.airavata.model.error.InvalidRequestException ire; // required
    public org.apache.airavata.model.error.AiravataClientException ace; // required
    public org.apache.airavata.model.error.AiravataSystemException ase; // 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"),
      IRE((short)1, "ire"),
      ACE((short)2, "ace"),
      ASE((short)3, "ase"),
      AE((short)4, "ae");

      private static final Map<String, _Fields> byName = new HashMap<String, _Fields>();

      static {
        for (_Fields field : EnumSet.allOf(_Fields.class)) {
          byName.put(field.getFieldName(), field);
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, or null if its not found.
       */
      public static _Fields findByThriftId(int fieldId) {
        switch(fieldId) {
          case 0: // SUCCESS
            return SUCCESS;
          case 1: // IRE
            return IRE;
          case 2: // ACE
            return ACE;
          case 3: // ASE
            return ASE;
          case 4: // 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 IllegalArgumentException("Field " + fieldId + " doesn't exist!");
        return fields;
      }

      /**
       * Find the _Fields constant that matches name, or null if its not found.
       */
      public static _Fields findByName(String name) {
        return byName.get(name);
      }

      private final short _thriftId;
      private final String _fieldName;

      _Fields(short thriftId, String fieldName) {
        _thriftId = thriftId;
        _fieldName = fieldName;
      }

      public short getThriftFieldId() {
        return _thriftId;
      }

      public String getFieldName() {
        return _fieldName;
      }
    }

    // isset id assignments
    public static final Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
    static {
      Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new EnumMap<_Fields, org.apache.thrift.meta_data.FieldMetaData>(_Fields.class);
      tmpMap.put(_Fields.SUCCESS, new org.apache.thrift.meta_data.FieldMetaData("success", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.ListMetaData(org.apache.thrift.protocol.TType.LIST, 
              new org.apache.thrift.meta_data.StructMetaData(org.apache.thrift.protocol.TType.STRUCT, org.apache.airavata.model.appcatalog.appdeployment.ApplicationDeploymentDescription.class))));
      tmpMap.put(_Fields.IRE, new org.apache.thrift.meta_data.FieldMetaData("ire", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRUCT)));
      tmpMap.put(_Fields.ACE, new org.apache.thrift.meta_data.FieldMetaData("ace", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRUCT)));
      tmpMap.put(_Fields.ASE, new org.apache.thrift.meta_data.FieldMetaData("ase", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRUCT)));
      tmpMap.put(_Fields.AE, new org.apache.thrift.meta_data.FieldMetaData("ae", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRUCT)));
      metaDataMap = Collections.unmodifiableMap(tmpMap);
      org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(getAllApplicationDeployments_result.class, metaDataMap);
    }

    public getAllApplicationDeployments_result() {
    }

    public getAllApplicationDeployments_result(
      List<org.apache.airavata.model.appcatalog.appdeployment.ApplicationDeploymentDescription> success,
      org.apache.airavata.model.error.InvalidRequestException ire,
      org.apache.airavata.model.error.AiravataClientException ace,
      org.apache.airavata.model.error.AiravataSystemException ase,
      org.apache.airavata.model.error.AuthorizationException ae)
    {
      this();
      this.success = success;
      this.ire = ire;
      this.ace = ace;
      this.ase = ase;
      this.ae = ae;
    }

    /**
     * Performs a deep copy on <i>other</i>.
     */
    public getAllApplicationDeployments_result(getAllApplicationDeployments_result other) {
      if (other.isSetSuccess()) {
        List<org.apache.airavata.model.appcatalog.appdeployment.ApplicationDeploymentDescription> __this__success = new ArrayList<org.apache.airavata.model.appcatalog.appdeployment.ApplicationDeploymentDescription>(other.success.size());
        for (org.apache.airavata.model.appcatalog.appdeployment.ApplicationDeploymentDescription other_element : other.success) {
          __this__success.add(new org.apache.airavata.model.appcatalog.appdeployment.ApplicationDeploymentDescription(other_element));
        }
        this.success = __this__success;
      }
      if (other.isSetIre()) {
        this.ire = new org.apache.airavata.model.error.InvalidRequestException(other.ire);
      }
      if (other.isSetAce()) {
        this.ace = new org.apache.airavata.model.error.AiravataClientException(other.ace);
      }
      if (other.isSetAse()) {
        this.ase = new org.apache.airavata.model.error.AiravataSystemException(other.ase);
      }
      if (other.isSetAe()) {
        this.ae = new org.apache.airavata.model.error.AuthorizationException(other.ae);
      }
    }

    public getAllApplicationDeployments_result deepCopy() {
      return new getAllApplicationDeployments_result(this);
    }

    @Override
    public void clear() {
      this.success = null;
      this.ire = null;
      this.ace = null;
      this.ase = null;
      this.ae = null;
    }

    public int getSuccessSize() {
      return (this.success == null) ? 0 : this.success.size();
    }

    public java.util.Iterator<org.apache.airavata.model.appcatalog.appdeployment.ApplicationDeploymentDescription> getSuccessIterator() {
      return (this.success == null) ? null : this.success.iterator();
    }

    public void addToSuccess(org.apache.airavata.model.appcatalog.appdeployment.ApplicationDeploymentDescription elem) {
      if (this.success == null) {
        this.success = new ArrayList<org.apache.airavata.model.appcatalog.appdeployment.ApplicationDeploymentDescription>();
      }
      this.success.add(elem);
    }

    public List<org.apache.airavata.model.appcatalog.appdeployment.ApplicationDeploymentDescription> getSuccess() {
      return this.success;
    }

    public getAllApplicationDeployments_result setSuccess(List<org.apache.airavata.model.appcatalog.appdeployment.ApplicationDeploymentDescription> 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.model.error.InvalidRequestException getIre() {
      return this.ire;
    }

    public getAllApplicationDeployments_result setIre(org.apache.airavata.model.error.InvalidRequestException ire) {
      this.ire = ire;
      return this;
    }

    public void unsetIre() {
      this.ire = null;
    }

    /** Returns true if field ire is set (has been assigned a value) and false otherwise */
    public boolean isSetIre() {
      return this.ire != null;
    }

    public void setIreIsSet(boolean value) {
      if (!value) {
        this.ire = null;
      }
    }

    public org.apache.airavata.model.error.AiravataClientException getAce() {
      return this.ace;
    }

    public getAllApplicationDeployments_result setAce(org.apache.airavata.model.error.AiravataClientException ace) {
      this.ace = ace;
      return this;
    }

    public void unsetAce() {
      this.ace = null;
    }

    /** Returns true if field ace is set (has been assigned a value) and false otherwise */
    public boolean isSetAce() {
      return this.ace != null;
    }

    public void setAceIsSet(boolean value) {
      if (!value) {
        this.ace = null;
      }
    }

    public org.apache.airavata.model.error.AiravataSystemException getAse() {
      return this.ase;
    }

    public getAllApplicationDeployments_result setAse(org.apache.airavata.model.error.AiravataSystemException ase) {
      this.ase = ase;
      return this;
    }

    public void unsetAse() {
      this.ase = null;
    }

    /** Returns true if field ase is set (has been assigned a value) and false otherwise */
    public boolean isSetAse() {
      return this.ase != null;
    }

    public void setAseIsSet(boolean value) {
      if (!value) {
        this.ase = null;
      }
    }

    public org.apache.airavata.model.error.AuthorizationException getAe() {
      return this.ae;
    }

    public getAllApplicationDeployments_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, Object value) {
      switch (field) {
      case SUCCESS:
        if (value == null) {
          unsetSuccess();
        } else {
          setSuccess((List<org.apache.airavata.model.appcatalog.appdeployment.ApplicationDeploymentDescription>)value);
        }
        break;

      case IRE:
        if (value == null) {
          unsetIre();
        } else {
          setIre((org.apache.airavata.model.error.InvalidRequestException)value);
        }
        break;

      case ACE:
        if (value == null) {
          unsetAce();
        } else {
          setAce((org.apache.airavata.model.error.AiravataClientException)value);
        }
        break;

      case ASE:
        if (value == null) {
          unsetAse();
        } else {
          setAse((org.apache.airavata.model.error.AiravataSystemException)value);
        }
        break;

      case AE:
        if (value == null) {
          unsetAe();
        } else {
          setAe((org.apache.airavata.model.error.AuthorizationException)value);
        }
        break;

      }
    }

    public Object getFieldValue(_Fields field) {
      switch (field) {
      case SUCCESS:
        return getSuccess();

      case IRE:
        return getIre();

      case ACE:
        return getAce();

      case ASE:
        return getAse();

      case AE:
        return getAe();

      }
      throw new IllegalStateException();
    }

    /** Returns true if field corresponding to fieldID is set (has been assigned a value) and false otherwise */
    public boolean isSet(_Fields field) {
      if (field == null) {
        throw new IllegalArgumentException();
      }

      switch (field) {
      case SUCCESS:
        return isSetSuccess();
      case IRE:
        return isSetIre();
      case ACE:
        return isSetAce();
      case ASE:
        return isSetAse();
      case AE:
        return isSetAe();
      }
      throw new IllegalStateException();
    }

    @Override
    public boolean equals(Object that) {
      if (that == null)
        return false;
      if (that instanceof getAllApplicationDeployments_result)
        return this.equals((getAllApplicationDeployments_result)that);
      return false;
    }

    public boolean equals(getAllApplicationDeployments_result that) {
      if (that == null)
        return false;

      boolean this_present_success = true && this.isSetSuccess();
      boolean that_present_success = true && that.isSetSuccess();
      if (this_present_success || that_present_success) {
        if (!(this_present_success && that_present_success))
          return false;
        if (!this.success.equals(that.success))
          return false;
      }

      boolean this_present_ire = true && this.isSetIre();
      boolean that_present_ire = true && that.isSetIre();
      if (this_present_ire || that_present_ire) {
        if (!(this_present_ire && that_present_ire))
          return false;
        if (!this.ire.equals(that.ire))
          return false;
      }

      boolean this_present_ace = true && this.isSetAce();
      boolean that_present_ace = true && that.isSetAce();
      if (this_present_ace || that_present_ace) {
        if (!(this_present_ace && that_present_ace))
          return false;
        if (!this.ace.equals(that.ace))
          return false;
      }

      boolean this_present_ase = true && this.isSetAse();
      boolean that_present_ase = true && that.isSetAse();
      if (this_present_ase || that_present_ase) {
        if (!(this_present_ase && that_present_ase))
          return false;
        if (!this.ase.equals(that.ase))
          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() {
      List<Object> list = new ArrayList<Object>();

      boolean present_success = true && (isSetSuccess());
      list.add(present_success);
      if (present_success)
        list.add(success);

      boolean present_ire = true && (isSetIre());
      list.add(present_ire);
      if (present_ire)
        list.add(ire);

      boolean present_ace = true && (isSetAce());
      list.add(present_ace);
      if (present_ace)
        list.add(ace);

      boolean present_ase = true && (isSetAse());
      list.add(present_ase);
      if (present_ase)
        list.add(ase);

      boolean present_ae = true && (isSetAe());
      list.add(present_ae);
      if (present_ae)
        list.add(ae);

      return list.hashCode();
    }

    @Override
    public int compareTo(getAllApplicationDeployments_result other) {
      if (!getClass().equals(other.getClass())) {
        return getClass().getName().compareTo(other.getClass().getName());
      }

      int lastComparison = 0;

      lastComparison = Boolean.valueOf(isSetSuccess()).compareTo(other.isSetSuccess());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetSuccess()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.success, other.success);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = Boolean.valueOf(isSetIre()).compareTo(other.isSetIre());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetIre()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.ire, other.ire);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = Boolean.valueOf(isSetAce()).compareTo(other.isSetAce());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetAce()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.ace, other.ace);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = Boolean.valueOf(isSetAse()).compareTo(other.isSetAse());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetAse()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.ase, other.ase);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = 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 {
      schemes.get(iprot.getScheme()).getScheme().read(iprot, this);
    }

    public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException {
      schemes.get(oprot.getScheme()).getScheme().write(oprot, this);
      }

    @Override
    public String toString() {
      StringBuilder sb = new StringBuilder("getAllApplicationDeployments_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("ire:");
      if (this.ire == null) {
        sb.append("null");
      } else {
        sb.append(this.ire);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("ace:");
      if (this.ace == null) {
        sb.append("null");
      } else {
        sb.append(this.ace);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("ase:");
      if (this.ase == null) {
        sb.append("null");
      } else {
        sb.append(this.ase);
      }
      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, 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 getAllApplicationDeployments_resultStandardSchemeFactory implements SchemeFactory {
      public getAllApplicationDeployments_resultStandardScheme getScheme() {
        return new getAllApplicationDeployments_resultStandardScheme();
      }
    }

    private static class getAllApplicationDeployments_resultStandardScheme extends StandardScheme<getAllApplicationDeployments_result> {

      public void read(org.apache.thrift.protocol.TProtocol iprot, getAllApplicationDeployments_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 _list158 = iprot.readListBegin();
                  struct.success = new ArrayList<org.apache.airavata.model.appcatalog.appdeployment.ApplicationDeploymentDescription>(_list158.size);
                  org.apache.airavata.model.appcatalog.appdeployment.ApplicationDeploymentDescription _elem159;
                  for (int _i160 = 0; _i160 < _list158.size; ++_i160)
                  {
                    _elem159 = new org.apache.airavata.model.appcatalog.appdeployment.ApplicationDeploymentDescription();
                    _elem159.read(iprot);
                    struct.success.add(_elem159);
                  }
                  iprot.readListEnd();
                }
                struct.setSuccessIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 1: // IRE
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.ire = new org.apache.airavata.model.error.InvalidRequestException();
                struct.ire.read(iprot);
                struct.setIreIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 2: // ACE
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.ace = new org.apache.airavata.model.error.AiravataClientException();
                struct.ace.read(iprot);
                struct.setAceIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 3: // ASE
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.ase = new org.apache.airavata.model.error.AiravataSystemException();
                struct.ase.read(iprot);
                struct.setAseIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 4: // 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, getAllApplicationDeployments_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.appcatalog.appdeployment.ApplicationDeploymentDescription _iter161 : struct.success)
            {
              _iter161.write(oprot);
            }
            oprot.writeListEnd();
          }
          oprot.writeFieldEnd();
        }
        if (struct.ire != null) {
          oprot.writeFieldBegin(IRE_FIELD_DESC);
          struct.ire.write(oprot);
          oprot.writeFieldEnd();
        }
        if (struct.ace != null) {
          oprot.writeFieldBegin(ACE_FIELD_DESC);
          struct.ace.write(oprot);
          oprot.writeFieldEnd();
        }
        if (struct.ase != null) {
          oprot.writeFieldBegin(ASE_FIELD_DESC);
          struct.ase.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 getAllApplicationDeployments_resultTupleSchemeFactory implements SchemeFactory {
      public getAllApplicationDeployments_resultTupleScheme getScheme() {
        return new getAllApplicationDeployments_resultTupleScheme();
      }
    }

    private static class getAllApplicationDeployments_resultTupleScheme extends TupleScheme<getAllApplicationDeployments_result> {

      @Override
      public void write(org.apache.thrift.protocol.TProtocol prot, getAllApplicationDeployments_result struct) throws org.apache.thrift.TException {
        TTupleProtocol oprot = (TTupleProtocol) prot;
        BitSet optionals = new BitSet();
        if (struct.isSetSuccess()) {
          optionals.set(0);
        }
        if (struct.isSetIre()) {
          optionals.set(1);
        }
        if (struct.isSetAce()) {
          optionals.set(2);
        }
        if (struct.isSetAse()) {
          optionals.set(3);
        }
        if (struct.isSetAe()) {
          optionals.set(4);
        }
        oprot.writeBitSet(optionals, 5);
        if (struct.isSetSuccess()) {
          {
            oprot.writeI32(struct.success.size());
            for (org.apache.airavata.model.appcatalog.appdeployment.ApplicationDeploymentDescription _iter162 : struct.success)
            {
              _iter162.write(oprot);
            }
          }
        }
        if (struct.isSetIre()) {
          struct.ire.write(oprot);
        }
        if (struct.isSetAce()) {
          struct.ace.write(oprot);
        }
        if (struct.isSetAse()) {
          struct.ase.write(oprot);
        }
        if (struct.isSetAe()) {
          struct.ae.write(oprot);
        }
      }

      @Override
      public void read(org.apache.thrift.protocol.TProtocol prot, getAllApplicationDeployments_result struct) throws org.apache.thrift.TException {
        TTupleProtocol iprot = (TTupleProtocol) prot;
        BitSet incoming = iprot.readBitSet(5);
        if (incoming.get(0)) {
          {
            org.apache.thrift.protocol.TList _list163 = new org.apache.thrift.protocol.TList(org.apache.thrift.protocol.TType.STRUCT, iprot.readI32());
            struct.success = new ArrayList<org.apache.airavata.model.appcatalog.appdeployment.ApplicationDeploymentDescription>(_list163.size);
            org.apache.airavata.model.appcatalog.appdeployment.ApplicationDeploymentDescription _elem164;
            for (int _i165 = 0; _i165 < _list163.size; ++_i165)
            {
              _elem164 = new org.apache.airavata.model.appcatalog.appdeployment.ApplicationDeploymentDescription();
              _elem164.read(iprot);
              struct.success.add(_elem164);
            }
          }
          struct.setSuccessIsSet(true);
        }
        if (incoming.get(1)) {
          struct.ire = new org.apache.airavata.model.error.InvalidRequestException();
          struct.ire.read(iprot);
          struct.setIreIsSet(true);
        }
        if (incoming.get(2)) {
          struct.ace = new org.apache.airavata.model.error.AiravataClientException();
          struct.ace.read(iprot);
          struct.setAceIsSet(true);
        }
        if (incoming.get(3)) {
          struct.ase = new org.apache.airavata.model.error.AiravataSystemException();
          struct.ase.read(iprot);
          struct.setAseIsSet(true);
        }
        if (incoming.get(4)) {
          struct.ae = new org.apache.airavata.model.error.AuthorizationException();
          struct.ae.read(iprot);
          struct.setAeIsSet(true);
        }
      }
    }

  }

  public static class getAppModuleDeployedResources_args implements org.apache.thrift.TBase<getAppModuleDeployedResources_args, getAppModuleDeployedResources_args._Fields>, java.io.Serializable, Cloneable, Comparable<getAppModuleDeployedResources_args>   {
    private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("getAppModuleDeployedResources_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 APP_MODULE_ID_FIELD_DESC = new org.apache.thrift.protocol.TField("appModuleId", org.apache.thrift.protocol.TType.STRING, (short)2);

    private static final Map<Class<? extends IScheme>, SchemeFactory> schemes = new HashMap<Class<? extends IScheme>, SchemeFactory>();
    static {
      schemes.put(StandardScheme.class, new getAppModuleDeployedResources_argsStandardSchemeFactory());
      schemes.put(TupleScheme.class, new getAppModuleDeployedResources_argsTupleSchemeFactory());
    }

    public org.apache.airavata.model.security.AuthzToken authzToken; // required
    public String appModuleId; // required

    /** 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"),
      APP_MODULE_ID((short)2, "appModuleId");

      private static final Map<String, _Fields> byName = new HashMap<String, _Fields>();

      static {
        for (_Fields field : EnumSet.allOf(_Fields.class)) {
          byName.put(field.getFieldName(), field);
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, or null if its not found.
       */
      public static _Fields findByThriftId(int fieldId) {
        switch(fieldId) {
          case 1: // AUTHZ_TOKEN
            return AUTHZ_TOKEN;
          case 2: // APP_MODULE_ID
            return APP_MODULE_ID;
          default:
            return null;
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, throwing an exception
       * if it is not found.
       */
      public static _Fields findByThriftIdOrThrow(int fieldId) {
        _Fields fields = findByThriftId(fieldId);
        if (fields == null) throw new IllegalArgumentException("Field " + fieldId + " doesn't exist!");
        return fields;
      }

      /**
       * Find the _Fields constant that matches name, or null if its not found.
       */
      public static _Fields findByName(String name) {
        return byName.get(name);
      }

      private final short _thriftId;
      private final String _fieldName;

      _Fields(short thriftId, String fieldName) {
        _thriftId = thriftId;
        _fieldName = fieldName;
      }

      public short getThriftFieldId() {
        return _thriftId;
      }

      public String getFieldName() {
        return _fieldName;
      }
    }

    // isset id assignments
    public static final Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
    static {
      Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new EnumMap<_Fields, org.apache.thrift.meta_data.FieldMetaData>(_Fields.class);
      tmpMap.put(_Fields.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.APP_MODULE_ID, new org.apache.thrift.meta_data.FieldMetaData("appModuleId", org.apache.thrift.TFieldRequirementType.REQUIRED, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING)));
      metaDataMap = Collections.unmodifiableMap(tmpMap);
      org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(getAppModuleDeployedResources_args.class, metaDataMap);
    }

    public getAppModuleDeployedResources_args() {
    }

    public getAppModuleDeployedResources_args(
      org.apache.airavata.model.security.AuthzToken authzToken,
      String appModuleId)
    {
      this();
      this.authzToken = authzToken;
      this.appModuleId = appModuleId;
    }

    /**
     * Performs a deep copy on <i>other</i>.
     */
    public getAppModuleDeployedResources_args(getAppModuleDeployedResources_args other) {
      if (other.isSetAuthzToken()) {
        this.authzToken = new org.apache.airavata.model.security.AuthzToken(other.authzToken);
      }
      if (other.isSetAppModuleId()) {
        this.appModuleId = other.appModuleId;
      }
    }

    public getAppModuleDeployedResources_args deepCopy() {
      return new getAppModuleDeployedResources_args(this);
    }

    @Override
    public void clear() {
      this.authzToken = null;
      this.appModuleId = null;
    }

    public org.apache.airavata.model.security.AuthzToken getAuthzToken() {
      return this.authzToken;
    }

    public getAppModuleDeployedResources_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 String getAppModuleId() {
      return this.appModuleId;
    }

    public getAppModuleDeployedResources_args setAppModuleId(String appModuleId) {
      this.appModuleId = appModuleId;
      return this;
    }

    public void unsetAppModuleId() {
      this.appModuleId = null;
    }

    /** Returns true if field appModuleId is set (has been assigned a value) and false otherwise */
    public boolean isSetAppModuleId() {
      return this.appModuleId != null;
    }

    public void setAppModuleIdIsSet(boolean value) {
      if (!value) {
        this.appModuleId = null;
      }
    }

    public void setFieldValue(_Fields field, Object value) {
      switch (field) {
      case AUTHZ_TOKEN:
        if (value == null) {
          unsetAuthzToken();
        } else {
          setAuthzToken((org.apache.airavata.model.security.AuthzToken)value);
        }
        break;

      case APP_MODULE_ID:
        if (value == null) {
          unsetAppModuleId();
        } else {
          setAppModuleId((String)value);
        }
        break;

      }
    }

    public Object getFieldValue(_Fields field) {
      switch (field) {
      case AUTHZ_TOKEN:
        return getAuthzToken();

      case APP_MODULE_ID:
        return getAppModuleId();

      }
      throw new IllegalStateException();
    }

    /** Returns true if field corresponding to fieldID is set (has been assigned a value) and false otherwise */
    public boolean isSet(_Fields field) {
      if (field == null) {
        throw new IllegalArgumentException();
      }

      switch (field) {
      case AUTHZ_TOKEN:
        return isSetAuthzToken();
      case APP_MODULE_ID:
        return isSetAppModuleId();
      }
      throw new IllegalStateException();
    }

    @Override
    public boolean equals(Object that) {
      if (that == null)
        return false;
      if (that instanceof getAppModuleDeployedResources_args)
        return this.equals((getAppModuleDeployedResources_args)that);
      return false;
    }

    public boolean equals(getAppModuleDeployedResources_args that) {
      if (that == null)
        return false;

      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_appModuleId = true && this.isSetAppModuleId();
      boolean that_present_appModuleId = true && that.isSetAppModuleId();
      if (this_present_appModuleId || that_present_appModuleId) {
        if (!(this_present_appModuleId && that_present_appModuleId))
          return false;
        if (!this.appModuleId.equals(that.appModuleId))
          return false;
      }

      return true;
    }

    @Override
    public int hashCode() {
      List<Object> list = new ArrayList<Object>();

      boolean present_authzToken = true && (isSetAuthzToken());
      list.add(present_authzToken);
      if (present_authzToken)
        list.add(authzToken);

      boolean present_appModuleId = true && (isSetAppModuleId());
      list.add(present_appModuleId);
      if (present_appModuleId)
        list.add(appModuleId);

      return list.hashCode();
    }

    @Override
    public int compareTo(getAppModuleDeployedResources_args other) {
      if (!getClass().equals(other.getClass())) {
        return getClass().getName().compareTo(other.getClass().getName());
      }

      int lastComparison = 0;

      lastComparison = 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 = Boolean.valueOf(isSetAppModuleId()).compareTo(other.isSetAppModuleId());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetAppModuleId()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.appModuleId, other.appModuleId);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      return 0;
    }

    public _Fields fieldForId(int fieldId) {
      return _Fields.findByThriftId(fieldId);
    }

    public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
      schemes.get(iprot.getScheme()).getScheme().read(iprot, this);
    }

    public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException {
      schemes.get(oprot.getScheme()).getScheme().write(oprot, this);
    }

    @Override
    public String toString() {
      StringBuilder sb = new StringBuilder("getAppModuleDeployedResources_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("appModuleId:");
      if (this.appModuleId == null) {
        sb.append("null");
      } else {
        sb.append(this.appModuleId);
      }
      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 (appModuleId == null) {
        throw new org.apache.thrift.protocol.TProtocolException("Required field 'appModuleId' 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, 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 getAppModuleDeployedResources_argsStandardSchemeFactory implements SchemeFactory {
      public getAppModuleDeployedResources_argsStandardScheme getScheme() {
        return new getAppModuleDeployedResources_argsStandardScheme();
      }
    }

    private static class getAppModuleDeployedResources_argsStandardScheme extends StandardScheme<getAppModuleDeployedResources_args> {

      public void read(org.apache.thrift.protocol.TProtocol iprot, getAppModuleDeployedResources_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: // APP_MODULE_ID
              if (schemeField.type == org.apache.thrift.protocol.TType.STRING) {
                struct.appModuleId = iprot.readString();
                struct.setAppModuleIdIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            default:
              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
          }
          iprot.readFieldEnd();
        }
        iprot.readStructEnd();

        // check for required fields of primitive type, which can't be checked in the validate method
        struct.validate();
      }

      public void write(org.apache.thrift.protocol.TProtocol oprot, getAppModuleDeployedResources_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.appModuleId != null) {
          oprot.writeFieldBegin(APP_MODULE_ID_FIELD_DESC);
          oprot.writeString(struct.appModuleId);
          oprot.writeFieldEnd();
        }
        oprot.writeFieldStop();
        oprot.writeStructEnd();
      }

    }

    private static class getAppModuleDeployedResources_argsTupleSchemeFactory implements SchemeFactory {
      public getAppModuleDeployedResources_argsTupleScheme getScheme() {
        return new getAppModuleDeployedResources_argsTupleScheme();
      }
    }

    private static class getAppModuleDeployedResources_argsTupleScheme extends TupleScheme<getAppModuleDeployedResources_args> {

      @Override
      public void write(org.apache.thrift.protocol.TProtocol prot, getAppModuleDeployedResources_args struct) throws org.apache.thrift.TException {
        TTupleProtocol oprot = (TTupleProtocol) prot;
        struct.authzToken.write(oprot);
        oprot.writeString(struct.appModuleId);
      }

      @Override
      public void read(org.apache.thrift.protocol.TProtocol prot, getAppModuleDeployedResources_args struct) throws org.apache.thrift.TException {
        TTupleProtocol iprot = (TTupleProtocol) prot;
        struct.authzToken = new org.apache.airavata.model.security.AuthzToken();
        struct.authzToken.read(iprot);
        struct.setAuthzTokenIsSet(true);
        struct.appModuleId = iprot.readString();
        struct.setAppModuleIdIsSet(true);
      }
    }

  }

  public static class getAppModuleDeployedResources_result implements org.apache.thrift.TBase<getAppModuleDeployedResources_result, getAppModuleDeployedResources_result._Fields>, java.io.Serializable, Cloneable, Comparable<getAppModuleDeployedResources_result>   {
    private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("getAppModuleDeployedResources_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 IRE_FIELD_DESC = new org.apache.thrift.protocol.TField("ire", org.apache.thrift.protocol.TType.STRUCT, (short)1);
    private static final org.apache.thrift.protocol.TField ACE_FIELD_DESC = new org.apache.thrift.protocol.TField("ace", org.apache.thrift.protocol.TType.STRUCT, (short)2);
    private static final org.apache.thrift.protocol.TField ASE_FIELD_DESC = new org.apache.thrift.protocol.TField("ase", org.apache.thrift.protocol.TType.STRUCT, (short)3);
    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)4);

    private static final Map<Class<? extends IScheme>, SchemeFactory> schemes = new HashMap<Class<? extends IScheme>, SchemeFactory>();
    static {
      schemes.put(StandardScheme.class, new getAppModuleDeployedResources_resultStandardSchemeFactory());
      schemes.put(TupleScheme.class, new getAppModuleDeployedResources_resultTupleSchemeFactory());
    }

    public List<String> success; // required
    public org.apache.airavata.model.error.InvalidRequestException ire; // required
    public org.apache.airavata.model.error.AiravataClientException ace; // required
    public org.apache.airavata.model.error.AiravataSystemException ase; // 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"),
      IRE((short)1, "ire"),
      ACE((short)2, "ace"),
      ASE((short)3, "ase"),
      AE((short)4, "ae");

      private static final Map<String, _Fields> byName = new HashMap<String, _Fields>();

      static {
        for (_Fields field : EnumSet.allOf(_Fields.class)) {
          byName.put(field.getFieldName(), field);
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, or null if its not found.
       */
      public static _Fields findByThriftId(int fieldId) {
        switch(fieldId) {
          case 0: // SUCCESS
            return SUCCESS;
          case 1: // IRE
            return IRE;
          case 2: // ACE
            return ACE;
          case 3: // ASE
            return ASE;
          case 4: // 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 IllegalArgumentException("Field " + fieldId + " doesn't exist!");
        return fields;
      }

      /**
       * Find the _Fields constant that matches name, or null if its not found.
       */
      public static _Fields findByName(String name) {
        return byName.get(name);
      }

      private final short _thriftId;
      private final String _fieldName;

      _Fields(short thriftId, String fieldName) {
        _thriftId = thriftId;
        _fieldName = fieldName;
      }

      public short getThriftFieldId() {
        return _thriftId;
      }

      public String getFieldName() {
        return _fieldName;
      }
    }

    // isset id assignments
    public static final Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
    static {
      Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new EnumMap<_Fields, org.apache.thrift.meta_data.FieldMetaData>(_Fields.class);
      tmpMap.put(_Fields.SUCCESS, new org.apache.thrift.meta_data.FieldMetaData("success", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.ListMetaData(org.apache.thrift.protocol.TType.LIST, 
              new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING))));
      tmpMap.put(_Fields.IRE, new org.apache.thrift.meta_data.FieldMetaData("ire", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRUCT)));
      tmpMap.put(_Fields.ACE, new org.apache.thrift.meta_data.FieldMetaData("ace", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRUCT)));
      tmpMap.put(_Fields.ASE, new org.apache.thrift.meta_data.FieldMetaData("ase", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRUCT)));
      tmpMap.put(_Fields.AE, new org.apache.thrift.meta_data.FieldMetaData("ae", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRUCT)));
      metaDataMap = Collections.unmodifiableMap(tmpMap);
      org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(getAppModuleDeployedResources_result.class, metaDataMap);
    }

    public getAppModuleDeployedResources_result() {
    }

    public getAppModuleDeployedResources_result(
      List<String> success,
      org.apache.airavata.model.error.InvalidRequestException ire,
      org.apache.airavata.model.error.AiravataClientException ace,
      org.apache.airavata.model.error.AiravataSystemException ase,
      org.apache.airavata.model.error.AuthorizationException ae)
    {
      this();
      this.success = success;
      this.ire = ire;
      this.ace = ace;
      this.ase = ase;
      this.ae = ae;
    }

    /**
     * Performs a deep copy on <i>other</i>.
     */
    public getAppModuleDeployedResources_result(getAppModuleDeployedResources_result other) {
      if (other.isSetSuccess()) {
        List<String> __this__success = new ArrayList<String>(other.success);
        this.success = __this__success;
      }
      if (other.isSetIre()) {
        this.ire = new org.apache.airavata.model.error.InvalidRequestException(other.ire);
      }
      if (other.isSetAce()) {
        this.ace = new org.apache.airavata.model.error.AiravataClientException(other.ace);
      }
      if (other.isSetAse()) {
        this.ase = new org.apache.airavata.model.error.AiravataSystemException(other.ase);
      }
      if (other.isSetAe()) {
        this.ae = new org.apache.airavata.model.error.AuthorizationException(other.ae);
      }
    }

    public getAppModuleDeployedResources_result deepCopy() {
      return new getAppModuleDeployedResources_result(this);
    }

    @Override
    public void clear() {
      this.success = null;
      this.ire = null;
      this.ace = null;
      this.ase = null;
      this.ae = null;
    }

    public int getSuccessSize() {
      return (this.success == null) ? 0 : this.success.size();
    }

    public java.util.Iterator<String> getSuccessIterator() {
      return (this.success == null) ? null : this.success.iterator();
    }

    public void addToSuccess(String elem) {
      if (this.success == null) {
        this.success = new ArrayList<String>();
      }
      this.success.add(elem);
    }

    public List<String> getSuccess() {
      return this.success;
    }

    public getAppModuleDeployedResources_result setSuccess(List<String> success) {
      this.success = success;
      return this;
    }

    public void unsetSuccess() {
      this.success = null;
    }

    /** Returns true if field success is set (has been assigned a value) and false otherwise */
    public boolean isSetSuccess() {
      return this.success != null;
    }

    public void setSuccessIsSet(boolean value) {
      if (!value) {
        this.success = null;
      }
    }

    public org.apache.airavata.model.error.InvalidRequestException getIre() {
      return this.ire;
    }

    public getAppModuleDeployedResources_result setIre(org.apache.airavata.model.error.InvalidRequestException ire) {
      this.ire = ire;
      return this;
    }

    public void unsetIre() {
      this.ire = null;
    }

    /** Returns true if field ire is set (has been assigned a value) and false otherwise */
    public boolean isSetIre() {
      return this.ire != null;
    }

    public void setIreIsSet(boolean value) {
      if (!value) {
        this.ire = null;
      }
    }

    public org.apache.airavata.model.error.AiravataClientException getAce() {
      return this.ace;
    }

    public getAppModuleDeployedResources_result setAce(org.apache.airavata.model.error.AiravataClientException ace) {
      this.ace = ace;
      return this;
    }

    public void unsetAce() {
      this.ace = null;
    }

    /** Returns true if field ace is set (has been assigned a value) and false otherwise */
    public boolean isSetAce() {
      return this.ace != null;
    }

    public void setAceIsSet(boolean value) {
      if (!value) {
        this.ace = null;
      }
    }

    public org.apache.airavata.model.error.AiravataSystemException getAse() {
      return this.ase;
    }

    public getAppModuleDeployedResources_result setAse(org.apache.airavata.model.error.AiravataSystemException ase) {
      this.ase = ase;
      return this;
    }

    public void unsetAse() {
      this.ase = null;
    }

    /** Returns true if field ase is set (has been assigned a value) and false otherwise */
    public boolean isSetAse() {
      return this.ase != null;
    }

    public void setAseIsSet(boolean value) {
      if (!value) {
        this.ase = null;
      }
    }

    public org.apache.airavata.model.error.AuthorizationException getAe() {
      return this.ae;
    }

    public getAppModuleDeployedResources_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, Object value) {
      switch (field) {
      case SUCCESS:
        if (value == null) {
          unsetSuccess();
        } else {
          setSuccess((List<String>)value);
        }
        break;

      case IRE:
        if (value == null) {
          unsetIre();
        } else {
          setIre((org.apache.airavata.model.error.InvalidRequestException)value);
        }
        break;

      case ACE:
        if (value == null) {
          unsetAce();
        } else {
          setAce((org.apache.airavata.model.error.AiravataClientException)value);
        }
        break;

      case ASE:
        if (value == null) {
          unsetAse();
        } else {
          setAse((org.apache.airavata.model.error.AiravataSystemException)value);
        }
        break;

      case AE:
        if (value == null) {
          unsetAe();
        } else {
          setAe((org.apache.airavata.model.error.AuthorizationException)value);
        }
        break;

      }
    }

    public Object getFieldValue(_Fields field) {
      switch (field) {
      case SUCCESS:
        return getSuccess();

      case IRE:
        return getIre();

      case ACE:
        return getAce();

      case ASE:
        return getAse();

      case AE:
        return getAe();

      }
      throw new IllegalStateException();
    }

    /** Returns true if field corresponding to fieldID is set (has been assigned a value) and false otherwise */
    public boolean isSet(_Fields field) {
      if (field == null) {
        throw new IllegalArgumentException();
      }

      switch (field) {
      case SUCCESS:
        return isSetSuccess();
      case IRE:
        return isSetIre();
      case ACE:
        return isSetAce();
      case ASE:
        return isSetAse();
      case AE:
        return isSetAe();
      }
      throw new IllegalStateException();
    }

    @Override
    public boolean equals(Object that) {
      if (that == null)
        return false;
      if (that instanceof getAppModuleDeployedResources_result)
        return this.equals((getAppModuleDeployedResources_result)that);
      return false;
    }

    public boolean equals(getAppModuleDeployedResources_result that) {
      if (that == null)
        return false;

      boolean this_present_success = true && this.isSetSuccess();
      boolean that_present_success = true && that.isSetSuccess();
      if (this_present_success || that_present_success) {
        if (!(this_present_success && that_present_success))
          return false;
        if (!this.success.equals(that.success))
          return false;
      }

      boolean this_present_ire = true && this.isSetIre();
      boolean that_present_ire = true && that.isSetIre();
      if (this_present_ire || that_present_ire) {
        if (!(this_present_ire && that_present_ire))
          return false;
        if (!this.ire.equals(that.ire))
          return false;
      }

      boolean this_present_ace = true && this.isSetAce();
      boolean that_present_ace = true && that.isSetAce();
      if (this_present_ace || that_present_ace) {
        if (!(this_present_ace && that_present_ace))
          return false;
        if (!this.ace.equals(that.ace))
          return false;
      }

      boolean this_present_ase = true && this.isSetAse();
      boolean that_present_ase = true && that.isSetAse();
      if (this_present_ase || that_present_ase) {
        if (!(this_present_ase && that_present_ase))
          return false;
        if (!this.ase.equals(that.ase))
          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() {
      List<Object> list = new ArrayList<Object>();

      boolean present_success = true && (isSetSuccess());
      list.add(present_success);
      if (present_success)
        list.add(success);

      boolean present_ire = true && (isSetIre());
      list.add(present_ire);
      if (present_ire)
        list.add(ire);

      boolean present_ace = true && (isSetAce());
      list.add(present_ace);
      if (present_ace)
        list.add(ace);

      boolean present_ase = true && (isSetAse());
      list.add(present_ase);
      if (present_ase)
        list.add(ase);

      boolean present_ae = true && (isSetAe());
      list.add(present_ae);
      if (present_ae)
        list.add(ae);

      return list.hashCode();
    }

    @Override
    public int compareTo(getAppModuleDeployedResources_result other) {
      if (!getClass().equals(other.getClass())) {
        return getClass().getName().compareTo(other.getClass().getName());
      }

      int lastComparison = 0;

      lastComparison = Boolean.valueOf(isSetSuccess()).compareTo(other.isSetSuccess());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetSuccess()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.success, other.success);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = Boolean.valueOf(isSetIre()).compareTo(other.isSetIre());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetIre()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.ire, other.ire);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = Boolean.valueOf(isSetAce()).compareTo(other.isSetAce());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetAce()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.ace, other.ace);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = Boolean.valueOf(isSetAse()).compareTo(other.isSetAse());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetAse()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.ase, other.ase);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = 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 {
      schemes.get(iprot.getScheme()).getScheme().read(iprot, this);
    }

    public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException {
      schemes.get(oprot.getScheme()).getScheme().write(oprot, this);
      }

    @Override
    public String toString() {
      StringBuilder sb = new StringBuilder("getAppModuleDeployedResources_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("ire:");
      if (this.ire == null) {
        sb.append("null");
      } else {
        sb.append(this.ire);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("ace:");
      if (this.ace == null) {
        sb.append("null");
      } else {
        sb.append(this.ace);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("ase:");
      if (this.ase == null) {
        sb.append("null");
      } else {
        sb.append(this.ase);
      }
      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, 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 getAppModuleDeployedResources_resultStandardSchemeFactory implements SchemeFactory {
      public getAppModuleDeployedResources_resultStandardScheme getScheme() {
        return new getAppModuleDeployedResources_resultStandardScheme();
      }
    }

    private static class getAppModuleDeployedResources_resultStandardScheme extends StandardScheme<getAppModuleDeployedResources_result> {

      public void read(org.apache.thrift.protocol.TProtocol iprot, getAppModuleDeployedResources_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 _list166 = iprot.readListBegin();
                  struct.success = new ArrayList<String>(_list166.size);
                  String _elem167;
                  for (int _i168 = 0; _i168 < _list166.size; ++_i168)
                  {
                    _elem167 = iprot.readString();
                    struct.success.add(_elem167);
                  }
                  iprot.readListEnd();
                }
                struct.setSuccessIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 1: // IRE
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.ire = new org.apache.airavata.model.error.InvalidRequestException();
                struct.ire.read(iprot);
                struct.setIreIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 2: // ACE
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.ace = new org.apache.airavata.model.error.AiravataClientException();
                struct.ace.read(iprot);
                struct.setAceIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 3: // ASE
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.ase = new org.apache.airavata.model.error.AiravataSystemException();
                struct.ase.read(iprot);
                struct.setAseIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 4: // 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, getAppModuleDeployedResources_result struct) throws org.apache.thrift.TException {
        struct.validate();

        oprot.writeStructBegin(STRUCT_DESC);
        if (struct.success != null) {
          oprot.writeFieldBegin(SUCCESS_FIELD_DESC);
          {
            oprot.writeListBegin(new org.apache.thrift.protocol.TList(org.apache.thrift.protocol.TType.STRING, struct.success.size()));
            for (String _iter169 : struct.success)
            {
              oprot.writeString(_iter169);
            }
            oprot.writeListEnd();
          }
          oprot.writeFieldEnd();
        }
        if (struct.ire != null) {
          oprot.writeFieldBegin(IRE_FIELD_DESC);
          struct.ire.write(oprot);
          oprot.writeFieldEnd();
        }
        if (struct.ace != null) {
          oprot.writeFieldBegin(ACE_FIELD_DESC);
          struct.ace.write(oprot);
          oprot.writeFieldEnd();
        }
        if (struct.ase != null) {
          oprot.writeFieldBegin(ASE_FIELD_DESC);
          struct.ase.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 getAppModuleDeployedResources_resultTupleSchemeFactory implements SchemeFactory {
      public getAppModuleDeployedResources_resultTupleScheme getScheme() {
        return new getAppModuleDeployedResources_resultTupleScheme();
      }
    }

    private static class getAppModuleDeployedResources_resultTupleScheme extends TupleScheme<getAppModuleDeployedResources_result> {

      @Override
      public void write(org.apache.thrift.protocol.TProtocol prot, getAppModuleDeployedResources_result struct) throws org.apache.thrift.TException {
        TTupleProtocol oprot = (TTupleProtocol) prot;
        BitSet optionals = new BitSet();
        if (struct.isSetSuccess()) {
          optionals.set(0);
        }
        if (struct.isSetIre()) {
          optionals.set(1);
        }
        if (struct.isSetAce()) {
          optionals.set(2);
        }
        if (struct.isSetAse()) {
          optionals.set(3);
        }
        if (struct.isSetAe()) {
          optionals.set(4);
        }
        oprot.writeBitSet(optionals, 5);
        if (struct.isSetSuccess()) {
          {
            oprot.writeI32(struct.success.size());
            for (String _iter170 : struct.success)
            {
              oprot.writeString(_iter170);
            }
          }
        }
        if (struct.isSetIre()) {
          struct.ire.write(oprot);
        }
        if (struct.isSetAce()) {
          struct.ace.write(oprot);
        }
        if (struct.isSetAse()) {
          struct.ase.write(oprot);
        }
        if (struct.isSetAe()) {
          struct.ae.write(oprot);
        }
      }

      @Override
      public void read(org.apache.thrift.protocol.TProtocol prot, getAppModuleDeployedResources_result struct) throws org.apache.thrift.TException {
        TTupleProtocol iprot = (TTupleProtocol) prot;
        BitSet incoming = iprot.readBitSet(5);
        if (incoming.get(0)) {
          {
            org.apache.thrift.protocol.TList _list171 = new org.apache.thrift.protocol.TList(org.apache.thrift.protocol.TType.STRING, iprot.readI32());
            struct.success = new ArrayList<String>(_list171.size);
            String _elem172;
            for (int _i173 = 0; _i173 < _list171.size; ++_i173)
            {
              _elem172 = iprot.readString();
              struct.success.add(_elem172);
            }
          }
          struct.setSuccessIsSet(true);
        }
        if (incoming.get(1)) {
          struct.ire = new org.apache.airavata.model.error.InvalidRequestException();
          struct.ire.read(iprot);
          struct.setIreIsSet(true);
        }
        if (incoming.get(2)) {
          struct.ace = new org.apache.airavata.model.error.AiravataClientException();
          struct.ace.read(iprot);
          struct.setAceIsSet(true);
        }
        if (incoming.get(3)) {
          struct.ase = new org.apache.airavata.model.error.AiravataSystemException();
          struct.ase.read(iprot);
          struct.setAseIsSet(true);
        }
        if (incoming.get(4)) {
          struct.ae = new org.apache.airavata.model.error.AuthorizationException();
          struct.ae.read(iprot);
          struct.setAeIsSet(true);
        }
      }
    }

  }

  public static class registerApplicationInterface_args implements org.apache.thrift.TBase<registerApplicationInterface_args, registerApplicationInterface_args._Fields>, java.io.Serializable, Cloneable, Comparable<registerApplicationInterface_args>   {
    private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("registerApplicationInterface_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.protocol.TField APPLICATION_INTERFACE_FIELD_DESC = new org.apache.thrift.protocol.TField("applicationInterface", org.apache.thrift.protocol.TType.STRUCT, (short)3);

    private static final Map<Class<? extends IScheme>, SchemeFactory> schemes = new HashMap<Class<? extends IScheme>, SchemeFactory>();
    static {
      schemes.put(StandardScheme.class, new registerApplicationInterface_argsStandardSchemeFactory());
      schemes.put(TupleScheme.class, new registerApplicationInterface_argsTupleSchemeFactory());
    }

    public org.apache.airavata.model.security.AuthzToken authzToken; // required
    public String gatewayId; // required
    public org.apache.airavata.model.appcatalog.appinterface.ApplicationInterfaceDescription applicationInterface; // required

    /** 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"),
      APPLICATION_INTERFACE((short)3, "applicationInterface");

      private static final Map<String, _Fields> byName = new HashMap<String, _Fields>();

      static {
        for (_Fields field : EnumSet.allOf(_Fields.class)) {
          byName.put(field.getFieldName(), field);
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, or null if its not found.
       */
      public static _Fields findByThriftId(int fieldId) {
        switch(fieldId) {
          case 1: // AUTHZ_TOKEN
            return AUTHZ_TOKEN;
          case 2: // GATEWAY_ID
            return GATEWAY_ID;
          case 3: // APPLICATION_INTERFACE
            return APPLICATION_INTERFACE;
          default:
            return null;
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, throwing an exception
       * if it is not found.
       */
      public static _Fields findByThriftIdOrThrow(int fieldId) {
        _Fields fields = findByThriftId(fieldId);
        if (fields == null) throw new IllegalArgumentException("Field " + fieldId + " doesn't exist!");
        return fields;
      }

      /**
       * Find the _Fields constant that matches name, or null if its not found.
       */
      public static _Fields findByName(String name) {
        return byName.get(name);
      }

      private final short _thriftId;
      private final String _fieldName;

      _Fields(short thriftId, String fieldName) {
        _thriftId = thriftId;
        _fieldName = fieldName;
      }

      public short getThriftFieldId() {
        return _thriftId;
      }

      public String getFieldName() {
        return _fieldName;
      }
    }

    // isset id assignments
    public static final Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
    static {
      Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new EnumMap<_Fields, org.apache.thrift.meta_data.FieldMetaData>(_Fields.class);
      tmpMap.put(_Fields.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)));
      tmpMap.put(_Fields.APPLICATION_INTERFACE, new org.apache.thrift.meta_data.FieldMetaData("applicationInterface", org.apache.thrift.TFieldRequirementType.REQUIRED, 
          new org.apache.thrift.meta_data.StructMetaData(org.apache.thrift.protocol.TType.STRUCT, org.apache.airavata.model.appcatalog.appinterface.ApplicationInterfaceDescription.class)));
      metaDataMap = Collections.unmodifiableMap(tmpMap);
      org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(registerApplicationInterface_args.class, metaDataMap);
    }

    public registerApplicationInterface_args() {
    }

    public registerApplicationInterface_args(
      org.apache.airavata.model.security.AuthzToken authzToken,
      String gatewayId,
      org.apache.airavata.model.appcatalog.appinterface.ApplicationInterfaceDescription applicationInterface)
    {
      this();
      this.authzToken = authzToken;
      this.gatewayId = gatewayId;
      this.applicationInterface = applicationInterface;
    }

    /**
     * Performs a deep copy on <i>other</i>.
     */
    public registerApplicationInterface_args(registerApplicationInterface_args other) {
      if (other.isSetAuthzToken()) {
        this.authzToken = new org.apache.airavata.model.security.AuthzToken(other.authzToken);
      }
      if (other.isSetGatewayId()) {
        this.gatewayId = other.gatewayId;
      }
      if (other.isSetApplicationInterface()) {
        this.applicationInterface = new org.apache.airavata.model.appcatalog.appinterface.ApplicationInterfaceDescription(other.applicationInterface);
      }
    }

    public registerApplicationInterface_args deepCopy() {
      return new registerApplicationInterface_args(this);
    }

    @Override
    public void clear() {
      this.authzToken = null;
      this.gatewayId = null;
      this.applicationInterface = null;
    }

    public org.apache.airavata.model.security.AuthzToken getAuthzToken() {
      return this.authzToken;
    }

    public registerApplicationInterface_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 String getGatewayId() {
      return this.gatewayId;
    }

    public registerApplicationInterface_args setGatewayId(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 org.apache.airavata.model.appcatalog.appinterface.ApplicationInterfaceDescription getApplicationInterface() {
      return this.applicationInterface;
    }

    public registerApplicationInterface_args setApplicationInterface(org.apache.airavata.model.appcatalog.appinterface.ApplicationInterfaceDescription applicationInterface) {
      this.applicationInterface = applicationInterface;
      return this;
    }

    public void unsetApplicationInterface() {
      this.applicationInterface = null;
    }

    /** Returns true if field applicationInterface is set (has been assigned a value) and false otherwise */
    public boolean isSetApplicationInterface() {
      return this.applicationInterface != null;
    }

    public void setApplicationInterfaceIsSet(boolean value) {
      if (!value) {
        this.applicationInterface = null;
      }
    }

    public void setFieldValue(_Fields field, 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((String)value);
        }
        break;

      case APPLICATION_INTERFACE:
        if (value == null) {
          unsetApplicationInterface();
        } else {
          setApplicationInterface((org.apache.airavata.model.appcatalog.appinterface.ApplicationInterfaceDescription)value);
        }
        break;

      }
    }

    public Object getFieldValue(_Fields field) {
      switch (field) {
      case AUTHZ_TOKEN:
        return getAuthzToken();

      case GATEWAY_ID:
        return getGatewayId();

      case APPLICATION_INTERFACE:
        return getApplicationInterface();

      }
      throw new IllegalStateException();
    }

    /** Returns true if field corresponding to fieldID is set (has been assigned a value) and false otherwise */
    public boolean isSet(_Fields field) {
      if (field == null) {
        throw new IllegalArgumentException();
      }

      switch (field) {
      case AUTHZ_TOKEN:
        return isSetAuthzToken();
      case GATEWAY_ID:
        return isSetGatewayId();
      case APPLICATION_INTERFACE:
        return isSetApplicationInterface();
      }
      throw new IllegalStateException();
    }

    @Override
    public boolean equals(Object that) {
      if (that == null)
        return false;
      if (that instanceof registerApplicationInterface_args)
        return this.equals((registerApplicationInterface_args)that);
      return false;
    }

    public boolean equals(registerApplicationInterface_args that) {
      if (that == null)
        return false;

      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;
      }

      boolean this_present_applicationInterface = true && this.isSetApplicationInterface();
      boolean that_present_applicationInterface = true && that.isSetApplicationInterface();
      if (this_present_applicationInterface || that_present_applicationInterface) {
        if (!(this_present_applicationInterface && that_present_applicationInterface))
          return false;
        if (!this.applicationInterface.equals(that.applicationInterface))
          return false;
      }

      return true;
    }

    @Override
    public int hashCode() {
      List<Object> list = new ArrayList<Object>();

      boolean present_authzToken = true && (isSetAuthzToken());
      list.add(present_authzToken);
      if (present_authzToken)
        list.add(authzToken);

      boolean present_gatewayId = true && (isSetGatewayId());
      list.add(present_gatewayId);
      if (present_gatewayId)
        list.add(gatewayId);

      boolean present_applicationInterface = true && (isSetApplicationInterface());
      list.add(present_applicationInterface);
      if (present_applicationInterface)
        list.add(applicationInterface);

      return list.hashCode();
    }

    @Override
    public int compareTo(registerApplicationInterface_args other) {
      if (!getClass().equals(other.getClass())) {
        return getClass().getName().compareTo(other.getClass().getName());
      }

      int lastComparison = 0;

      lastComparison = 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 = 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;
        }
      }
      lastComparison = Boolean.valueOf(isSetApplicationInterface()).compareTo(other.isSetApplicationInterface());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetApplicationInterface()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.applicationInterface, other.applicationInterface);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      return 0;
    }

    public _Fields fieldForId(int fieldId) {
      return _Fields.findByThriftId(fieldId);
    }

    public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
      schemes.get(iprot.getScheme()).getScheme().read(iprot, this);
    }

    public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException {
      schemes.get(oprot.getScheme()).getScheme().write(oprot, this);
    }

    @Override
    public String toString() {
      StringBuilder sb = new StringBuilder("registerApplicationInterface_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;
      if (!first) sb.append(", ");
      sb.append("applicationInterface:");
      if (this.applicationInterface == null) {
        sb.append("null");
      } else {
        sb.append(this.applicationInterface);
      }
      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());
      }
      if (applicationInterface == null) {
        throw new org.apache.thrift.protocol.TProtocolException("Required field 'applicationInterface' was not present! Struct: " + toString());
      }
      // check for sub-struct validity
      if (authzToken != null) {
        authzToken.validate();
      }
      if (applicationInterface != null) {
        applicationInterface.validate();
      }
    }

    private void writeObject(java.io.ObjectOutputStream out) throws java.io.IOException {
      try {
        write(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(out)));
      } catch (org.apache.thrift.TException te) {
        throw new java.io.IOException(te);
      }
    }

    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, ClassNotFoundException {
      try {
        read(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(in)));
      } catch (org.apache.thrift.TException te) {
        throw new java.io.IOException(te);
      }
    }

    private static class registerApplicationInterface_argsStandardSchemeFactory implements SchemeFactory {
      public registerApplicationInterface_argsStandardScheme getScheme() {
        return new registerApplicationInterface_argsStandardScheme();
      }
    }

    private static class registerApplicationInterface_argsStandardScheme extends StandardScheme<registerApplicationInterface_args> {

      public void read(org.apache.thrift.protocol.TProtocol iprot, registerApplicationInterface_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;
            case 3: // APPLICATION_INTERFACE
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.applicationInterface = new org.apache.airavata.model.appcatalog.appinterface.ApplicationInterfaceDescription();
                struct.applicationInterface.read(iprot);
                struct.setApplicationInterfaceIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            default:
              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
          }
          iprot.readFieldEnd();
        }
        iprot.readStructEnd();

        // check for required fields of primitive type, which can't be checked in the validate method
        struct.validate();
      }

      public void write(org.apache.thrift.protocol.TProtocol oprot, registerApplicationInterface_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();
        }
        if (struct.applicationInterface != null) {
          oprot.writeFieldBegin(APPLICATION_INTERFACE_FIELD_DESC);
          struct.applicationInterface.write(oprot);
          oprot.writeFieldEnd();
        }
        oprot.writeFieldStop();
        oprot.writeStructEnd();
      }

    }

    private static class registerApplicationInterface_argsTupleSchemeFactory implements SchemeFactory {
      public registerApplicationInterface_argsTupleScheme getScheme() {
        return new registerApplicationInterface_argsTupleScheme();
      }
    }

    private static class registerApplicationInterface_argsTupleScheme extends TupleScheme<registerApplicationInterface_args> {

      @Override
      public void write(org.apache.thrift.protocol.TProtocol prot, registerApplicationInterface_args struct) throws org.apache.thrift.TException {
        TTupleProtocol oprot = (TTupleProtocol) prot;
        struct.authzToken.write(oprot);
        oprot.writeString(struct.gatewayId);
        struct.applicationInterface.write(oprot);
      }

      @Override
      public void read(org.apache.thrift.protocol.TProtocol prot, registerApplicationInterface_args struct) throws org.apache.thrift.TException {
        TTupleProtocol iprot = (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);
        struct.applicationInterface = new org.apache.airavata.model.appcatalog.appinterface.ApplicationInterfaceDescription();
        struct.applicationInterface.read(iprot);
        struct.setApplicationInterfaceIsSet(true);
      }
    }

  }

  public static class registerApplicationInterface_result implements org.apache.thrift.TBase<registerApplicationInterface_result, registerApplicationInterface_result._Fields>, java.io.Serializable, Cloneable, Comparable<registerApplicationInterface_result>   {
    private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("registerApplicationInterface_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 IRE_FIELD_DESC = new org.apache.thrift.protocol.TField("ire", org.apache.thrift.protocol.TType.STRUCT, (short)1);
    private static final org.apache.thrift.protocol.TField ACE_FIELD_DESC = new org.apache.thrift.protocol.TField("ace", org.apache.thrift.protocol.TType.STRUCT, (short)2);
    private static final org.apache.thrift.protocol.TField ASE_FIELD_DESC = new org.apache.thrift.protocol.TField("ase", org.apache.thrift.protocol.TType.STRUCT, (short)3);
    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)4);

    private static final Map<Class<? extends IScheme>, SchemeFactory> schemes = new HashMap<Class<? extends IScheme>, SchemeFactory>();
    static {
      schemes.put(StandardScheme.class, new registerApplicationInterface_resultStandardSchemeFactory());
      schemes.put(TupleScheme.class, new registerApplicationInterface_resultTupleSchemeFactory());
    }

    public String success; // required
    public org.apache.airavata.model.error.InvalidRequestException ire; // required
    public org.apache.airavata.model.error.AiravataClientException ace; // required
    public org.apache.airavata.model.error.AiravataSystemException ase; // 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"),
      IRE((short)1, "ire"),
      ACE((short)2, "ace"),
      ASE((short)3, "ase"),
      AE((short)4, "ae");

      private static final Map<String, _Fields> byName = new HashMap<String, _Fields>();

      static {
        for (_Fields field : EnumSet.allOf(_Fields.class)) {
          byName.put(field.getFieldName(), field);
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, or null if its not found.
       */
      public static _Fields findByThriftId(int fieldId) {
        switch(fieldId) {
          case 0: // SUCCESS
            return SUCCESS;
          case 1: // IRE
            return IRE;
          case 2: // ACE
            return ACE;
          case 3: // ASE
            return ASE;
          case 4: // 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 IllegalArgumentException("Field " + fieldId + " doesn't exist!");
        return fields;
      }

      /**
       * Find the _Fields constant that matches name, or null if its not found.
       */
      public static _Fields findByName(String name) {
        return byName.get(name);
      }

      private final short _thriftId;
      private final String _fieldName;

      _Fields(short thriftId, String fieldName) {
        _thriftId = thriftId;
        _fieldName = fieldName;
      }

      public short getThriftFieldId() {
        return _thriftId;
      }

      public String getFieldName() {
        return _fieldName;
      }
    }

    // isset id assignments
    public static final Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
    static {
      Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new EnumMap<_Fields, org.apache.thrift.meta_data.FieldMetaData>(_Fields.class);
      tmpMap.put(_Fields.SUCCESS, new org.apache.thrift.meta_data.FieldMetaData("success", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING)));
      tmpMap.put(_Fields.IRE, new org.apache.thrift.meta_data.FieldMetaData("ire", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRUCT)));
      tmpMap.put(_Fields.ACE, new org.apache.thrift.meta_data.FieldMetaData("ace", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRUCT)));
      tmpMap.put(_Fields.ASE, new org.apache.thrift.meta_data.FieldMetaData("ase", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRUCT)));
      tmpMap.put(_Fields.AE, new org.apache.thrift.meta_data.FieldMetaData("ae", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRUCT)));
      metaDataMap = Collections.unmodifiableMap(tmpMap);
      org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(registerApplicationInterface_result.class, metaDataMap);
    }

    public registerApplicationInterface_result() {
    }

    public registerApplicationInterface_result(
      String success,
      org.apache.airavata.model.error.InvalidRequestException ire,
      org.apache.airavata.model.error.AiravataClientException ace,
      org.apache.airavata.model.error.AiravataSystemException ase,
      org.apache.airavata.model.error.AuthorizationException ae)
    {
      this();
      this.success = success;
      this.ire = ire;
      this.ace = ace;
      this.ase = ase;
      this.ae = ae;
    }

    /**
     * Performs a deep copy on <i>other</i>.
     */
    public registerApplicationInterface_result(registerApplicationInterface_result other) {
      if (other.isSetSuccess()) {
        this.success = other.success;
      }
      if (other.isSetIre()) {
        this.ire = new org.apache.airavata.model.error.InvalidRequestException(other.ire);
      }
      if (other.isSetAce()) {
        this.ace = new org.apache.airavata.model.error.AiravataClientException(other.ace);
      }
      if (other.isSetAse()) {
        this.ase = new org.apache.airavata.model.error.AiravataSystemException(other.ase);
      }
      if (other.isSetAe()) {
        this.ae = new org.apache.airavata.model.error.AuthorizationException(other.ae);
      }
    }

    public registerApplicationInterface_result deepCopy() {
      return new registerApplicationInterface_result(this);
    }

    @Override
    public void clear() {
      this.success = null;
      this.ire = null;
      this.ace = null;
      this.ase = null;
      this.ae = null;
    }

    public String getSuccess() {
      return this.success;
    }

    public registerApplicationInterface_result setSuccess(String success) {
      this.success = success;
      return this;
    }

    public void unsetSuccess() {
      this.success = null;
    }

    /** Returns true if field success is set (has been assigned a value) and false otherwise */
    public boolean isSetSuccess() {
      return this.success != null;
    }

    public void setSuccessIsSet(boolean value) {
      if (!value) {
        this.success = null;
      }
    }

    public org.apache.airavata.model.error.InvalidRequestException getIre() {
      return this.ire;
    }

    public registerApplicationInterface_result setIre(org.apache.airavata.model.error.InvalidRequestException ire) {
      this.ire = ire;
      return this;
    }

    public void unsetIre() {
      this.ire = null;
    }

    /** Returns true if field ire is set (has been assigned a value) and false otherwise */
    public boolean isSetIre() {
      return this.ire != null;
    }

    public void setIreIsSet(boolean value) {
      if (!value) {
        this.ire = null;
      }
    }

    public org.apache.airavata.model.error.AiravataClientException getAce() {
      return this.ace;
    }

    public registerApplicationInterface_result setAce(org.apache.airavata.model.error.AiravataClientException ace) {
      this.ace = ace;
      return this;
    }

    public void unsetAce() {
      this.ace = null;
    }

    /** Returns true if field ace is set (has been assigned a value) and false otherwise */
    public boolean isSetAce() {
      return this.ace != null;
    }

    public void setAceIsSet(boolean value) {
      if (!value) {
        this.ace = null;
      }
    }

    public org.apache.airavata.model.error.AiravataSystemException getAse() {
      return this.ase;
    }

    public registerApplicationInterface_result setAse(org.apache.airavata.model.error.AiravataSystemException ase) {
      this.ase = ase;
      return this;
    }

    public void unsetAse() {
      this.ase = null;
    }

    /** Returns true if field ase is set (has been assigned a value) and false otherwise */
    public boolean isSetAse() {
      return this.ase != null;
    }

    public void setAseIsSet(boolean value) {
      if (!value) {
        this.ase = null;
      }
    }

    public org.apache.airavata.model.error.AuthorizationException getAe() {
      return this.ae;
    }

    public registerApplicationInterface_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, Object value) {
      switch (field) {
      case SUCCESS:
        if (value == null) {
          unsetSuccess();
        } else {
          setSuccess((String)value);
        }
        break;

      case IRE:
        if (value == null) {
          unsetIre();
        } else {
          setIre((org.apache.airavata.model.error.InvalidRequestException)value);
        }
        break;

      case ACE:
        if (value == null) {
          unsetAce();
        } else {
          setAce((org.apache.airavata.model.error.AiravataClientException)value);
        }
        break;

      case ASE:
        if (value == null) {
          unsetAse();
        } else {
          setAse((org.apache.airavata.model.error.AiravataSystemException)value);
        }
        break;

      case AE:
        if (value == null) {
          unsetAe();
        } else {
          setAe((org.apache.airavata.model.error.AuthorizationException)value);
        }
        break;

      }
    }

    public Object getFieldValue(_Fields field) {
      switch (field) {
      case SUCCESS:
        return getSuccess();

      case IRE:
        return getIre();

      case ACE:
        return getAce();

      case ASE:
        return getAse();

      case AE:
        return getAe();

      }
      throw new IllegalStateException();
    }

    /** Returns true if field corresponding to fieldID is set (has been assigned a value) and false otherwise */
    public boolean isSet(_Fields field) {
      if (field == null) {
        throw new IllegalArgumentException();
      }

      switch (field) {
      case SUCCESS:
        return isSetSuccess();
      case IRE:
        return isSetIre();
      case ACE:
        return isSetAce();
      case ASE:
        return isSetAse();
      case AE:
        return isSetAe();
      }
      throw new IllegalStateException();
    }

    @Override
    public boolean equals(Object that) {
      if (that == null)
        return false;
      if (that instanceof registerApplicationInterface_result)
        return this.equals((registerApplicationInterface_result)that);
      return false;
    }

    public boolean equals(registerApplicationInterface_result that) {
      if (that == null)
        return false;

      boolean this_present_success = true && this.isSetSuccess();
      boolean that_present_success = true && that.isSetSuccess();
      if (this_present_success || that_present_success) {
        if (!(this_present_success && that_present_success))
          return false;
        if (!this.success.equals(that.success))
          return false;
      }

      boolean this_present_ire = true && this.isSetIre();
      boolean that_present_ire = true && that.isSetIre();
      if (this_present_ire || that_present_ire) {
        if (!(this_present_ire && that_present_ire))
          return false;
        if (!this.ire.equals(that.ire))
          return false;
      }

      boolean this_present_ace = true && this.isSetAce();
      boolean that_present_ace = true && that.isSetAce();
      if (this_present_ace || that_present_ace) {
        if (!(this_present_ace && that_present_ace))
          return false;
        if (!this.ace.equals(that.ace))
          return false;
      }

      boolean this_present_ase = true && this.isSetAse();
      boolean that_present_ase = true && that.isSetAse();
      if (this_present_ase || that_present_ase) {
        if (!(this_present_ase && that_present_ase))
          return false;
        if (!this.ase.equals(that.ase))
          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() {
      List<Object> list = new ArrayList<Object>();

      boolean present_success = true && (isSetSuccess());
      list.add(present_success);
      if (present_success)
        list.add(success);

      boolean present_ire = true && (isSetIre());
      list.add(present_ire);
      if (present_ire)
        list.add(ire);

      boolean present_ace = true && (isSetAce());
      list.add(present_ace);
      if (present_ace)
        list.add(ace);

      boolean present_ase = true && (isSetAse());
      list.add(present_ase);
      if (present_ase)
        list.add(ase);

      boolean present_ae = true && (isSetAe());
      list.add(present_ae);
      if (present_ae)
        list.add(ae);

      return list.hashCode();
    }

    @Override
    public int compareTo(registerApplicationInterface_result other) {
      if (!getClass().equals(other.getClass())) {
        return getClass().getName().compareTo(other.getClass().getName());
      }

      int lastComparison = 0;

      lastComparison = Boolean.valueOf(isSetSuccess()).compareTo(other.isSetSuccess());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetSuccess()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.success, other.success);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = Boolean.valueOf(isSetIre()).compareTo(other.isSetIre());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetIre()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.ire, other.ire);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = Boolean.valueOf(isSetAce()).compareTo(other.isSetAce());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetAce()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.ace, other.ace);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = Boolean.valueOf(isSetAse()).compareTo(other.isSetAse());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetAse()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.ase, other.ase);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = 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 {
      schemes.get(iprot.getScheme()).getScheme().read(iprot, this);
    }

    public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException {
      schemes.get(oprot.getScheme()).getScheme().write(oprot, this);
      }

    @Override
    public String toString() {
      StringBuilder sb = new StringBuilder("registerApplicationInterface_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("ire:");
      if (this.ire == null) {
        sb.append("null");
      } else {
        sb.append(this.ire);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("ace:");
      if (this.ace == null) {
        sb.append("null");
      } else {
        sb.append(this.ace);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("ase:");
      if (this.ase == null) {
        sb.append("null");
      } else {
        sb.append(this.ase);
      }
      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, 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 registerApplicationInterface_resultStandardSchemeFactory implements SchemeFactory {
      public registerApplicationInterface_resultStandardScheme getScheme() {
        return new registerApplicationInterface_resultStandardScheme();
      }
    }

    private static class registerApplicationInterface_resultStandardScheme extends StandardScheme<registerApplicationInterface_result> {

      public void read(org.apache.thrift.protocol.TProtocol iprot, registerApplicationInterface_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: // IRE
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.ire = new org.apache.airavata.model.error.InvalidRequestException();
                struct.ire.read(iprot);
                struct.setIreIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 2: // ACE
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.ace = new org.apache.airavata.model.error.AiravataClientException();
                struct.ace.read(iprot);
                struct.setAceIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 3: // ASE
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.ase = new org.apache.airavata.model.error.AiravataSystemException();
                struct.ase.read(iprot);
                struct.setAseIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 4: // 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, registerApplicationInterface_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.ire != null) {
          oprot.writeFieldBegin(IRE_FIELD_DESC);
          struct.ire.write(oprot);
          oprot.writeFieldEnd();
        }
        if (struct.ace != null) {
          oprot.writeFieldBegin(ACE_FIELD_DESC);
          struct.ace.write(oprot);
          oprot.writeFieldEnd();
        }
        if (struct.ase != null) {
          oprot.writeFieldBegin(ASE_FIELD_DESC);
          struct.ase.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 registerApplicationInterface_resultTupleSchemeFactory implements SchemeFactory {
      public registerApplicationInterface_resultTupleScheme getScheme() {
        return new registerApplicationInterface_resultTupleScheme();
      }
    }

    private static class registerApplicationInterface_resultTupleScheme extends TupleScheme<registerApplicationInterface_result> {

      @Override
      public void write(org.apache.thrift.protocol.TProtocol prot, registerApplicationInterface_result struct) throws org.apache.thrift.TException {
        TTupleProtocol oprot = (TTupleProtocol) prot;
        BitSet optionals = new BitSet();
        if (struct.isSetSuccess()) {
          optionals.set(0);
        }
        if (struct.isSetIre()) {
          optionals.set(1);
        }
        if (struct.isSetAce()) {
          optionals.set(2);
        }
        if (struct.isSetAse()) {
          optionals.set(3);
        }
        if (struct.isSetAe()) {
          optionals.set(4);
        }
        oprot.writeBitSet(optionals, 5);
        if (struct.isSetSuccess()) {
          oprot.writeString(struct.success);
        }
        if (struct.isSetIre()) {
          struct.ire.write(oprot);
        }
        if (struct.isSetAce()) {
          struct.ace.write(oprot);
        }
        if (struct.isSetAse()) {
          struct.ase.write(oprot);
        }
        if (struct.isSetAe()) {
          struct.ae.write(oprot);
        }
      }

      @Override
      public void read(org.apache.thrift.protocol.TProtocol prot, registerApplicationInterface_result struct) throws org.apache.thrift.TException {
        TTupleProtocol iprot = (TTupleProtocol) prot;
        BitSet incoming = iprot.readBitSet(5);
        if (incoming.get(0)) {
          struct.success = iprot.readString();
          struct.setSuccessIsSet(true);
        }
        if (incoming.get(1)) {
          struct.ire = new org.apache.airavata.model.error.InvalidRequestException();
          struct.ire.read(iprot);
          struct.setIreIsSet(true);
        }
        if (incoming.get(2)) {
          struct.ace = new org.apache.airavata.model.error.AiravataClientException();
          struct.ace.read(iprot);
          struct.setAceIsSet(true);
        }
        if (incoming.get(3)) {
          struct.ase = new org.apache.airavata.model.error.AiravataSystemException();
          struct.ase.read(iprot);
          struct.setAseIsSet(true);
        }
        if (incoming.get(4)) {
          struct.ae = new org.apache.airavata.model.error.AuthorizationException();
          struct.ae.read(iprot);
          struct.setAeIsSet(true);
        }
      }
    }

  }

  public static class getApplicationInterface_args implements org.apache.thrift.TBase<getApplicationInterface_args, getApplicationInterface_args._Fields>, java.io.Serializable, Cloneable, Comparable<getApplicationInterface_args>   {
    private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("getApplicationInterface_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 APP_INTERFACE_ID_FIELD_DESC = new org.apache.thrift.protocol.TField("appInterfaceId", org.apache.thrift.protocol.TType.STRING, (short)2);

    private static final Map<Class<? extends IScheme>, SchemeFactory> schemes = new HashMap<Class<? extends IScheme>, SchemeFactory>();
    static {
      schemes.put(StandardScheme.class, new getApplicationInterface_argsStandardSchemeFactory());
      schemes.put(TupleScheme.class, new getApplicationInterface_argsTupleSchemeFactory());
    }

    public org.apache.airavata.model.security.AuthzToken authzToken; // required
    public String appInterfaceId; // required

    /** 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"),
      APP_INTERFACE_ID((short)2, "appInterfaceId");

      private static final Map<String, _Fields> byName = new HashMap<String, _Fields>();

      static {
        for (_Fields field : EnumSet.allOf(_Fields.class)) {
          byName.put(field.getFieldName(), field);
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, or null if its not found.
       */
      public static _Fields findByThriftId(int fieldId) {
        switch(fieldId) {
          case 1: // AUTHZ_TOKEN
            return AUTHZ_TOKEN;
          case 2: // APP_INTERFACE_ID
            return APP_INTERFACE_ID;
          default:
            return null;
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, throwing an exception
       * if it is not found.
       */
      public static _Fields findByThriftIdOrThrow(int fieldId) {
        _Fields fields = findByThriftId(fieldId);
        if (fields == null) throw new IllegalArgumentException("Field " + fieldId + " doesn't exist!");
        return fields;
      }

      /**
       * Find the _Fields constant that matches name, or null if its not found.
       */
      public static _Fields findByName(String name) {
        return byName.get(name);
      }

      private final short _thriftId;
      private final String _fieldName;

      _Fields(short thriftId, String fieldName) {
        _thriftId = thriftId;
        _fieldName = fieldName;
      }

      public short getThriftFieldId() {
        return _thriftId;
      }

      public String getFieldName() {
        return _fieldName;
      }
    }

    // isset id assignments
    public static final Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
    static {
      Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new EnumMap<_Fields, org.apache.thrift.meta_data.FieldMetaData>(_Fields.class);
      tmpMap.put(_Fields.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.APP_INTERFACE_ID, new org.apache.thrift.meta_data.FieldMetaData("appInterfaceId", org.apache.thrift.TFieldRequirementType.REQUIRED, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING)));
      metaDataMap = Collections.unmodifiableMap(tmpMap);
      org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(getApplicationInterface_args.class, metaDataMap);
    }

    public getApplicationInterface_args() {
    }

    public getApplicationInterface_args(
      org.apache.airavata.model.security.AuthzToken authzToken,
      String appInterfaceId)
    {
      this();
      this.authzToken = authzToken;
      this.appInterfaceId = appInterfaceId;
    }

    /**
     * Performs a deep copy on <i>other</i>.
     */
    public getApplicationInterface_args(getApplicationInterface_args other) {
      if (other.isSetAuthzToken()) {
        this.authzToken = new org.apache.airavata.model.security.AuthzToken(other.authzToken);
      }
      if (other.isSetAppInterfaceId()) {
        this.appInterfaceId = other.appInterfaceId;
      }
    }

    public getApplicationInterface_args deepCopy() {
      return new getApplicationInterface_args(this);
    }

    @Override
    public void clear() {
      this.authzToken = null;
      this.appInterfaceId = null;
    }

    public org.apache.airavata.model.security.AuthzToken getAuthzToken() {
      return this.authzToken;
    }

    public getApplicationInterface_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 String getAppInterfaceId() {
      return this.appInterfaceId;
    }

    public getApplicationInterface_args setAppInterfaceId(String appInterfaceId) {
      this.appInterfaceId = appInterfaceId;
      return this;
    }

    public void unsetAppInterfaceId() {
      this.appInterfaceId = null;
    }

    /** Returns true if field appInterfaceId is set (has been assigned a value) and false otherwise */
    public boolean isSetAppInterfaceId() {
      return this.appInterfaceId != null;
    }

    public void setAppInterfaceIdIsSet(boolean value) {
      if (!value) {
        this.appInterfaceId = null;
      }
    }

    public void setFieldValue(_Fields field, Object value) {
      switch (field) {
      case AUTHZ_TOKEN:
        if (value == null) {
          unsetAuthzToken();
        } else {
          setAuthzToken((org.apache.airavata.model.security.AuthzToken)value);
        }
        break;

      case APP_INTERFACE_ID:
        if (value == null) {
          unsetAppInterfaceId();
        } else {
          setAppInterfaceId((String)value);
        }
        break;

      }
    }

    public Object getFieldValue(_Fields field) {
      switch (field) {
      case AUTHZ_TOKEN:
        return getAuthzToken();

      case APP_INTERFACE_ID:
        return getAppInterfaceId();

      }
      throw new IllegalStateException();
    }

    /** Returns true if field corresponding to fieldID is set (has been assigned a value) and false otherwise */
    public boolean isSet(_Fields field) {
      if (field == null) {
        throw new IllegalArgumentException();
      }

      switch (field) {
      case AUTHZ_TOKEN:
        return isSetAuthzToken();
      case APP_INTERFACE_ID:
        return isSetAppInterfaceId();
      }
      throw new IllegalStateException();
    }

    @Override
    public boolean equals(Object that) {
      if (that == null)
        return false;
      if (that instanceof getApplicationInterface_args)
        return this.equals((getApplicationInterface_args)that);
      return false;
    }

    public boolean equals(getApplicationInterface_args that) {
      if (that == null)
        return false;

      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_appInterfaceId = true && this.isSetAppInterfaceId();
      boolean that_present_appInterfaceId = true && that.isSetAppInterfaceId();
      if (this_present_appInterfaceId || that_present_appInterfaceId) {
        if (!(this_present_appInterfaceId && that_present_appInterfaceId))
          return false;
        if (!this.appInterfaceId.equals(that.appInterfaceId))
          return false;
      }

      return true;
    }

    @Override
    public int hashCode() {
      List<Object> list = new ArrayList<Object>();

      boolean present_authzToken = true && (isSetAuthzToken());
      list.add(present_authzToken);
      if (present_authzToken)
        list.add(authzToken);

      boolean present_appInterfaceId = true && (isSetAppInterfaceId());
      list.add(present_appInterfaceId);
      if (present_appInterfaceId)
        list.add(appInterfaceId);

      return list.hashCode();
    }

    @Override
    public int compareTo(getApplicationInterface_args other) {
      if (!getClass().equals(other.getClass())) {
        return getClass().getName().compareTo(other.getClass().getName());
      }

      int lastComparison = 0;

      lastComparison = 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 = Boolean.valueOf(isSetAppInterfaceId()).compareTo(other.isSetAppInterfaceId());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetAppInterfaceId()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.appInterfaceId, other.appInterfaceId);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      return 0;
    }

    public _Fields fieldForId(int fieldId) {
      return _Fields.findByThriftId(fieldId);
    }

    public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
      schemes.get(iprot.getScheme()).getScheme().read(iprot, this);
    }

    public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException {
      schemes.get(oprot.getScheme()).getScheme().write(oprot, this);
    }

    @Override
    public String toString() {
      StringBuilder sb = new StringBuilder("getApplicationInterface_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("appInterfaceId:");
      if (this.appInterfaceId == null) {
        sb.append("null");
      } else {
        sb.append(this.appInterfaceId);
      }
      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 (appInterfaceId == null) {
        throw new org.apache.thrift.protocol.TProtocolException("Required field 'appInterfaceId' 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, 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 getApplicationInterface_argsStandardSchemeFactory implements SchemeFactory {
      public getApplicationInterface_argsStandardScheme getScheme() {
        return new getApplicationInterface_argsStandardScheme();
      }
    }

    private static class getApplicationInterface_argsStandardScheme extends StandardScheme<getApplicationInterface_args> {

      public void read(org.apache.thrift.protocol.TProtocol iprot, getApplicationInterface_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: // APP_INTERFACE_ID
              if (schemeField.type == org.apache.thrift.protocol.TType.STRING) {
                struct.appInterfaceId = iprot.readString();
                struct.setAppInterfaceIdIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            default:
              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
          }
          iprot.readFieldEnd();
        }
        iprot.readStructEnd();

        // check for required fields of primitive type, which can't be checked in the validate method
        struct.validate();
      }

      public void write(org.apache.thrift.protocol.TProtocol oprot, getApplicationInterface_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.appInterfaceId != null) {
          oprot.writeFieldBegin(APP_INTERFACE_ID_FIELD_DESC);
          oprot.writeString(struct.appInterfaceId);
          oprot.writeFieldEnd();
        }
        oprot.writeFieldStop();
        oprot.writeStructEnd();
      }

    }

    private static class getApplicationInterface_argsTupleSchemeFactory implements SchemeFactory {
      public getApplicationInterface_argsTupleScheme getScheme() {
        return new getApplicationInterface_argsTupleScheme();
      }
    }

    private static class getApplicationInterface_argsTupleScheme extends TupleScheme<getApplicationInterface_args> {

      @Override
      public void write(org.apache.thrift.protocol.TProtocol prot, getApplicationInterface_args struct) throws org.apache.thrift.TException {
        TTupleProtocol oprot = (TTupleProtocol) prot;
        struct.authzToken.write(oprot);
        oprot.writeString(struct.appInterfaceId);
      }

      @Override
      public void read(org.apache.thrift.protocol.TProtocol prot, getApplicationInterface_args struct) throws org.apache.thrift.TException {
        TTupleProtocol iprot = (TTupleProtocol) prot;
        struct.authzToken = new org.apache.airavata.model.security.AuthzToken();
        struct.authzToken.read(iprot);
        struct.setAuthzTokenIsSet(true);
        struct.appInterfaceId = iprot.readString();
        struct.setAppInterfaceIdIsSet(true);
      }
    }

  }

  public static class getApplicationInterface_result implements org.apache.thrift.TBase<getApplicationInterface_result, getApplicationInterface_result._Fields>, java.io.Serializable, Cloneable, Comparable<getApplicationInterface_result>   {
    private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("getApplicationInterface_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 IRE_FIELD_DESC = new org.apache.thrift.protocol.TField("ire", org.apache.thrift.protocol.TType.STRUCT, (short)1);
    private static final org.apache.thrift.protocol.TField ACE_FIELD_DESC = new org.apache.thrift.protocol.TField("ace", org.apache.thrift.protocol.TType.STRUCT, (short)2);
    private static final org.apache.thrift.protocol.TField ASE_FIELD_DESC = new org.apache.thrift.protocol.TField("ase", org.apache.thrift.protocol.TType.STRUCT, (short)3);
    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)4);

    private static final Map<Class<? extends IScheme>, SchemeFactory> schemes = new HashMap<Class<? extends IScheme>, SchemeFactory>();
    static {
      schemes.put(StandardScheme.class, new getApplicationInterface_resultStandardSchemeFactory());
      schemes.put(TupleScheme.class, new getApplicationInterface_resultTupleSchemeFactory());
    }

    public org.apache.airavata.model.appcatalog.appinterface.ApplicationInterfaceDescription success; // required
    public org.apache.airavata.model.error.InvalidRequestException ire; // required
    public org.apache.airavata.model.error.AiravataClientException ace; // required
    public org.apache.airavata.model.error.AiravataSystemException ase; // 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"),
      IRE((short)1, "ire"),
      ACE((short)2, "ace"),
      ASE((short)3, "ase"),
      AE((short)4, "ae");

      private static final Map<String, _Fields> byName = new HashMap<String, _Fields>();

      static {
        for (_Fields field : EnumSet.allOf(_Fields.class)) {
          byName.put(field.getFieldName(), field);
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, or null if its not found.
       */
      public static _Fields findByThriftId(int fieldId) {
        switch(fieldId) {
          case 0: // SUCCESS
            return SUCCESS;
          case 1: // IRE
            return IRE;
          case 2: // ACE
            return ACE;
          case 3: // ASE
            return ASE;
          case 4: // 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 IllegalArgumentException("Field " + fieldId + " doesn't exist!");
        return fields;
      }

      /**
       * Find the _Fields constant that matches name, or null if its not found.
       */
      public static _Fields findByName(String name) {
        return byName.get(name);
      }

      private final short _thriftId;
      private final String _fieldName;

      _Fields(short thriftId, String fieldName) {
        _thriftId = thriftId;
        _fieldName = fieldName;
      }

      public short getThriftFieldId() {
        return _thriftId;
      }

      public String getFieldName() {
        return _fieldName;
      }
    }

    // isset id assignments
    public static final Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
    static {
      Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new EnumMap<_Fields, org.apache.thrift.meta_data.FieldMetaData>(_Fields.class);
      tmpMap.put(_Fields.SUCCESS, new org.apache.thrift.meta_data.FieldMetaData("success", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.StructMetaData(org.apache.thrift.protocol.TType.STRUCT, org.apache.airavata.model.appcatalog.appinterface.ApplicationInterfaceDescription.class)));
      tmpMap.put(_Fields.IRE, new org.apache.thrift.meta_data.FieldMetaData("ire", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRUCT)));
      tmpMap.put(_Fields.ACE, new org.apache.thrift.meta_data.FieldMetaData("ace", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRUCT)));
      tmpMap.put(_Fields.ASE, new org.apache.thrift.meta_data.FieldMetaData("ase", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRUCT)));
      tmpMap.put(_Fields.AE, new org.apache.thrift.meta_data.FieldMetaData("ae", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRUCT)));
      metaDataMap = Collections.unmodifiableMap(tmpMap);
      org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(getApplicationInterface_result.class, metaDataMap);
    }

    public getApplicationInterface_result() {
    }

    public getApplicationInterface_result(
      org.apache.airavata.model.appcatalog.appinterface.ApplicationInterfaceDescription success,
      org.apache.airavata.model.error.InvalidRequestException ire,
      org.apache.airavata.model.error.AiravataClientException ace,
      org.apache.airavata.model.error.AiravataSystemException ase,
      org.apache.airavata.model.error.AuthorizationException ae)
    {
      this();
      this.success = success;
      this.ire = ire;
      this.ace = ace;
      this.ase = ase;
      this.ae = ae;
    }

    /**
     * Performs a deep copy on <i>other</i>.
     */
    public getApplicationInterface_result(getApplicationInterface_result other) {
      if (other.isSetSuccess()) {
        this.success = new org.apache.airavata.model.appcatalog.appinterface.ApplicationInterfaceDescription(other.success);
      }
      if (other.isSetIre()) {
        this.ire = new org.apache.airavata.model.error.InvalidRequestException(other.ire);
      }
      if (other.isSetAce()) {
        this.ace = new org.apache.airavata.model.error.AiravataClientException(other.ace);
      }
      if (other.isSetAse()) {
        this.ase = new org.apache.airavata.model.error.AiravataSystemException(other.ase);
      }
      if (other.isSetAe()) {
        this.ae = new org.apache.airavata.model.error.AuthorizationException(other.ae);
      }
    }

    public getApplicationInterface_result deepCopy() {
      return new getApplicationInterface_result(this);
    }

    @Override
    public void clear() {
      this.success = null;
      this.ire = null;
      this.ace = null;
      this.ase = null;
      this.ae = null;
    }

    public org.apache.airavata.model.appcatalog.appinterface.ApplicationInterfaceDescription getSuccess() {
      return this.success;
    }

    public getApplicationInterface_result setSuccess(org.apache.airavata.model.appcatalog.appinterface.ApplicationInterfaceDescription 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.model.error.InvalidRequestException getIre() {
      return this.ire;
    }

    public getApplicationInterface_result setIre(org.apache.airavata.model.error.InvalidRequestException ire) {
      this.ire = ire;
      return this;
    }

    public void unsetIre() {
      this.ire = null;
    }

    /** Returns true if field ire is set (has been assigned a value) and false otherwise */
    public boolean isSetIre() {
      return this.ire != null;
    }

    public void setIreIsSet(boolean value) {
      if (!value) {
        this.ire = null;
      }
    }

    public org.apache.airavata.model.error.AiravataClientException getAce() {
      return this.ace;
    }

    public getApplicationInterface_result setAce(org.apache.airavata.model.error.AiravataClientException ace) {
      this.ace = ace;
      return this;
    }

    public void unsetAce() {
      this.ace = null;
    }

    /** Returns true if field ace is set (has been assigned a value) and false otherwise */
    public boolean isSetAce() {
      return this.ace != null;
    }

    public void setAceIsSet(boolean value) {
      if (!value) {
        this.ace = null;
      }
    }

    public org.apache.airavata.model.error.AiravataSystemException getAse() {
      return this.ase;
    }

    public getApplicationInterface_result setAse(org.apache.airavata.model.error.AiravataSystemException ase) {
      this.ase = ase;
      return this;
    }

    public void unsetAse() {
      this.ase = null;
    }

    /** Returns true if field ase is set (has been assigned a value) and false otherwise */
    public boolean isSetAse() {
      return this.ase != null;
    }

    public void setAseIsSet(boolean value) {
      if (!value) {
        this.ase = null;
      }
    }

    public org.apache.airavata.model.error.AuthorizationException getAe() {
      return this.ae;
    }

    public getApplicationInterface_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, Object value) {
      switch (field) {
      case SUCCESS:
        if (value == null) {
          unsetSuccess();
        } else {
          setSuccess((org.apache.airavata.model.appcatalog.appinterface.ApplicationInterfaceDescription)value);
        }
        break;

      case IRE:
        if (value == null) {
          unsetIre();
        } else {
          setIre((org.apache.airavata.model.error.InvalidRequestException)value);
        }
        break;

      case ACE:
        if (value == null) {
          unsetAce();
        } else {
          setAce((org.apache.airavata.model.error.AiravataClientException)value);
        }
        break;

      case ASE:
        if (value == null) {
          unsetAse();
        } else {
          setAse((org.apache.airavata.model.error.AiravataSystemException)value);
        }
        break;

      case AE:
        if (value == null) {
          unsetAe();
        } else {
          setAe((org.apache.airavata.model.error.AuthorizationException)value);
        }
        break;

      }
    }

    public Object getFieldValue(_Fields field) {
      switch (field) {
      case SUCCESS:
        return getSuccess();

      case IRE:
        return getIre();

      case ACE:
        return getAce();

      case ASE:
        return getAse();

      case AE:
        return getAe();

      }
      throw new IllegalStateException();
    }

    /** Returns true if field corresponding to fieldID is set (has been assigned a value) and false otherwise */
    public boolean isSet(_Fields field) {
      if (field == null) {
        throw new IllegalArgumentException();
      }

      switch (field) {
      case SUCCESS:
        return isSetSuccess();
      case IRE:
        return isSetIre();
      case ACE:
        return isSetAce();
      case ASE:
        return isSetAse();
      case AE:
        return isSetAe();
      }
      throw new IllegalStateException();
    }

    @Override
    public boolean equals(Object that) {
      if (that == null)
        return false;
      if (that instanceof getApplicationInterface_result)
        return this.equals((getApplicationInterface_result)that);
      return false;
    }

    public boolean equals(getApplicationInterface_result that) {
      if (that == null)
        return false;

      boolean this_present_success = true && this.isSetSuccess();
      boolean that_present_success = true && that.isSetSuccess();
      if (this_present_success || that_present_success) {
        if (!(this_present_success && that_present_success))
          return false;
        if (!this.success.equals(that.success))
          return false;
      }

      boolean this_present_ire = true && this.isSetIre();
      boolean that_present_ire = true && that.isSetIre();
      if (this_present_ire || that_present_ire) {
        if (!(this_present_ire && that_present_ire))
          return false;
        if (!this.ire.equals(that.ire))
          return false;
      }

      boolean this_present_ace = true && this.isSetAce();
      boolean that_present_ace = true && that.isSetAce();
      if (this_present_ace || that_present_ace) {
        if (!(this_present_ace && that_present_ace))
          return false;
        if (!this.ace.equals(that.ace))
          return false;
      }

      boolean this_present_ase = true && this.isSetAse();
      boolean that_present_ase = true && that.isSetAse();
      if (this_present_ase || that_present_ase) {
        if (!(this_present_ase && that_present_ase))
          return false;
        if (!this.ase.equals(that.ase))
          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() {
      List<Object> list = new ArrayList<Object>();

      boolean present_success = true && (isSetSuccess());
      list.add(present_success);
      if (present_success)
        list.add(success);

      boolean present_ire = true && (isSetIre());
      list.add(present_ire);
      if (present_ire)
        list.add(ire);

      boolean present_ace = true && (isSetAce());
      list.add(present_ace);
      if (present_ace)
        list.add(ace);

      boolean present_ase = true && (isSetAse());
      list.add(present_ase);
      if (present_ase)
        list.add(ase);

      boolean present_ae = true && (isSetAe());
      list.add(present_ae);
      if (present_ae)
        list.add(ae);

      return list.hashCode();
    }

    @Override
    public int compareTo(getApplicationInterface_result other) {
      if (!getClass().equals(other.getClass())) {
        return getClass().getName().compareTo(other.getClass().getName());
      }

      int lastComparison = 0;

      lastComparison = Boolean.valueOf(isSetSuccess()).compareTo(other.isSetSuccess());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetSuccess()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.success, other.success);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = Boolean.valueOf(isSetIre()).compareTo(other.isSetIre());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetIre()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.ire, other.ire);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = Boolean.valueOf(isSetAce()).compareTo(other.isSetAce());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetAce()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.ace, other.ace);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = Boolean.valueOf(isSetAse()).compareTo(other.isSetAse());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetAse()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.ase, other.ase);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = 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 {
      schemes.get(iprot.getScheme()).getScheme().read(iprot, this);
    }

    public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException {
      schemes.get(oprot.getScheme()).getScheme().write(oprot, this);
      }

    @Override
    public String toString() {
      StringBuilder sb = new StringBuilder("getApplicationInterface_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("ire:");
      if (this.ire == null) {
        sb.append("null");
      } else {
        sb.append(this.ire);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("ace:");
      if (this.ace == null) {
        sb.append("null");
      } else {
        sb.append(this.ace);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("ase:");
      if (this.ase == null) {
        sb.append("null");
      } else {
        sb.append(this.ase);
      }
      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, 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 getApplicationInterface_resultStandardSchemeFactory implements SchemeFactory {
      public getApplicationInterface_resultStandardScheme getScheme() {
        return new getApplicationInterface_resultStandardScheme();
      }
    }

    private static class getApplicationInterface_resultStandardScheme extends StandardScheme<getApplicationInterface_result> {

      public void read(org.apache.thrift.protocol.TProtocol iprot, getApplicationInterface_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.appcatalog.appinterface.ApplicationInterfaceDescription();
                struct.success.read(iprot);
                struct.setSuccessIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 1: // IRE
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.ire = new org.apache.airavata.model.error.InvalidRequestException();
                struct.ire.read(iprot);
                struct.setIreIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 2: // ACE
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.ace = new org.apache.airavata.model.error.AiravataClientException();
                struct.ace.read(iprot);
                struct.setAceIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 3: // ASE
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.ase = new org.apache.airavata.model.error.AiravataSystemException();
                struct.ase.read(iprot);
                struct.setAseIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 4: // 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, getApplicationInterface_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.ire != null) {
          oprot.writeFieldBegin(IRE_FIELD_DESC);
          struct.ire.write(oprot);
          oprot.writeFieldEnd();
        }
        if (struct.ace != null) {
          oprot.writeFieldBegin(ACE_FIELD_DESC);
          struct.ace.write(oprot);
          oprot.writeFieldEnd();
        }
        if (struct.ase != null) {
          oprot.writeFieldBegin(ASE_FIELD_DESC);
          struct.ase.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 getApplicationInterface_resultTupleSchemeFactory implements SchemeFactory {
      public getApplicationInterface_resultTupleScheme getScheme() {
        return new getApplicationInterface_resultTupleScheme();
      }
    }

    private static class getApplicationInterface_resultTupleScheme extends TupleScheme<getApplicationInterface_result> {

      @Override
      public void write(org.apache.thrift.protocol.TProtocol prot, getApplicationInterface_result struct) throws org.apache.thrift.TException {
        TTupleProtocol oprot = (TTupleProtocol) prot;
        BitSet optionals = new BitSet();
        if (struct.isSetSuccess()) {
          optionals.set(0);
        }
        if (struct.isSetIre()) {
          optionals.set(1);
        }
        if (struct.isSetAce()) {
          optionals.set(2);
        }
        if (struct.isSetAse()) {
          optionals.set(3);
        }
        if (struct.isSetAe()) {
          optionals.set(4);
        }
        oprot.writeBitSet(optionals, 5);
        if (struct.isSetSuccess()) {
          struct.success.write(oprot);
        }
        if (struct.isSetIre()) {
          struct.ire.write(oprot);
        }
        if (struct.isSetAce()) {
          struct.ace.write(oprot);
        }
        if (struct.isSetAse()) {
          struct.ase.write(oprot);
        }
        if (struct.isSetAe()) {
          struct.ae.write(oprot);
        }
      }

      @Override
      public void read(org.apache.thrift.protocol.TProtocol prot, getApplicationInterface_result struct) throws org.apache.thrift.TException {
        TTupleProtocol iprot = (TTupleProtocol) prot;
        BitSet incoming = iprot.readBitSet(5);
        if (incoming.get(0)) {
          struct.success = new org.apache.airavata.model.appcatalog.appinterface.ApplicationInterfaceDescription();
          struct.success.read(iprot);
          struct.setSuccessIsSet(true);
        }
        if (incoming.get(1)) {
          struct.ire = new org.apache.airavata.model.error.InvalidRequestException();
          struct.ire.read(iprot);
          struct.setIreIsSet(true);
        }
        if (incoming.get(2)) {
          struct.ace = new org.apache.airavata.model.error.AiravataClientException();
          struct.ace.read(iprot);
          struct.setAceIsSet(true);
        }
        if (incoming.get(3)) {
          struct.ase = new org.apache.airavata.model.error.AiravataSystemException();
          struct.ase.read(iprot);
          struct.setAseIsSet(true);
        }
        if (incoming.get(4)) {
          struct.ae = new org.apache.airavata.model.error.AuthorizationException();
          struct.ae.read(iprot);
          struct.setAeIsSet(true);
        }
      }
    }

  }

  public static class updateApplicationInterface_args implements org.apache.thrift.TBase<updateApplicationInterface_args, updateApplicationInterface_args._Fields>, java.io.Serializable, Cloneable, Comparable<updateApplicationInterface_args>   {
    private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("updateApplicationInterface_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 APP_INTERFACE_ID_FIELD_DESC = new org.apache.thrift.protocol.TField("appInterfaceId", org.apache.thrift.protocol.TType.STRING, (short)2);
    private static final org.apache.thrift.protocol.TField APPLICATION_INTERFACE_FIELD_DESC = new org.apache.thrift.protocol.TField("applicationInterface", org.apache.thrift.protocol.TType.STRUCT, (short)3);

    private static final Map<Class<? extends IScheme>, SchemeFactory> schemes = new HashMap<Class<? extends IScheme>, SchemeFactory>();
    static {
      schemes.put(StandardScheme.class, new updateApplicationInterface_argsStandardSchemeFactory());
      schemes.put(TupleScheme.class, new updateApplicationInterface_argsTupleSchemeFactory());
    }

    public org.apache.airavata.model.security.AuthzToken authzToken; // required
    public String appInterfaceId; // required
    public org.apache.airavata.model.appcatalog.appinterface.ApplicationInterfaceDescription applicationInterface; // required

    /** 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"),
      APP_INTERFACE_ID((short)2, "appInterfaceId"),
      APPLICATION_INTERFACE((short)3, "applicationInterface");

      private static final Map<String, _Fields> byName = new HashMap<String, _Fields>();

      static {
        for (_Fields field : EnumSet.allOf(_Fields.class)) {
          byName.put(field.getFieldName(), field);
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, or null if its not found.
       */
      public static _Fields findByThriftId(int fieldId) {
        switch(fieldId) {
          case 1: // AUTHZ_TOKEN
            return AUTHZ_TOKEN;
          case 2: // APP_INTERFACE_ID
            return APP_INTERFACE_ID;
          case 3: // APPLICATION_INTERFACE
            return APPLICATION_INTERFACE;
          default:
            return null;
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, throwing an exception
       * if it is not found.
       */
      public static _Fields findByThriftIdOrThrow(int fieldId) {
        _Fields fields = findByThriftId(fieldId);
        if (fields == null) throw new IllegalArgumentException("Field " + fieldId + " doesn't exist!");
        return fields;
      }

      /**
       * Find the _Fields constant that matches name, or null if its not found.
       */
      public static _Fields findByName(String name) {
        return byName.get(name);
      }

      private final short _thriftId;
      private final String _fieldName;

      _Fields(short thriftId, String fieldName) {
        _thriftId = thriftId;
        _fieldName = fieldName;
      }

      public short getThriftFieldId() {
        return _thriftId;
      }

      public String getFieldName() {
        return _fieldName;
      }
    }

    // isset id assignments
    public static final Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
    static {
      Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new EnumMap<_Fields, org.apache.thrift.meta_data.FieldMetaData>(_Fields.class);
      tmpMap.put(_Fields.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.APP_INTERFACE_ID, new org.apache.thrift.meta_data.FieldMetaData("appInterfaceId", org.apache.thrift.TFieldRequirementType.REQUIRED, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING)));
      tmpMap.put(_Fields.APPLICATION_INTERFACE, new org.apache.thrift.meta_data.FieldMetaData("applicationInterface", org.apache.thrift.TFieldRequirementType.REQUIRED, 
          new org.apache.thrift.meta_data.StructMetaData(org.apache.thrift.protocol.TType.STRUCT, org.apache.airavata.model.appcatalog.appinterface.ApplicationInterfaceDescription.class)));
      metaDataMap = Collections.unmodifiableMap(tmpMap);
      org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(updateApplicationInterface_args.class, metaDataMap);
    }

    public updateApplicationInterface_args() {
    }

    public updateApplicationInterface_args(
      org.apache.airavata.model.security.AuthzToken authzToken,
      String appInterfaceId,
      org.apache.airavata.model.appcatalog.appinterface.ApplicationInterfaceDescription applicationInterface)
    {
      this();
      this.authzToken = authzToken;
      this.appInterfaceId = appInterfaceId;
      this.applicationInterface = applicationInterface;
    }

    /**
     * Performs a deep copy on <i>other</i>.
     */
    public updateApplicationInterface_args(updateApplicationInterface_args other) {
      if (other.isSetAuthzToken()) {
        this.authzToken = new org.apache.airavata.model.security.AuthzToken(other.authzToken);
      }
      if (other.isSetAppInterfaceId()) {
        this.appInterfaceId = other.appInterfaceId;
      }
      if (other.isSetApplicationInterface()) {
        this.applicationInterface = new org.apache.airavata.model.appcatalog.appinterface.ApplicationInterfaceDescription(other.applicationInterface);
      }
    }

    public updateApplicationInterface_args deepCopy() {
      return new updateApplicationInterface_args(this);
    }

    @Override
    public void clear() {
      this.authzToken = null;
      this.appInterfaceId = null;
      this.applicationInterface = null;
    }

    public org.apache.airavata.model.security.AuthzToken getAuthzToken() {
      return this.authzToken;
    }

    public updateApplicationInterface_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 String getAppInterfaceId() {
      return this.appInterfaceId;
    }

    public updateApplicationInterface_args setAppInterfaceId(String appInterfaceId) {
      this.appInterfaceId = appInterfaceId;
      return this;
    }

    public void unsetAppInterfaceId() {
      this.appInterfaceId = null;
    }

    /** Returns true if field appInterfaceId is set (has been assigned a value) and false otherwise */
    public boolean isSetAppInterfaceId() {
      return this.appInterfaceId != null;
    }

    public void setAppInterfaceIdIsSet(boolean value) {
      if (!value) {
        this.appInterfaceId = null;
      }
    }

    public org.apache.airavata.model.appcatalog.appinterface.ApplicationInterfaceDescription getApplicationInterface() {
      return this.applicationInterface;
    }

    public updateApplicationInterface_args setApplicationInterface(org.apache.airavata.model.appcatalog.appinterface.ApplicationInterfaceDescription applicationInterface) {
      this.applicationInterface = applicationInterface;
      return this;
    }

    public void unsetApplicationInterface() {
      this.applicationInterface = null;
    }

    /** Returns true if field applicationInterface is set (has been assigned a value) and false otherwise */
    public boolean isSetApplicationInterface() {
      return this.applicationInterface != null;
    }

    public void setApplicationInterfaceIsSet(boolean value) {
      if (!value) {
        this.applicationInterface = null;
      }
    }

    public void setFieldValue(_Fields field, Object value) {
      switch (field) {
      case AUTHZ_TOKEN:
        if (value == null) {
          unsetAuthzToken();
        } else {
          setAuthzToken((org.apache.airavata.model.security.AuthzToken)value);
        }
        break;

      case APP_INTERFACE_ID:
        if (value == null) {
          unsetAppInterfaceId();
        } else {
          setAppInterfaceId((String)value);
        }
        break;

      case APPLICATION_INTERFACE:
        if (value == null) {
          unsetApplicationInterface();
        } else {
          setApplicationInterface((org.apache.airavata.model.appcatalog.appinterface.ApplicationInterfaceDescription)value);
        }
        break;

      }
    }

    public Object getFieldValue(_Fields field) {
      switch (field) {
      case AUTHZ_TOKEN:
        return getAuthzToken();

      case APP_INTERFACE_ID:
        return getAppInterfaceId();

      case APPLICATION_INTERFACE:
        return getApplicationInterface();

      }
      throw new IllegalStateException();
    }

    /** Returns true if field corresponding to fieldID is set (has been assigned a value) and false otherwise */
    public boolean isSet(_Fields field) {
      if (field == null) {
        throw new IllegalArgumentException();
      }

      switch (field) {
      case AUTHZ_TOKEN:
        return isSetAuthzToken();
      case APP_INTERFACE_ID:
        return isSetAppInterfaceId();
      case APPLICATION_INTERFACE:
        return isSetApplicationInterface();
      }
      throw new IllegalStateException();
    }

    @Override
    public boolean equals(Object that) {
      if (that == null)
        return false;
      if (that instanceof updateApplicationInterface_args)
        return this.equals((updateApplicationInterface_args)that);
      return false;
    }

    public boolean equals(updateApplicationInterface_args that) {
      if (that == null)
        return false;

      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_appInterfaceId = true && this.isSetAppInterfaceId();
      boolean that_present_appInterfaceId = true && that.isSetAppInterfaceId();
      if (this_present_appInterfaceId || that_present_appInterfaceId) {
        if (!(this_present_appInterfaceId && that_present_appInterfaceId))
          return false;
        if (!this.appInterfaceId.equals(that.appInterfaceId))
          return false;
      }

      boolean this_present_applicationInterface = true && this.isSetApplicationInterface();
      boolean that_present_applicationInterface = true && that.isSetApplicationInterface();
      if (this_present_applicationInterface || that_present_applicationInterface) {
        if (!(this_present_applicationInterface && that_present_applicationInterface))
          return false;
        if (!this.applicationInterface.equals(that.applicationInterface))
          return false;
      }

      return true;
    }

    @Override
    public int hashCode() {
      List<Object> list = new ArrayList<Object>();

      boolean present_authzToken = true && (isSetAuthzToken());
      list.add(present_authzToken);
      if (present_authzToken)
        list.add(authzToken);

      boolean present_appInterfaceId = true && (isSetAppInterfaceId());
      list.add(present_appInterfaceId);
      if (present_appInterfaceId)
        list.add(appInterfaceId);

      boolean present_applicationInterface = true && (isSetApplicationInterface());
      list.add(present_applicationInterface);
      if (present_applicationInterface)
        list.add(applicationInterface);

      return list.hashCode();
    }

    @Override
    public int compareTo(updateApplicationInterface_args other) {
      if (!getClass().equals(other.getClass())) {
        return getClass().getName().compareTo(other.getClass().getName());
      }

      int lastComparison = 0;

      lastComparison = 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 = Boolean.valueOf(isSetAppInterfaceId()).compareTo(other.isSetAppInterfaceId());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetAppInterfaceId()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.appInterfaceId, other.appInterfaceId);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = Boolean.valueOf(isSetApplicationInterface()).compareTo(other.isSetApplicationInterface());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetApplicationInterface()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.applicationInterface, other.applicationInterface);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      return 0;
    }

    public _Fields fieldForId(int fieldId) {
      return _Fields.findByThriftId(fieldId);
    }

    public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
      schemes.get(iprot.getScheme()).getScheme().read(iprot, this);
    }

    public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException {
      schemes.get(oprot.getScheme()).getScheme().write(oprot, this);
    }

    @Override
    public String toString() {
      StringBuilder sb = new StringBuilder("updateApplicationInterface_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("appInterfaceId:");
      if (this.appInterfaceId == null) {
        sb.append("null");
      } else {
        sb.append(this.appInterfaceId);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("applicationInterface:");
      if (this.applicationInterface == null) {
        sb.append("null");
      } else {
        sb.append(this.applicationInterface);
      }
      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 (appInterfaceId == null) {
        throw new org.apache.thrift.protocol.TProtocolException("Required field 'appInterfaceId' was not present! Struct: " + toString());
      }
      if (applicationInterface == null) {
        throw new org.apache.thrift.protocol.TProtocolException("Required field 'applicationInterface' was not present! Struct: " + toString());
      }
      // check for sub-struct validity
      if (authzToken != null) {
        authzToken.validate();
      }
      if (applicationInterface != null) {
        applicationInterface.validate();
      }
    }

    private void writeObject(java.io.ObjectOutputStream out) throws java.io.IOException {
      try {
        write(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(out)));
      } catch (org.apache.thrift.TException te) {
        throw new java.io.IOException(te);
      }
    }

    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, ClassNotFoundException {
      try {
        read(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(in)));
      } catch (org.apache.thrift.TException te) {
        throw new java.io.IOException(te);
      }
    }

    private static class updateApplicationInterface_argsStandardSchemeFactory implements SchemeFactory {
      public updateApplicationInterface_argsStandardScheme getScheme() {
        return new updateApplicationInterface_argsStandardScheme();
      }
    }

    private static class updateApplicationInterface_argsStandardScheme extends StandardScheme<updateApplicationInterface_args> {

      public void read(org.apache.thrift.protocol.TProtocol iprot, updateApplicationInterface_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: // APP_INTERFACE_ID
              if (schemeField.type == org.apache.thrift.protocol.TType.STRING) {
                struct.appInterfaceId = iprot.readString();
                struct.setAppInterfaceIdIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 3: // APPLICATION_INTERFACE
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.applicationInterface = new org.apache.airavata.model.appcatalog.appinterface.ApplicationInterfaceDescription();
                struct.applicationInterface.read(iprot);
                struct.setApplicationInterfaceIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            default:
              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
          }
          iprot.readFieldEnd();
        }
        iprot.readStructEnd();

        // check for required fields of primitive type, which can't be checked in the validate method
        struct.validate();
      }

      public void write(org.apache.thrift.protocol.TProtocol oprot, updateApplicationInterface_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.appInterfaceId != null) {
          oprot.writeFieldBegin(APP_INTERFACE_ID_FIELD_DESC);
          oprot.writeString(struct.appInterfaceId);
          oprot.writeFieldEnd();
        }
        if (struct.applicationInterface != null) {
          oprot.writeFieldBegin(APPLICATION_INTERFACE_FIELD_DESC);
          struct.applicationInterface.write(oprot);
          oprot.writeFieldEnd();
        }
        oprot.writeFieldStop();
        oprot.writeStructEnd();
      }

    }

    private static class updateApplicationInterface_argsTupleSchemeFactory implements SchemeFactory {
      public updateApplicationInterface_argsTupleScheme getScheme() {
        return new updateApplicationInterface_argsTupleScheme();
      }
    }

    private static class updateApplicationInterface_argsTupleScheme extends TupleScheme<updateApplicationInterface_args> {

      @Override
      public void write(org.apache.thrift.protocol.TProtocol prot, updateApplicationInterface_args struct) throws org.apache.thrift.TException {
        TTupleProtocol oprot = (TTupleProtocol) prot;
        struct.authzToken.write(oprot);
        oprot.writeString(struct.appInterfaceId);
        struct.applicationInterface.write(oprot);
      }

      @Override
      public void read(org.apache.thrift.protocol.TProtocol prot, updateApplicationInterface_args struct) throws org.apache.thrift.TException {
        TTupleProtocol iprot = (TTupleProtocol) prot;
        struct.authzToken = new org.apache.airavata.model.security.AuthzToken();
        struct.authzToken.read(iprot);
        struct.setAuthzTokenIsSet(true);
        struct.appInterfaceId = iprot.readString();
        struct.setAppInterfaceIdIsSet(true);
        struct.applicationInterface = new org.apache.airavata.model.appcatalog.appinterface.ApplicationInterfaceDescription();
        struct.applicationInterface.read(iprot);
        struct.setApplicationInterfaceIsSet(true);
      }
    }

  }

  public static class updateApplicationInterface_result implements org.apache.thrift.TBase<updateApplicationInterface_result, updateApplicationInterface_result._Fields>, java.io.Serializable, Cloneable, Comparable<updateApplicationInterface_result>   {
    private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("updateApplicationInterface_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 IRE_FIELD_DESC = new org.apache.thrift.protocol.TField("ire", org.apache.thrift.protocol.TType.STRUCT, (short)1);
    private static final org.apache.thrift.protocol.TField ACE_FIELD_DESC = new org.apache.thrift.protocol.TField("ace", org.apache.thrift.protocol.TType.STRUCT, (short)2);
    private static final org.apache.thrift.protocol.TField ASE_FIELD_DESC = new org.apache.thrift.protocol.TField("ase", org.apache.thrift.protocol.TType.STRUCT, (short)3);
    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)4);

    private static final Map<Class<? extends IScheme>, SchemeFactory> schemes = new HashMap<Class<? extends IScheme>, SchemeFactory>();
    static {
      schemes.put(StandardScheme.class, new updateApplicationInterface_resultStandardSchemeFactory());
      schemes.put(TupleScheme.class, new updateApplicationInterface_resultTupleSchemeFactory());
    }

    public boolean success; // required
    public org.apache.airavata.model.error.InvalidRequestException ire; // required
    public org.apache.airavata.model.error.AiravataClientException ace; // required
    public org.apache.airavata.model.error.AiravataSystemException ase; // 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"),
      IRE((short)1, "ire"),
      ACE((short)2, "ace"),
      ASE((short)3, "ase"),
      AE((short)4, "ae");

      private static final Map<String, _Fields> byName = new HashMap<String, _Fields>();

      static {
        for (_Fields field : EnumSet.allOf(_Fields.class)) {
          byName.put(field.getFieldName(), field);
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, or null if its not found.
       */
      public static _Fields findByThriftId(int fieldId) {
        switch(fieldId) {
          case 0: // SUCCESS
            return SUCCESS;
          case 1: // IRE
            return IRE;
          case 2: // ACE
            return ACE;
          case 3: // ASE
            return ASE;
          case 4: // 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 IllegalArgumentException("Field " + fieldId + " doesn't exist!");
        return fields;
      }

      /**
       * Find the _Fields constant that matches name, or null if its not found.
       */
      public static _Fields findByName(String name) {
        return byName.get(name);
      }

      private final short _thriftId;
      private final String _fieldName;

      _Fields(short thriftId, String fieldName) {
        _thriftId = thriftId;
        _fieldName = fieldName;
      }

      public short getThriftFieldId() {
        return _thriftId;
      }

      public String getFieldName() {
        return _fieldName;
      }
    }

    // isset id assignments
    private static final int __SUCCESS_ISSET_ID = 0;
    private byte __isset_bitfield = 0;
    public static final Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
    static {
      Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new EnumMap<_Fields, org.apache.thrift.meta_data.FieldMetaData>(_Fields.class);
      tmpMap.put(_Fields.SUCCESS, new org.apache.thrift.meta_data.FieldMetaData("success", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.BOOL)));
      tmpMap.put(_Fields.IRE, new org.apache.thrift.meta_data.FieldMetaData("ire", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRUCT)));
      tmpMap.put(_Fields.ACE, new org.apache.thrift.meta_data.FieldMetaData("ace", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRUCT)));
      tmpMap.put(_Fields.ASE, new org.apache.thrift.meta_data.FieldMetaData("ase", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRUCT)));
      tmpMap.put(_Fields.AE, new org.apache.thrift.meta_data.FieldMetaData("ae", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRUCT)));
      metaDataMap = Collections.unmodifiableMap(tmpMap);
      org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(updateApplicationInterface_result.class, metaDataMap);
    }

    public updateApplicationInterface_result() {
    }

    public updateApplicationInterface_result(
      boolean success,
      org.apache.airavata.model.error.InvalidRequestException ire,
      org.apache.airavata.model.error.AiravataClientException ace,
      org.apache.airavata.model.error.AiravataSystemException ase,
      org.apache.airavata.model.error.AuthorizationException ae)
    {
      this();
      this.success = success;
      setSuccessIsSet(true);
      this.ire = ire;
      this.ace = ace;
      this.ase = ase;
      this.ae = ae;
    }

    /**
     * Performs a deep copy on <i>other</i>.
     */
    public updateApplicationInterface_result(updateApplicationInterface_result other) {
      __isset_bitfield = other.__isset_bitfield;
      this.success = other.success;
      if (other.isSetIre()) {
        this.ire = new org.apache.airavata.model.error.InvalidRequestException(other.ire);
      }
      if (other.isSetAce()) {
        this.ace = new org.apache.airavata.model.error.AiravataClientException(other.ace);
      }
      if (other.isSetAse()) {
        this.ase = new org.apache.airavata.model.error.AiravataSystemException(other.ase);
      }
      if (other.isSetAe()) {
        this.ae = new org.apache.airavata.model.error.AuthorizationException(other.ae);
      }
    }

    public updateApplicationInterface_result deepCopy() {
      return new updateApplicationInterface_result(this);
    }

    @Override
    public void clear() {
      setSuccessIsSet(false);
      this.success = false;
      this.ire = null;
      this.ace = null;
      this.ase = null;
      this.ae = null;
    }

    public boolean isSuccess() {
      return this.success;
    }

    public updateApplicationInterface_result setSuccess(boolean success) {
      this.success = success;
      setSuccessIsSet(true);
      return this;
    }

    public void unsetSuccess() {
      __isset_bitfield = EncodingUtils.clearBit(__isset_bitfield, __SUCCESS_ISSET_ID);
    }

    /** Returns true if field success is set (has been assigned a value) and false otherwise */
    public boolean isSetSuccess() {
      return EncodingUtils.testBit(__isset_bitfield, __SUCCESS_ISSET_ID);
    }

    public void setSuccessIsSet(boolean value) {
      __isset_bitfield = EncodingUtils.setBit(__isset_bitfield, __SUCCESS_ISSET_ID, value);
    }

    public org.apache.airavata.model.error.InvalidRequestException getIre() {
      return this.ire;
    }

    public updateApplicationInterface_result setIre(org.apache.airavata.model.error.InvalidRequestException ire) {
      this.ire = ire;
      return this;
    }

    public void unsetIre() {
      this.ire = null;
    }

    /** Returns true if field ire is set (has been assigned a value) and false otherwise */
    public boolean isSetIre() {
      return this.ire != null;
    }

    public void setIreIsSet(boolean value) {
      if (!value) {
        this.ire = null;
      }
    }

    public org.apache.airavata.model.error.AiravataClientException getAce() {
      return this.ace;
    }

    public updateApplicationInterface_result setAce(org.apache.airavata.model.error.AiravataClientException ace) {
      this.ace = ace;
      return this;
    }

    public void unsetAce() {
      this.ace = null;
    }

    /** Returns true if field ace is set (has been assigned a value) and false otherwise */
    public boolean isSetAce() {
      return this.ace != null;
    }

    public void setAceIsSet(boolean value) {
      if (!value) {
        this.ace = null;
      }
    }

    public org.apache.airavata.model.error.AiravataSystemException getAse() {
      return this.ase;
    }

    public updateApplicationInterface_result setAse(org.apache.airavata.model.error.AiravataSystemException ase) {
      this.ase = ase;
      return this;
    }

    public void unsetAse() {
      this.ase = null;
    }

    /** Returns true if field ase is set (has been assigned a value) and false otherwise */
    public boolean isSetAse() {
      return this.ase != null;
    }

    public void setAseIsSet(boolean value) {
      if (!value) {
        this.ase = null;
      }
    }

    public org.apache.airavata.model.error.AuthorizationException getAe() {
      return this.ae;
    }

    public updateApplicationInterface_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, Object value) {
      switch (field) {
      case SUCCESS:
        if (value == null) {
          unsetSuccess();
        } else {
          setSuccess((Boolean)value);
        }
        break;

      case IRE:
        if (value == null) {
          unsetIre();
        } else {
          setIre((org.apache.airavata.model.error.InvalidRequestException)value);
        }
        break;

      case ACE:
        if (value == null) {
          unsetAce();
        } else {
          setAce((org.apache.airavata.model.error.AiravataClientException)value);
        }
        break;

      case ASE:
        if (value == null) {
          unsetAse();
        } else {
          setAse((org.apache.airavata.model.error.AiravataSystemException)value);
        }
        break;

      case AE:
        if (value == null) {
          unsetAe();
        } else {
          setAe((org.apache.airavata.model.error.AuthorizationException)value);
        }
        break;

      }
    }

    public Object getFieldValue(_Fields field) {
      switch (field) {
      case SUCCESS:
        return Boolean.valueOf(isSuccess());

      case IRE:
        return getIre();

      case ACE:
        return getAce();

      case ASE:
        return getAse();

      case AE:
        return getAe();

      }
      throw new IllegalStateException();
    }

    /** Returns true if field corresponding to fieldID is set (has been assigned a value) and false otherwise */
    public boolean isSet(_Fields field) {
      if (field == null) {
        throw new IllegalArgumentException();
      }

      switch (field) {
      case SUCCESS:
        return isSetSuccess();
      case IRE:
        return isSetIre();
      case ACE:
        return isSetAce();
      case ASE:
        return isSetAse();
      case AE:
        return isSetAe();
      }
      throw new IllegalStateException();
    }

    @Override
    public boolean equals(Object that) {
      if (that == null)
        return false;
      if (that instanceof updateApplicationInterface_result)
        return this.equals((updateApplicationInterface_result)that);
      return false;
    }

    public boolean equals(updateApplicationInterface_result that) {
      if (that == null)
        return false;

      boolean this_present_success = true;
      boolean that_present_success = true;
      if (this_present_success || that_present_success) {
        if (!(this_present_success && that_present_success))
          return false;
        if (this.success != that.success)
          return false;
      }

      boolean this_present_ire = true && this.isSetIre();
      boolean that_present_ire = true && that.isSetIre();
      if (this_present_ire || that_present_ire) {
        if (!(this_present_ire && that_present_ire))
          return false;
        if (!this.ire.equals(that.ire))
          return false;
      }

      boolean this_present_ace = true && this.isSetAce();
      boolean that_present_ace = true && that.isSetAce();
      if (this_present_ace || that_present_ace) {
        if (!(this_present_ace && that_present_ace))
          return false;
        if (!this.ace.equals(that.ace))
          return false;
      }

      boolean this_present_ase = true && this.isSetAse();
      boolean that_present_ase = true && that.isSetAse();
      if (this_present_ase || that_present_ase) {
        if (!(this_present_ase && that_present_ase))
          return false;
        if (!this.ase.equals(that.ase))
          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() {
      List<Object> list = new ArrayList<Object>();

      boolean present_success = true;
      list.add(present_success);
      if (present_success)
        list.add(success);

      boolean present_ire = true && (isSetIre());
      list.add(present_ire);
      if (present_ire)
        list.add(ire);

      boolean present_ace = true && (isSetAce());
      list.add(present_ace);
      if (present_ace)
        list.add(ace);

      boolean present_ase = true && (isSetAse());
      list.add(present_ase);
      if (present_ase)
        list.add(ase);

      boolean present_ae = true && (isSetAe());
      list.add(present_ae);
      if (present_ae)
        list.add(ae);

      return list.hashCode();
    }

    @Override
    public int compareTo(updateApplicationInterface_result other) {
      if (!getClass().equals(other.getClass())) {
        return getClass().getName().compareTo(other.getClass().getName());
      }

      int lastComparison = 0;

      lastComparison = Boolean.valueOf(isSetSuccess()).compareTo(other.isSetSuccess());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetSuccess()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.success, other.success);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = Boolean.valueOf(isSetIre()).compareTo(other.isSetIre());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetIre()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.ire, other.ire);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = Boolean.valueOf(isSetAce()).compareTo(other.isSetAce());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetAce()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.ace, other.ace);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = Boolean.valueOf(isSetAse()).compareTo(other.isSetAse());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetAse()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.ase, other.ase);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = 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 {
      schemes.get(iprot.getScheme()).getScheme().read(iprot, this);
    }

    public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException {
      schemes.get(oprot.getScheme()).getScheme().write(oprot, this);
      }

    @Override
    public String toString() {
      StringBuilder sb = new StringBuilder("updateApplicationInterface_result(");
      boolean first = true;

      sb.append("success:");
      sb.append(this.success);
      first = false;
      if (!first) sb.append(", ");
      sb.append("ire:");
      if (this.ire == null) {
        sb.append("null");
      } else {
        sb.append(this.ire);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("ace:");
      if (this.ace == null) {
        sb.append("null");
      } else {
        sb.append(this.ace);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("ase:");
      if (this.ase == null) {
        sb.append("null");
      } else {
        sb.append(this.ase);
      }
      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, 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 updateApplicationInterface_resultStandardSchemeFactory implements SchemeFactory {
      public updateApplicationInterface_resultStandardScheme getScheme() {
        return new updateApplicationInterface_resultStandardScheme();
      }
    }

    private static class updateApplicationInterface_resultStandardScheme extends StandardScheme<updateApplicationInterface_result> {

      public void read(org.apache.thrift.protocol.TProtocol iprot, updateApplicationInterface_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: // IRE
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.ire = new org.apache.airavata.model.error.InvalidRequestException();
                struct.ire.read(iprot);
                struct.setIreIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 2: // ACE
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.ace = new org.apache.airavata.model.error.AiravataClientException();
                struct.ace.read(iprot);
                struct.setAceIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 3: // ASE
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.ase = new org.apache.airavata.model.error.AiravataSystemException();
                struct.ase.read(iprot);
                struct.setAseIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 4: // 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, updateApplicationInterface_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.ire != null) {
          oprot.writeFieldBegin(IRE_FIELD_DESC);
          struct.ire.write(oprot);
          oprot.writeFieldEnd();
        }
        if (struct.ace != null) {
          oprot.writeFieldBegin(ACE_FIELD_DESC);
          struct.ace.write(oprot);
          oprot.writeFieldEnd();
        }
        if (struct.ase != null) {
          oprot.writeFieldBegin(ASE_FIELD_DESC);
          struct.ase.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 updateApplicationInterface_resultTupleSchemeFactory implements SchemeFactory {
      public updateApplicationInterface_resultTupleScheme getScheme() {
        return new updateApplicationInterface_resultTupleScheme();
      }
    }

    private static class updateApplicationInterface_resultTupleScheme extends TupleScheme<updateApplicationInterface_result> {

      @Override
      public void write(org.apache.thrift.protocol.TProtocol prot, updateApplicationInterface_result struct) throws org.apache.thrift.TException {
        TTupleProtocol oprot = (TTupleProtocol) prot;
        BitSet optionals = new BitSet();
        if (struct.isSetSuccess()) {
          optionals.set(0);
        }
        if (struct.isSetIre()) {
          optionals.set(1);
        }
        if (struct.isSetAce()) {
          optionals.set(2);
        }
        if (struct.isSetAse()) {
          optionals.set(3);
        }
        if (struct.isSetAe()) {
          optionals.set(4);
        }
        oprot.writeBitSet(optionals, 5);
        if (struct.isSetSuccess()) {
          oprot.writeBool(struct.success);
        }
        if (struct.isSetIre()) {
          struct.ire.write(oprot);
        }
        if (struct.isSetAce()) {
          struct.ace.write(oprot);
        }
        if (struct.isSetAse()) {
          struct.ase.write(oprot);
        }
        if (struct.isSetAe()) {
          struct.ae.write(oprot);
        }
      }

      @Override
      public void read(org.apache.thrift.protocol.TProtocol prot, updateApplicationInterface_result struct) throws org.apache.thrift.TException {
        TTupleProtocol iprot = (TTupleProtocol) prot;
        BitSet incoming = iprot.readBitSet(5);
        if (incoming.get(0)) {
          struct.success = iprot.readBool();
          struct.setSuccessIsSet(true);
        }
        if (incoming.get(1)) {
          struct.ire = new org.apache.airavata.model.error.InvalidRequestException();
          struct.ire.read(iprot);
          struct.setIreIsSet(true);
        }
        if (incoming.get(2)) {
          struct.ace = new org.apache.airavata.model.error.AiravataClientException();
          struct.ace.read(iprot);
          struct.setAceIsSet(true);
        }
        if (incoming.get(3)) {
          struct.ase = new org.apache.airavata.model.error.AiravataSystemException();
          struct.ase.read(iprot);
          struct.setAseIsSet(true);
        }
        if (incoming.get(4)) {
          struct.ae = new org.apache.airavata.model.error.AuthorizationException();
          struct.ae.read(iprot);
          struct.setAeIsSet(true);
        }
      }
    }

  }

  public static class deleteApplicationInterface_args implements org.apache.thrift.TBase<deleteApplicationInterface_args, deleteApplicationInterface_args._Fields>, java.io.Serializable, Cloneable, Comparable<deleteApplicationInterface_args>   {
    private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("deleteApplicationInterface_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 APP_INTERFACE_ID_FIELD_DESC = new org.apache.thrift.protocol.TField("appInterfaceId", org.apache.thrift.protocol.TType.STRING, (short)2);

    private static final Map<Class<? extends IScheme>, SchemeFactory> schemes = new HashMap<Class<? extends IScheme>, SchemeFactory>();
    static {
      schemes.put(StandardScheme.class, new deleteApplicationInterface_argsStandardSchemeFactory());
      schemes.put(TupleScheme.class, new deleteApplicationInterface_argsTupleSchemeFactory());
    }

    public org.apache.airavata.model.security.AuthzToken authzToken; // required
    public String appInterfaceId; // required

    /** 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"),
      APP_INTERFACE_ID((short)2, "appInterfaceId");

      private static final Map<String, _Fields> byName = new HashMap<String, _Fields>();

      static {
        for (_Fields field : EnumSet.allOf(_Fields.class)) {
          byName.put(field.getFieldName(), field);
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, or null if its not found.
       */
      public static _Fields findByThriftId(int fieldId) {
        switch(fieldId) {
          case 1: // AUTHZ_TOKEN
            return AUTHZ_TOKEN;
          case 2: // APP_INTERFACE_ID
            return APP_INTERFACE_ID;
          default:
            return null;
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, throwing an exception
       * if it is not found.
       */
      public static _Fields findByThriftIdOrThrow(int fieldId) {
        _Fields fields = findByThriftId(fieldId);
        if (fields == null) throw new IllegalArgumentException("Field " + fieldId + " doesn't exist!");
        return fields;
      }

      /**
       * Find the _Fields constant that matches name, or null if its not found.
       */
      public static _Fields findByName(String name) {
        return byName.get(name);
      }

      private final short _thriftId;
      private final String _fieldName;

      _Fields(short thriftId, String fieldName) {
        _thriftId = thriftId;
        _fieldName = fieldName;
      }

      public short getThriftFieldId() {
        return _thriftId;
      }

      public String getFieldName() {
        return _fieldName;
      }
    }

    // isset id assignments
    public static final Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
    static {
      Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new EnumMap<_Fields, org.apache.thrift.meta_data.FieldMetaData>(_Fields.class);
      tmpMap.put(_Fields.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.APP_INTERFACE_ID, new org.apache.thrift.meta_data.FieldMetaData("appInterfaceId", org.apache.thrift.TFieldRequirementType.REQUIRED, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING)));
      metaDataMap = Collections.unmodifiableMap(tmpMap);
      org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(deleteApplicationInterface_args.class, metaDataMap);
    }

    public deleteApplicationInterface_args() {
    }

    public deleteApplicationInterface_args(
      org.apache.airavata.model.security.AuthzToken authzToken,
      String appInterfaceId)
    {
      this();
      this.authzToken = authzToken;
      this.appInterfaceId = appInterfaceId;
    }

    /**
     * Performs a deep copy on <i>other</i>.
     */
    public deleteApplicationInterface_args(deleteApplicationInterface_args other) {
      if (other.isSetAuthzToken()) {
        this.authzToken = new org.apache.airavata.model.security.AuthzToken(other.authzToken);
      }
      if (other.isSetAppInterfaceId()) {
        this.appInterfaceId = other.appInterfaceId;
      }
    }

    public deleteApplicationInterface_args deepCopy() {
      return new deleteApplicationInterface_args(this);
    }

    @Override
    public void clear() {
      this.authzToken = null;
      this.appInterfaceId = null;
    }

    public org.apache.airavata.model.security.AuthzToken getAuthzToken() {
      return this.authzToken;
    }

    public deleteApplicationInterface_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 String getAppInterfaceId() {
      return this.appInterfaceId;
    }

    public deleteApplicationInterface_args setAppInterfaceId(String appInterfaceId) {
      this.appInterfaceId = appInterfaceId;
      return this;
    }

    public void unsetAppInterfaceId() {
      this.appInterfaceId = null;
    }

    /** Returns true if field appInterfaceId is set (has been assigned a value) and false otherwise */
    public boolean isSetAppInterfaceId() {
      return this.appInterfaceId != null;
    }

    public void setAppInterfaceIdIsSet(boolean value) {
      if (!value) {
        this.appInterfaceId = null;
      }
    }

    public void setFieldValue(_Fields field, Object value) {
      switch (field) {
      case AUTHZ_TOKEN:
        if (value == null) {
          unsetAuthzToken();
        } else {
          setAuthzToken((org.apache.airavata.model.security.AuthzToken)value);
        }
        break;

      case APP_INTERFACE_ID:
        if (value == null) {
          unsetAppInterfaceId();
        } else {
          setAppInterfaceId((String)value);
        }
        break;

      }
    }

    public Object getFieldValue(_Fields field) {
      switch (field) {
      case AUTHZ_TOKEN:
        return getAuthzToken();

      case APP_INTERFACE_ID:
        return getAppInterfaceId();

      }
      throw new IllegalStateException();
    }

    /** Returns true if field corresponding to fieldID is set (has been assigned a value) and false otherwise */
    public boolean isSet(_Fields field) {
      if (field == null) {
        throw new IllegalArgumentException();
      }

      switch (field) {
      case AUTHZ_TOKEN:
        return isSetAuthzToken();
      case APP_INTERFACE_ID:
        return isSetAppInterfaceId();
      }
      throw new IllegalStateException();
    }

    @Override
    public boolean equals(Object that) {
      if (that == null)
        return false;
      if (that instanceof deleteApplicationInterface_args)
        return this.equals((deleteApplicationInterface_args)that);
      return false;
    }

    public boolean equals(deleteApplicationInterface_args that) {
      if (that == null)
        return false;

      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_appInterfaceId = true && this.isSetAppInterfaceId();
      boolean that_present_appInterfaceId = true && that.isSetAppInterfaceId();
      if (this_present_appInterfaceId || that_present_appInterfaceId) {
        if (!(this_present_appInterfaceId && that_present_appInterfaceId))
          return false;
        if (!this.appInterfaceId.equals(that.appInterfaceId))
          return false;
      }

      return true;
    }

    @Override
    public int hashCode() {
      List<Object> list = new ArrayList<Object>();

      boolean present_authzToken = true && (isSetAuthzToken());
      list.add(present_authzToken);
      if (present_authzToken)
        list.add(authzToken);

      boolean present_appInterfaceId = true && (isSetAppInterfaceId());
      list.add(present_appInterfaceId);
      if (present_appInterfaceId)
        list.add(appInterfaceId);

      return list.hashCode();
    }

    @Override
    public int compareTo(deleteApplicationInterface_args other) {
      if (!getClass().equals(other.getClass())) {
        return getClass().getName().compareTo(other.getClass().getName());
      }

      int lastComparison = 0;

      lastComparison = 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 = Boolean.valueOf(isSetAppInterfaceId()).compareTo(other.isSetAppInterfaceId());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetAppInterfaceId()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.appInterfaceId, other.appInterfaceId);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      return 0;
    }

    public _Fields fieldForId(int fieldId) {
      return _Fields.findByThriftId(fieldId);
    }

    public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
      schemes.get(iprot.getScheme()).getScheme().read(iprot, this);
    }

    public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException {
      schemes.get(oprot.getScheme()).getScheme().write(oprot, this);
    }

    @Override
    public String toString() {
      StringBuilder sb = new StringBuilder("deleteApplicationInterface_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("appInterfaceId:");
      if (this.appInterfaceId == null) {
        sb.append("null");
      } else {
        sb.append(this.appInterfaceId);
      }
      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 (appInterfaceId == null) {
        throw new org.apache.thrift.protocol.TProtocolException("Required field 'appInterfaceId' 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, 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 deleteApplicationInterface_argsStandardSchemeFactory implements SchemeFactory {
      public deleteApplicationInterface_argsStandardScheme getScheme() {
        return new deleteApplicationInterface_argsStandardScheme();
      }
    }

    private static class deleteApplicationInterface_argsStandardScheme extends StandardScheme<deleteApplicationInterface_args> {

      public void read(org.apache.thrift.protocol.TProtocol iprot, deleteApplicationInterface_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: // APP_INTERFACE_ID
              if (schemeField.type == org.apache.thrift.protocol.TType.STRING) {
                struct.appInterfaceId = iprot.readString();
                struct.setAppInterfaceIdIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            default:
              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
          }
          iprot.readFieldEnd();
        }
        iprot.readStructEnd();

        // check for required fields of primitive type, which can't be checked in the validate method
        struct.validate();
      }

      public void write(org.apache.thrift.protocol.TProtocol oprot, deleteApplicationInterface_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.appInterfaceId != null) {
          oprot.writeFieldBegin(APP_INTERFACE_ID_FIELD_DESC);
          oprot.writeString(struct.appInterfaceId);
          oprot.writeFieldEnd();
        }
        oprot.writeFieldStop();
        oprot.writeStructEnd();
      }

    }

    private static class deleteApplicationInterface_argsTupleSchemeFactory implements SchemeFactory {
      public deleteApplicationInterface_argsTupleScheme getScheme() {
        return new deleteApplicationInterface_argsTupleScheme();
      }
    }

    private static class deleteApplicationInterface_argsTupleScheme extends TupleScheme<deleteApplicationInterface_args> {

      @Override
      public void write(org.apache.thrift.protocol.TProtocol prot, deleteApplicationInterface_args struct) throws org.apache.thrift.TException {
        TTupleProtocol oprot = (TTupleProtocol) prot;
        struct.authzToken.write(oprot);
        oprot.writeString(struct.appInterfaceId);
      }

      @Override
      public void read(org.apache.thrift.protocol.TProtocol prot, deleteApplicationInterface_args struct) throws org.apache.thrift.TException {
        TTupleProtocol iprot = (TTupleProtocol) prot;
        struct.authzToken = new org.apache.airavata.model.security.AuthzToken();
        struct.authzToken.read(iprot);
        struct.setAuthzTokenIsSet(true);
        struct.appInterfaceId = iprot.readString();
        struct.setAppInterfaceIdIsSet(true);
      }
    }

  }

  public static class deleteApplicationInterface_result implements org.apache.thrift.TBase<deleteApplicationInterface_result, deleteApplicationInterface_result._Fields>, java.io.Serializable, Cloneable, Comparable<deleteApplicationInterface_result>   {
    private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("deleteApplicationInterface_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 IRE_FIELD_DESC = new org.apache.thrift.protocol.TField("ire", org.apache.thrift.protocol.TType.STRUCT, (short)1);
    private static final org.apache.thrift.protocol.TField ACE_FIELD_DESC = new org.apache.thrift.protocol.TField("ace", org.apache.thrift.protocol.TType.STRUCT, (short)2);
    private static final org.apache.thrift.protocol.TField ASE_FIELD_DESC = new org.apache.thrift.protocol.TField("ase", org.apache.thrift.protocol.TType.STRUCT, (short)3);
    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)4);

    private static final Map<Class<? extends IScheme>, SchemeFactory> schemes = new HashMap<Class<? extends IScheme>, SchemeFactory>();
    static {
      schemes.put(StandardScheme.class, new deleteApplicationInterface_resultStandardSchemeFactory());
      schemes.put(TupleScheme.class, new deleteApplicationInterface_resultTupleSchemeFactory());
    }

    public boolean success; // required
    public org.apache.airavata.model.error.InvalidRequestException ire; // required
    public org.apache.airavata.model.error.AiravataClientException ace; // required
    public org.apache.airavata.model.error.AiravataSystemException ase; // 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"),
      IRE((short)1, "ire"),
      ACE((short)2, "ace"),
      ASE((short)3, "ase"),
      AE((short)4, "ae");

      private static final Map<String, _Fields> byName = new HashMap<String, _Fields>();

      static {
        for (_Fields field : EnumSet.allOf(_Fields.class)) {
          byName.put(field.getFieldName(), field);
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, or null if its not found.
       */
      public static _Fields findByThriftId(int fieldId) {
        switch(fieldId) {
          case 0: // SUCCESS
            return SUCCESS;
          case 1: // IRE
            return IRE;
          case 2: // ACE
            return ACE;
          case 3: // ASE
            return ASE;
          case 4: // 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 IllegalArgumentException("Field " + fieldId + " doesn't exist!");
        return fields;
      }

      /**
       * Find the _Fields constant that matches name, or null if its not found.
       */
      public static _Fields findByName(String name) {
        return byName.get(name);
      }

      private final short _thriftId;
      private final String _fieldName;

      _Fields(short thriftId, String fieldName) {
        _thriftId = thriftId;
        _fieldName = fieldName;
      }

      public short getThriftFieldId() {
        return _thriftId;
      }

      public String getFieldName() {
        return _fieldName;
      }
    }

    // isset id assignments
    private static final int __SUCCESS_ISSET_ID = 0;
    private byte __isset_bitfield = 0;
    public static final Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
    static {
      Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new EnumMap<_Fields, org.apache.thrift.meta_data.FieldMetaData>(_Fields.class);
      tmpMap.put(_Fields.SUCCESS, new org.apache.thrift.meta_data.FieldMetaData("success", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.BOOL)));
      tmpMap.put(_Fields.IRE, new org.apache.thrift.meta_data.FieldMetaData("ire", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRUCT)));
      tmpMap.put(_Fields.ACE, new org.apache.thrift.meta_data.FieldMetaData("ace", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRUCT)));
      tmpMap.put(_Fields.ASE, new org.apache.thrift.meta_data.FieldMetaData("ase", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRUCT)));
      tmpMap.put(_Fields.AE, new org.apache.thrift.meta_data.FieldMetaData("ae", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRUCT)));
      metaDataMap = Collections.unmodifiableMap(tmpMap);
      org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(deleteApplicationInterface_result.class, metaDataMap);
    }

    public deleteApplicationInterface_result() {
    }

    public deleteApplicationInterface_result(
      boolean success,
      org.apache.airavata.model.error.InvalidRequestException ire,
      org.apache.airavata.model.error.AiravataClientException ace,
      org.apache.airavata.model.error.AiravataSystemException ase,
      org.apache.airavata.model.error.AuthorizationException ae)
    {
      this();
      this.success = success;
      setSuccessIsSet(true);
      this.ire = ire;
      this.ace = ace;
      this.ase = ase;
      this.ae = ae;
    }

    /**
     * Performs a deep copy on <i>other</i>.
     */
    public deleteApplicationInterface_result(deleteApplicationInterface_result other) {
      __isset_bitfield = other.__isset_bitfield;
      this.success = other.success;
      if (other.isSetIre()) {
        this.ire = new org.apache.airavata.model.error.InvalidRequestException(other.ire);
      }
      if (other.isSetAce()) {
        this.ace = new org.apache.airavata.model.error.AiravataClientException(other.ace);
      }
      if (other.isSetAse()) {
        this.ase = new org.apache.airavata.model.error.AiravataSystemException(other.ase);
      }
      if (other.isSetAe()) {
        this.ae = new org.apache.airavata.model.error.AuthorizationException(other.ae);
      }
    }

    public deleteApplicationInterface_result deepCopy() {
      return new deleteApplicationInterface_result(this);
    }

    @Override
    public void clear() {
      setSuccessIsSet(false);
      this.success = false;
      this.ire = null;
      this.ace = null;
      this.ase = null;
      this.ae = null;
    }

    public boolean isSuccess() {
      return this.success;
    }

    public deleteApplicationInterface_result setSuccess(boolean success) {
      this.success = success;
      setSuccessIsSet(true);
      return this;
    }

    public void unsetSuccess() {
      __isset_bitfield = EncodingUtils.clearBit(__isset_bitfield, __SUCCESS_ISSET_ID);
    }

    /** Returns true if field success is set (has been assigned a value) and false otherwise */
    public boolean isSetSuccess() {
      return EncodingUtils.testBit(__isset_bitfield, __SUCCESS_ISSET_ID);
    }

    public void setSuccessIsSet(boolean value) {
      __isset_bitfield = EncodingUtils.setBit(__isset_bitfield, __SUCCESS_ISSET_ID, value);
    }

    public org.apache.airavata.model.error.InvalidRequestException getIre() {
      return this.ire;
    }

    public deleteApplicationInterface_result setIre(org.apache.airavata.model.error.InvalidRequestException ire) {
      this.ire = ire;
      return this;
    }

    public void unsetIre() {
      this.ire = null;
    }

    /** Returns true if field ire is set (has been assigned a value) and false otherwise */
    public boolean isSetIre() {
      return this.ire != null;
    }

    public void setIreIsSet(boolean value) {
      if (!value) {
        this.ire = null;
      }
    }

    public org.apache.airavata.model.error.AiravataClientException getAce() {
      return this.ace;
    }

    public deleteApplicationInterface_result setAce(org.apache.airavata.model.error.AiravataClientException ace) {
      this.ace = ace;
      return this;
    }

    public void unsetAce() {
      this.ace = null;
    }

    /** Returns true if field ace is set (has been assigned a value) and false otherwise */
    public boolean isSetAce() {
      return this.ace != null;
    }

    public void setAceIsSet(boolean value) {
      if (!value) {
        this.ace = null;
      }
    }

    public org.apache.airavata.model.error.AiravataSystemException getAse() {
      return this.ase;
    }

    public deleteApplicationInterface_result setAse(org.apache.airavata.model.error.AiravataSystemException ase) {
      this.ase = ase;
      return this;
    }

    public void unsetAse() {
      this.ase = null;
    }

    /** Returns true if field ase is set (has been assigned a value) and false otherwise */
    public boolean isSetAse() {
      return this.ase != null;
    }

    public void setAseIsSet(boolean value) {
      if (!value) {
        this.ase = null;
      }
    }

    public org.apache.airavata.model.error.AuthorizationException getAe() {
      return this.ae;
    }

    public deleteApplicationInterface_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, Object value) {
      switch (field) {
      case SUCCESS:
        if (value == null) {
          unsetSuccess();
        } else {
          setSuccess((Boolean)value);
        }
        break;

      case IRE:
        if (value == null) {
          unsetIre();
        } else {
          setIre((org.apache.airavata.model.error.InvalidRequestException)value);
        }
        break;

      case ACE:
        if (value == null) {
          unsetAce();
        } else {
          setAce((org.apache.airavata.model.error.AiravataClientException)value);
        }
        break;

      case ASE:
        if (value == null) {
          unsetAse();
        } else {
          setAse((org.apache.airavata.model.error.AiravataSystemException)value);
        }
        break;

      case AE:
        if (value == null) {
          unsetAe();
        } else {
          setAe((org.apache.airavata.model.error.AuthorizationException)value);
        }
        break;

      }
    }

    public Object getFieldValue(_Fields field) {
      switch (field) {
      case SUCCESS:
        return Boolean.valueOf(isSuccess());

      case IRE:
        return getIre();

      case ACE:
        return getAce();

      case ASE:
        return getAse();

      case AE:
        return getAe();

      }
      throw new IllegalStateException();
    }

    /** Returns true if field corresponding to fieldID is set (has been assigned a value) and false otherwise */
    public boolean isSet(_Fields field) {
      if (field == null) {
        throw new IllegalArgumentException();
      }

      switch (field) {
      case SUCCESS:
        return isSetSuccess();
      case IRE:
        return isSetIre();
      case ACE:
        return isSetAce();
      case ASE:
        return isSetAse();
      case AE:
        return isSetAe();
      }
      throw new IllegalStateException();
    }

    @Override
    public boolean equals(Object that) {
      if (that == null)
        return false;
      if (that instanceof deleteApplicationInterface_result)
        return this.equals((deleteApplicationInterface_result)that);
      return false;
    }

    public boolean equals(deleteApplicationInterface_result that) {
      if (that == null)
        return false;

      boolean this_present_success = true;
      boolean that_present_success = true;
      if (this_present_success || that_present_success) {
        if (!(this_present_success && that_present_success))
          return false;
        if (this.success != that.success)
          return false;
      }

      boolean this_present_ire = true && this.isSetIre();
      boolean that_present_ire = true && that.isSetIre();
      if (this_present_ire || that_present_ire) {
        if (!(this_present_ire && that_present_ire))
          return false;
        if (!this.ire.equals(that.ire))
          return false;
      }

      boolean this_present_ace = true && this.isSetAce();
      boolean that_present_ace = true && that.isSetAce();
      if (this_present_ace || that_present_ace) {
        if (!(this_present_ace && that_present_ace))
          return false;
        if (!this.ace.equals(that.ace))
          return false;
      }

      boolean this_present_ase = true && this.isSetAse();
      boolean that_present_ase = true && that.isSetAse();
      if (this_present_ase || that_present_ase) {
        if (!(this_present_ase && that_present_ase))
          return false;
        if (!this.ase.equals(that.ase))
          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() {
      List<Object> list = new ArrayList<Object>();

      boolean present_success = true;
      list.add(present_success);
      if (present_success)
        list.add(success);

      boolean present_ire = true && (isSetIre());
      list.add(present_ire);
      if (present_ire)
        list.add(ire);

      boolean present_ace = true && (isSetAce());
      list.add(present_ace);
      if (present_ace)
        list.add(ace);

      boolean present_ase = true && (isSetAse());
      list.add(present_ase);
      if (present_ase)
        list.add(ase);

      boolean present_ae = true && (isSetAe());
      list.add(present_ae);
      if (present_ae)
        list.add(ae);

      return list.hashCode();
    }

    @Override
    public int compareTo(deleteApplicationInterface_result other) {
      if (!getClass().equals(other.getClass())) {
        return getClass().getName().compareTo(other.getClass().getName());
      }

      int lastComparison = 0;

      lastComparison = Boolean.valueOf(isSetSuccess()).compareTo(other.isSetSuccess());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetSuccess()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.success, other.success);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = Boolean.valueOf(isSetIre()).compareTo(other.isSetIre());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetIre()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.ire, other.ire);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = Boolean.valueOf(isSetAce()).compareTo(other.isSetAce());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetAce()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.ace, other.ace);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = Boolean.valueOf(isSetAse()).compareTo(other.isSetAse());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetAse()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.ase, other.ase);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = 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 {
      schemes.get(iprot.getScheme()).getScheme().read(iprot, this);
    }

    public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException {
      schemes.get(oprot.getScheme()).getScheme().write(oprot, this);
      }

    @Override
    public String toString() {
      StringBuilder sb = new StringBuilder("deleteApplicationInterface_result(");
      boolean first = true;

      sb.append("success:");
      sb.append(this.success);
      first = false;
      if (!first) sb.append(", ");
      sb.append("ire:");
      if (this.ire == null) {
        sb.append("null");
      } else {
        sb.append(this.ire);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("ace:");
      if (this.ace == null) {
        sb.append("null");
      } else {
        sb.append(this.ace);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("ase:");
      if (this.ase == null) {
        sb.append("null");
      } else {
        sb.append(this.ase);
      }
      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, 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 deleteApplicationInterface_resultStandardSchemeFactory implements SchemeFactory {
      public deleteApplicationInterface_resultStandardScheme getScheme() {
        return new deleteApplicationInterface_resultStandardScheme();
      }
    }

    private static class deleteApplicationInterface_resultStandardScheme extends StandardScheme<deleteApplicationInterface_result> {

      public void read(org.apache.thrift.protocol.TProtocol iprot, deleteApplicationInterface_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: // IRE
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.ire = new org.apache.airavata.model.error.InvalidRequestException();
                struct.ire.read(iprot);
                struct.setIreIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 2: // ACE
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.ace = new org.apache.airavata.model.error.AiravataClientException();
                struct.ace.read(iprot);
                struct.setAceIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 3: // ASE
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.ase = new org.apache.airavata.model.error.AiravataSystemException();
                struct.ase.read(iprot);
                struct.setAseIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 4: // 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, deleteApplicationInterface_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.ire != null) {
          oprot.writeFieldBegin(IRE_FIELD_DESC);
          struct.ire.write(oprot);
          oprot.writeFieldEnd();
        }
        if (struct.ace != null) {
          oprot.writeFieldBegin(ACE_FIELD_DESC);
          struct.ace.write(oprot);
          oprot.writeFieldEnd();
        }
        if (struct.ase != null) {
          oprot.writeFieldBegin(ASE_FIELD_DESC);
          struct.ase.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 deleteApplicationInterface_resultTupleSchemeFactory implements SchemeFactory {
      public deleteApplicationInterface_resultTupleScheme getScheme() {
        return new deleteApplicationInterface_resultTupleScheme();
      }
    }

    private static class deleteApplicationInterface_resultTupleScheme extends TupleScheme<deleteApplicationInterface_result> {

      @Override
      public void write(org.apache.thrift.protocol.TProtocol prot, deleteApplicationInterface_result struct) throws org.apache.thrift.TException {
        TTupleProtocol oprot = (TTupleProtocol) prot;
        BitSet optionals = new BitSet();
        if (struct.isSetSuccess()) {
          optionals.set(0);
        }
        if (struct.isSetIre()) {
          optionals.set(1);
        }
        if (struct.isSetAce()) {
          optionals.set(2);
        }
        if (struct.isSetAse()) {
          optionals.set(3);
        }
        if (struct.isSetAe()) {
          optionals.set(4);
        }
        oprot.writeBitSet(optionals, 5);
        if (struct.isSetSuccess()) {
          oprot.writeBool(struct.success);
        }
        if (struct.isSetIre()) {
          struct.ire.write(oprot);
        }
        if (struct.isSetAce()) {
          struct.ace.write(oprot);
        }
        if (struct.isSetAse()) {
          struct.ase.write(oprot);
        }
        if (struct.isSetAe()) {
          struct.ae.write(oprot);
        }
      }

      @Override
      public void read(org.apache.thrift.protocol.TProtocol prot, deleteApplicationInterface_result struct) throws org.apache.thrift.TException {
        TTupleProtocol iprot = (TTupleProtocol) prot;
        BitSet incoming = iprot.readBitSet(5);
        if (incoming.get(0)) {
          struct.success = iprot.readBool();
          struct.setSuccessIsSet(true);
        }
        if (incoming.get(1)) {
          struct.ire = new org.apache.airavata.model.error.InvalidRequestException();
          struct.ire.read(iprot);
          struct.setIreIsSet(true);
        }
        if (incoming.get(2)) {
          struct.ace = new org.apache.airavata.model.error.AiravataClientException();
          struct.ace.read(iprot);
          struct.setAceIsSet(true);
        }
        if (incoming.get(3)) {
          struct.ase = new org.apache.airavata.model.error.AiravataSystemException();
          struct.ase.read(iprot);
          struct.setAseIsSet(true);
        }
        if (incoming.get(4)) {
          struct.ae = new org.apache.airavata.model.error.AuthorizationException();
          struct.ae.read(iprot);
          struct.setAeIsSet(true);
        }
      }
    }

  }

  public static class getAllApplicationInterfaceNames_args implements org.apache.thrift.TBase<getAllApplicationInterfaceNames_args, getAllApplicationInterfaceNames_args._Fields>, java.io.Serializable, Cloneable, Comparable<getAllApplicationInterfaceNames_args>   {
    private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("getAllApplicationInterfaceNames_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 Map<Class<? extends IScheme>, SchemeFactory> schemes = new HashMap<Class<? extends IScheme>, SchemeFactory>();
    static {
      schemes.put(StandardScheme.class, new getAllApplicationInterfaceNames_argsStandardSchemeFactory());
      schemes.put(TupleScheme.class, new getAllApplicationInterfaceNames_argsTupleSchemeFactory());
    }

    public org.apache.airavata.model.security.AuthzToken authzToken; // required
    public 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 Map<String, _Fields> byName = new HashMap<String, _Fields>();

      static {
        for (_Fields field : EnumSet.allOf(_Fields.class)) {
          byName.put(field.getFieldName(), field);
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, or null if its not found.
       */
      public static _Fields findByThriftId(int fieldId) {
        switch(fieldId) {
          case 1: // 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 IllegalArgumentException("Field " + fieldId + " doesn't exist!");
        return fields;
      }

      /**
       * Find the _Fields constant that matches name, or null if its not found.
       */
      public static _Fields findByName(String name) {
        return byName.get(name);
      }

      private final short _thriftId;
      private final String _fieldName;

      _Fields(short thriftId, String fieldName) {
        _thriftId = thriftId;
        _fieldName = fieldName;
      }

      public short getThriftFieldId() {
        return _thriftId;
      }

      public String getFieldName() {
        return _fieldName;
      }
    }

    // isset id assignments
    public static final Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
    static {
      Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new EnumMap<_Fields, org.apache.thrift.meta_data.FieldMetaData>(_Fields.class);
      tmpMap.put(_Fields.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 = Collections.unmodifiableMap(tmpMap);
      org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(getAllApplicationInterfaceNames_args.class, metaDataMap);
    }

    public getAllApplicationInterfaceNames_args() {
    }

    public getAllApplicationInterfaceNames_args(
      org.apache.airavata.model.security.AuthzToken authzToken,
      String gatewayId)
    {
      this();
      this.authzToken = authzToken;
      this.gatewayId = gatewayId;
    }

    /**
     * Performs a deep copy on <i>other</i>.
     */
    public getAllApplicationInterfaceNames_args(getAllApplicationInterfaceNames_args other) {
      if (other.isSetAuthzToken()) {
        this.authzToken = new org.apache.airavata.model.security.AuthzToken(other.authzToken);
      }
      if (other.isSetGatewayId()) {
        this.gatewayId = other.gatewayId;
      }
    }

    public getAllApplicationInterfaceNames_args deepCopy() {
      return new getAllApplicationInterfaceNames_args(this);
    }

    @Override
    public void clear() {
      this.authzToken = null;
      this.gatewayId = null;
    }

    public org.apache.airavata.model.security.AuthzToken getAuthzToken() {
      return this.authzToken;
    }

    public getAllApplicationInterfaceNames_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 String getGatewayId() {
      return this.gatewayId;
    }

    public getAllApplicationInterfaceNames_args setGatewayId(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, 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((String)value);
        }
        break;

      }
    }

    public Object getFieldValue(_Fields field) {
      switch (field) {
      case AUTHZ_TOKEN:
        return getAuthzToken();

      case GATEWAY_ID:
        return getGatewayId();

      }
      throw new IllegalStateException();
    }

    /** Returns true if field corresponding to fieldID is set (has been assigned a value) and false otherwise */
    public boolean isSet(_Fields field) {
      if (field == null) {
        throw new IllegalArgumentException();
      }

      switch (field) {
      case AUTHZ_TOKEN:
        return isSetAuthzToken();
      case GATEWAY_ID:
        return isSetGatewayId();
      }
      throw new IllegalStateException();
    }

    @Override
    public boolean equals(Object that) {
      if (that == null)
        return false;
      if (that instanceof getAllApplicationInterfaceNames_args)
        return this.equals((getAllApplicationInterfaceNames_args)that);
      return false;
    }

    public boolean equals(getAllApplicationInterfaceNames_args that) {
      if (that == null)
        return false;

      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() {
      List<Object> list = new ArrayList<Object>();

      boolean present_authzToken = true && (isSetAuthzToken());
      list.add(present_authzToken);
      if (present_authzToken)
        list.add(authzToken);

      boolean present_gatewayId = true && (isSetGatewayId());
      list.add(present_gatewayId);
      if (present_gatewayId)
        list.add(gatewayId);

      return list.hashCode();
    }

    @Override
    public int compareTo(getAllApplicationInterfaceNames_args other) {
      if (!getClass().equals(other.getClass())) {
        return getClass().getName().compareTo(other.getClass().getName());
      }

      int lastComparison = 0;

      lastComparison = 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 = 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 {
      schemes.get(iprot.getScheme()).getScheme().read(iprot, this);
    }

    public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException {
      schemes.get(oprot.getScheme()).getScheme().write(oprot, this);
    }

    @Override
    public String toString() {
      StringBuilder sb = new StringBuilder("getAllApplicationInterfaceNames_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, 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 getAllApplicationInterfaceNames_argsStandardSchemeFactory implements SchemeFactory {
      public getAllApplicationInterfaceNames_argsStandardScheme getScheme() {
        return new getAllApplicationInterfaceNames_argsStandardScheme();
      }
    }

    private static class getAllApplicationInterfaceNames_argsStandardScheme extends StandardScheme<getAllApplicationInterfaceNames_args> {

      public void read(org.apache.thrift.protocol.TProtocol iprot, getAllApplicationInterfaceNames_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, getAllApplicationInterfaceNames_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 getAllApplicationInterfaceNames_argsTupleSchemeFactory implements SchemeFactory {
      public getAllApplicationInterfaceNames_argsTupleScheme getScheme() {
        return new getAllApplicationInterfaceNames_argsTupleScheme();
      }
    }

    private static class getAllApplicationInterfaceNames_argsTupleScheme extends TupleScheme<getAllApplicationInterfaceNames_args> {

      @Override
      public void write(org.apache.thrift.protocol.TProtocol prot, getAllApplicationInterfaceNames_args struct) throws org.apache.thrift.TException {
        TTupleProtocol oprot = (TTupleProtocol) prot;
        struct.authzToken.write(oprot);
        oprot.writeString(struct.gatewayId);
      }

      @Override
      public void read(org.apache.thrift.protocol.TProtocol prot, getAllApplicationInterfaceNames_args struct) throws org.apache.thrift.TException {
        TTupleProtocol iprot = (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);
      }
    }

  }

  public static class getAllApplicationInterfaceNames_result implements org.apache.thrift.TBase<getAllApplicationInterfaceNames_result, getAllApplicationInterfaceNames_result._Fields>, java.io.Serializable, Cloneable, Comparable<getAllApplicationInterfaceNames_result>   {
    private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("getAllApplicationInterfaceNames_result");

    private static final org.apache.thrift.protocol.TField SUCCESS_FIELD_DESC = new org.apache.thrift.protocol.TField("success", org.apache.thrift.protocol.TType.MAP, (short)0);
    private static final org.apache.thrift.protocol.TField IRE_FIELD_DESC = new org.apache.thrift.protocol.TField("ire", org.apache.thrift.protocol.TType.STRUCT, (short)1);
    private static final org.apache.thrift.protocol.TField ACE_FIELD_DESC = new org.apache.thrift.protocol.TField("ace", org.apache.thrift.protocol.TType.STRUCT, (short)2);
    private static final org.apache.thrift.protocol.TField ASE_FIELD_DESC = new org.apache.thrift.protocol.TField("ase", org.apache.thrift.protocol.TType.STRUCT, (short)3);
    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)4);

    private static final Map<Class<? extends IScheme>, SchemeFactory> schemes = new HashMap<Class<? extends IScheme>, SchemeFactory>();
    static {
      schemes.put(StandardScheme.class, new getAllApplicationInterfaceNames_resultStandardSchemeFactory());
      schemes.put(TupleScheme.class, new getAllApplicationInterfaceNames_resultTupleSchemeFactory());
    }

    public Map<String,String> success; // required
    public org.apache.airavata.model.error.InvalidRequestException ire; // required
    public org.apache.airavata.model.error.AiravataClientException ace; // required
    public org.apache.airavata.model.error.AiravataSystemException ase; // 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"),
      IRE((short)1, "ire"),
      ACE((short)2, "ace"),
      ASE((short)3, "ase"),
      AE((short)4, "ae");

      private static final Map<String, _Fields> byName = new HashMap<String, _Fields>();

      static {
        for (_Fields field : EnumSet.allOf(_Fields.class)) {
          byName.put(field.getFieldName(), field);
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, or null if its not found.
       */
      public static _Fields findByThriftId(int fieldId) {
        switch(fieldId) {
          case 0: // SUCCESS
            return SUCCESS;
          case 1: // IRE
            return IRE;
          case 2: // ACE
            return ACE;
          case 3: // ASE
            return ASE;
          case 4: // 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 IllegalArgumentException("Field " + fieldId + " doesn't exist!");
        return fields;
      }

      /**
       * Find the _Fields constant that matches name, or null if its not found.
       */
      public static _Fields findByName(String name) {
        return byName.get(name);
      }

      private final short _thriftId;
      private final String _fieldName;

      _Fields(short thriftId, String fieldName) {
        _thriftId = thriftId;
        _fieldName = fieldName;
      }

      public short getThriftFieldId() {
        return _thriftId;
      }

      public String getFieldName() {
        return _fieldName;
      }
    }

    // isset id assignments
    public static final Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
    static {
      Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new EnumMap<_Fields, org.apache.thrift.meta_data.FieldMetaData>(_Fields.class);
      tmpMap.put(_Fields.SUCCESS, new org.apache.thrift.meta_data.FieldMetaData("success", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.MapMetaData(org.apache.thrift.protocol.TType.MAP, 
              new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING), 
              new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING))));
      tmpMap.put(_Fields.IRE, new org.apache.thrift.meta_data.FieldMetaData("ire", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRUCT)));
      tmpMap.put(_Fields.ACE, new org.apache.thrift.meta_data.FieldMetaData("ace", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRUCT)));
      tmpMap.put(_Fields.ASE, new org.apache.thrift.meta_data.FieldMetaData("ase", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRUCT)));
      tmpMap.put(_Fields.AE, new org.apache.thrift.meta_data.FieldMetaData("ae", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRUCT)));
      metaDataMap = Collections.unmodifiableMap(tmpMap);
      org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(getAllApplicationInterfaceNames_result.class, metaDataMap);
    }

    public getAllApplicationInterfaceNames_result() {
    }

    public getAllApplicationInterfaceNames_result(
      Map<String,String> success,
      org.apache.airavata.model.error.InvalidRequestException ire,
      org.apache.airavata.model.error.AiravataClientException ace,
      org.apache.airavata.model.error.AiravataSystemException ase,
      org.apache.airavata.model.error.AuthorizationException ae)
    {
      this();
      this.success = success;
      this.ire = ire;
      this.ace = ace;
      this.ase = ase;
      this.ae = ae;
    }

    /**
     * Performs a deep copy on <i>other</i>.
     */
    public getAllApplicationInterfaceNames_result(getAllApplicationInterfaceNames_result other) {
      if (other.isSetSuccess()) {
        Map<String,String> __this__success = new HashMap<String,String>(other.success);
        this.success = __this__success;
      }
      if (other.isSetIre()) {
        this.ire = new org.apache.airavata.model.error.InvalidRequestException(other.ire);
      }
      if (other.isSetAce()) {
        this.ace = new org.apache.airavata.model.error.AiravataClientException(other.ace);
      }
      if (other.isSetAse()) {
        this.ase = new org.apache.airavata.model.error.AiravataSystemException(other.ase);
      }
      if (other.isSetAe()) {
        this.ae = new org.apache.airavata.model.error.AuthorizationException(other.ae);
      }
    }

    public getAllApplicationInterfaceNames_result deepCopy() {
      return new getAllApplicationInterfaceNames_result(this);
    }

    @Override
    public void clear() {
      this.success = null;
      this.ire = null;
      this.ace = null;
      this.ase = null;
      this.ae = null;
    }

    public int getSuccessSize() {
      return (this.success == null) ? 0 : this.success.size();
    }

    public void putToSuccess(String key, String val) {
      if (this.success == null) {
        this.success = new HashMap<String,String>();
      }
      this.success.put(key, val);
    }

    public Map<String,String> getSuccess() {
      return this.success;
    }

    public getAllApplicationInterfaceNames_result setSuccess(Map<String,String> success) {
      this.success = success;
      return this;
    }

    public void unsetSuccess() {
      this.success = null;
    }

    /** Returns true if field success is set (has been assigned a value) and false otherwise */
    public boolean isSetSuccess() {
      return this.success != null;
    }

    public void setSuccessIsSet(boolean value) {
      if (!value) {
        this.success = null;
      }
    }

    public org.apache.airavata.model.error.InvalidRequestException getIre() {
      return this.ire;
    }

    public getAllApplicationInterfaceNames_result setIre(org.apache.airavata.model.error.InvalidRequestException ire) {
      this.ire = ire;
      return this;
    }

    public void unsetIre() {
      this.ire = null;
    }

    /** Returns true if field ire is set (has been assigned a value) and false otherwise */
    public boolean isSetIre() {
      return this.ire != null;
    }

    public void setIreIsSet(boolean value) {
      if (!value) {
        this.ire = null;
      }
    }

    public org.apache.airavata.model.error.AiravataClientException getAce() {
      return this.ace;
    }

    public getAllApplicationInterfaceNames_result setAce(org.apache.airavata.model.error.AiravataClientException ace) {
      this.ace = ace;
      return this;
    }

    public void unsetAce() {
      this.ace = null;
    }

    /** Returns true if field ace is set (has been assigned a value) and false otherwise */
    public boolean isSetAce() {
      return this.ace != null;
    }

    public void setAceIsSet(boolean value) {
      if (!value) {
        this.ace = null;
      }
    }

    public org.apache.airavata.model.error.AiravataSystemException getAse() {
      return this.ase;
    }

    public getAllApplicationInterfaceNames_result setAse(org.apache.airavata.model.error.AiravataSystemException ase) {
      this.ase = ase;
      return this;
    }

    public void unsetAse() {
      this.ase = null;
    }

    /** Returns true if field ase is set (has been assigned a value) and false otherwise */
    public boolean isSetAse() {
      return this.ase != null;
    }

    public void setAseIsSet(boolean value) {
      if (!value) {
        this.ase = null;
      }
    }

    public org.apache.airavata.model.error.AuthorizationException getAe() {
      return this.ae;
    }

    public getAllApplicationInterfaceNames_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, Object value) {
      switch (field) {
      case SUCCESS:
        if (value == null) {
          unsetSuccess();
        } else {
          setSuccess((Map<String,String>)value);
        }
        break;

      case IRE:
        if (value == null) {
          unsetIre();
        } else {
          setIre((org.apache.airavata.model.error.InvalidRequestException)value);
        }
        break;

      case ACE:
        if (value == null) {
          unsetAce();
        } else {
          setAce((org.apache.airavata.model.error.AiravataClientException)value);
        }
        break;

      case ASE:
        if (value == null) {
          unsetAse();
        } else {
          setAse((org.apache.airavata.model.error.AiravataSystemException)value);
        }
        break;

      case AE:
        if (value == null) {
          unsetAe();
        } else {
          setAe((org.apache.airavata.model.error.AuthorizationException)value);
        }
        break;

      }
    }

    public Object getFieldValue(_Fields field) {
      switch (field) {
      case SUCCESS:
        return getSuccess();

      case IRE:
        return getIre();

      case ACE:
        return getAce();

      case ASE:
        return getAse();

      case AE:
        return getAe();

      }
      throw new IllegalStateException();
    }

    /** Returns true if field corresponding to fieldID is set (has been assigned a value) and false otherwise */
    public boolean isSet(_Fields field) {
      if (field == null) {
        throw new IllegalArgumentException();
      }

      switch (field) {
      case SUCCESS:
        return isSetSuccess();
      case IRE:
        return isSetIre();
      case ACE:
        return isSetAce();
      case ASE:
        return isSetAse();
      case AE:
        return isSetAe();
      }
      throw new IllegalStateException();
    }

    @Override
    public boolean equals(Object that) {
      if (that == null)
        return false;
      if (that instanceof getAllApplicationInterfaceNames_result)
        return this.equals((getAllApplicationInterfaceNames_result)that);
      return false;
    }

    public boolean equals(getAllApplicationInterfaceNames_result that) {
      if (that == null)
        return false;

      boolean this_present_success = true && this.isSetSuccess();
      boolean that_present_success = true && that.isSetSuccess();
      if (this_present_success || that_present_success) {
        if (!(this_present_success && that_present_success))
          return false;
        if (!this.success.equals(that.success))
          return false;
      }

      boolean this_present_ire = true && this.isSetIre();
      boolean that_present_ire = true && that.isSetIre();
      if (this_present_ire || that_present_ire) {
        if (!(this_present_ire && that_present_ire))
          return false;
        if (!this.ire.equals(that.ire))
          return false;
      }

      boolean this_present_ace = true && this.isSetAce();
      boolean that_present_ace = true && that.isSetAce();
      if (this_present_ace || that_present_ace) {
        if (!(this_present_ace && that_present_ace))
          return false;
        if (!this.ace.equals(that.ace))
          return false;
      }

      boolean this_present_ase = true && this.isSetAse();
      boolean that_present_ase = true && that.isSetAse();
      if (this_present_ase || that_present_ase) {
        if (!(this_present_ase && that_present_ase))
          return false;
        if (!this.ase.equals(that.ase))
          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() {
      List<Object> list = new ArrayList<Object>();

      boolean present_success = true && (isSetSuccess());
      list.add(present_success);
      if (present_success)
        list.add(success);

      boolean present_ire = true && (isSetIre());
      list.add(present_ire);
      if (present_ire)
        list.add(ire);

      boolean present_ace = true && (isSetAce());
      list.add(present_ace);
      if (present_ace)
        list.add(ace);

      boolean present_ase = true && (isSetAse());
      list.add(present_ase);
      if (present_ase)
        list.add(ase);

      boolean present_ae = true && (isSetAe());
      list.add(present_ae);
      if (present_ae)
        list.add(ae);

      return list.hashCode();
    }

    @Override
    public int compareTo(getAllApplicationInterfaceNames_result other) {
      if (!getClass().equals(other.getClass())) {
        return getClass().getName().compareTo(other.getClass().getName());
      }

      int lastComparison = 0;

      lastComparison = Boolean.valueOf(isSetSuccess()).compareTo(other.isSetSuccess());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetSuccess()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.success, other.success);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = Boolean.valueOf(isSetIre()).compareTo(other.isSetIre());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetIre()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.ire, other.ire);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = Boolean.valueOf(isSetAce()).compareTo(other.isSetAce());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetAce()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.ace, other.ace);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = Boolean.valueOf(isSetAse()).compareTo(other.isSetAse());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetAse()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.ase, other.ase);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = 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 {
      schemes.get(iprot.getScheme()).getScheme().read(iprot, this);
    }

    public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException {
      schemes.get(oprot.getScheme()).getScheme().write(oprot, this);
      }

    @Override
    public String toString() {
      StringBuilder sb = new StringBuilder("getAllApplicationInterfaceNames_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("ire:");
      if (this.ire == null) {
        sb.append("null");
      } else {
        sb.append(this.ire);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("ace:");
      if (this.ace == null) {
        sb.append("null");
      } else {
        sb.append(this.ace);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("ase:");
      if (this.ase == null) {
        sb.append("null");
      } else {
        sb.append(this.ase);
      }
      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, 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 getAllApplicationInterfaceNames_resultStandardSchemeFactory implements SchemeFactory {
      public getAllApplicationInterfaceNames_resultStandardScheme getScheme() {
        return new getAllApplicationInterfaceNames_resultStandardScheme();
      }
    }

    private static class getAllApplicationInterfaceNames_resultStandardScheme extends StandardScheme<getAllApplicationInterfaceNames_result> {

      public void read(org.apache.thrift.protocol.TProtocol iprot, getAllApplicationInterfaceNames_result struct) throws org.apache.thrift.TException {
        org.apache.thrift.protocol.TField schemeField;
        iprot.readStructBegin();
        while (true)
        {
          schemeField = iprot.readFieldBegin();
          if (schemeField.type == org.apache.thrift.protocol.TType.STOP) { 
            break;
          }
          switch (schemeField.id) {
            case 0: // SUCCESS
              if (schemeField.type == org.apache.thrift.protocol.TType.MAP) {
                {
                  org.apache.thrift.protocol.TMap _map174 = iprot.readMapBegin();
                  struct.success = new HashMap<String,String>(2*_map174.size);
                  String _key175;
                  String _val176;
                  for (int _i177 = 0; _i177 < _map174.size; ++_i177)
                  {
                    _key175 = iprot.readString();
                    _val176 = iprot.readString();
                    struct.success.put(_key175, _val176);
                  }
                  iprot.readMapEnd();
                }
                struct.setSuccessIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 1: // IRE
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.ire = new org.apache.airavata.model.error.InvalidRequestException();
                struct.ire.read(iprot);
                struct.setIreIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 2: // ACE
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.ace = new org.apache.airavata.model.error.AiravataClientException();
                struct.ace.read(iprot);
                struct.setAceIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 3: // ASE
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.ase = new org.apache.airavata.model.error.AiravataSystemException();
                struct.ase.read(iprot);
                struct.setAseIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 4: // 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, getAllApplicationInterfaceNames_result struct) throws org.apache.thrift.TException {
        struct.validate();

        oprot.writeStructBegin(STRUCT_DESC);
        if (struct.success != null) {
          oprot.writeFieldBegin(SUCCESS_FIELD_DESC);
          {
            oprot.writeMapBegin(new org.apache.thrift.protocol.TMap(org.apache.thrift.protocol.TType.STRING, org.apache.thrift.protocol.TType.STRING, struct.success.size()));
            for (Map.Entry<String, String> _iter178 : struct.success.entrySet())
            {
              oprot.writeString(_iter178.getKey());
              oprot.writeString(_iter178.getValue());
            }
            oprot.writeMapEnd();
          }
          oprot.writeFieldEnd();
        }
        if (struct.ire != null) {
          oprot.writeFieldBegin(IRE_FIELD_DESC);
          struct.ire.write(oprot);
          oprot.writeFieldEnd();
        }
        if (struct.ace != null) {
          oprot.writeFieldBegin(ACE_FIELD_DESC);
          struct.ace.write(oprot);
          oprot.writeFieldEnd();
        }
        if (struct.ase != null) {
          oprot.writeFieldBegin(ASE_FIELD_DESC);
          struct.ase.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 getAllApplicationInterfaceNames_resultTupleSchemeFactory implements SchemeFactory {
      public getAllApplicationInterfaceNames_resultTupleScheme getScheme() {
        return new getAllApplicationInterfaceNames_resultTupleScheme();
      }
    }

    private static class getAllApplicationInterfaceNames_resultTupleScheme extends TupleScheme<getAllApplicationInterfaceNames_result> {

      @Override
      public void write(org.apache.thrift.protocol.TProtocol prot, getAllApplicationInterfaceNames_result struct) throws org.apache.thrift.TException {
        TTupleProtocol oprot = (TTupleProtocol) prot;
        BitSet optionals = new BitSet();
        if (struct.isSetSuccess()) {
          optionals.set(0);
        }
        if (struct.isSetIre()) {
          optionals.set(1);
        }
        if (struct.isSetAce()) {
          optionals.set(2);
        }
        if (struct.isSetAse()) {
          optionals.set(3);
        }
        if (struct.isSetAe()) {
          optionals.set(4);
        }
        oprot.writeBitSet(optionals, 5);
        if (struct.isSetSuccess()) {
          {
            oprot.writeI32(struct.success.size());
            for (Map.Entry<String, String> _iter179 : struct.success.entrySet())
            {
              oprot.writeString(_iter179.getKey());
              oprot.writeString(_iter179.getValue());
            }
          }
        }
        if (struct.isSetIre()) {
          struct.ire.write(oprot);
        }
        if (struct.isSetAce()) {
          struct.ace.write(oprot);
        }
        if (struct.isSetAse()) {
          struct.ase.write(oprot);
        }
        if (struct.isSetAe()) {
          struct.ae.write(oprot);
        }
      }

      @Override
      public void read(org.apache.thrift.protocol.TProtocol prot, getAllApplicationInterfaceNames_result struct) throws org.apache.thrift.TException {
        TTupleProtocol iprot = (TTupleProtocol) prot;
        BitSet incoming = iprot.readBitSet(5);
        if (incoming.get(0)) {
          {
            org.apache.thrift.protocol.TMap _map180 = new org.apache.thrift.protocol.TMap(org.apache.thrift.protocol.TType.STRING, org.apache.thrift.protocol.TType.STRING, iprot.readI32());
            struct.success = new HashMap<String,String>(2*_map180.size);
            String _key181;
            String _val182;
            for (int _i183 = 0; _i183 < _map180.size; ++_i183)
            {
              _key181 = iprot.readString();
              _val182 = iprot.readString();
              struct.success.put(_key181, _val182);
            }
          }
          struct.setSuccessIsSet(true);
        }
        if (incoming.get(1)) {
          struct.ire = new org.apache.airavata.model.error.InvalidRequestException();
          struct.ire.read(iprot);
          struct.setIreIsSet(true);
        }
        if (incoming.get(2)) {
          struct.ace = new org.apache.airavata.model.error.AiravataClientException();
          struct.ace.read(iprot);
          struct.setAceIsSet(true);
        }
        if (incoming.get(3)) {
          struct.ase = new org.apache.airavata.model.error.AiravataSystemException();
          struct.ase.read(iprot);
          struct.setAseIsSet(true);
        }
        if (incoming.get(4)) {
          struct.ae = new org.apache.airavata.model.error.AuthorizationException();
          struct.ae.read(iprot);
          struct.setAeIsSet(true);
        }
      }
    }

  }

  public static class getAllApplicationInterfaces_args implements org.apache.thrift.TBase<getAllApplicationInterfaces_args, getAllApplicationInterfaces_args._Fields>, java.io.Serializable, Cloneable, Comparable<getAllApplicationInterfaces_args>   {
    private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("getAllApplicationInterfaces_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 Map<Class<? extends IScheme>, SchemeFactory> schemes = new HashMap<Class<? extends IScheme>, SchemeFactory>();
    static {
      schemes.put(StandardScheme.class, new getAllApplicationInterfaces_argsStandardSchemeFactory());
      schemes.put(TupleScheme.class, new getAllApplicationInterfaces_argsTupleSchemeFactory());
    }

    public org.apache.airavata.model.security.AuthzToken authzToken; // required
    public 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 Map<String, _Fields> byName = new HashMap<String, _Fields>();

      static {
        for (_Fields field : EnumSet.allOf(_Fields.class)) {
          byName.put(field.getFieldName(), field);
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, or null if its not found.
       */
      public static _Fields findByThriftId(int fieldId) {
        switch(fieldId) {
          case 1: // 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 IllegalArgumentException("Field " + fieldId + " doesn't exist!");
        return fields;
      }

      /**
       * Find the _Fields constant that matches name, or null if its not found.
       */
      public static _Fields findByName(String name) {
        return byName.get(name);
      }

      private final short _thriftId;
      private final String _fieldName;

      _Fields(short thriftId, String fieldName) {
        _thriftId = thriftId;
        _fieldName = fieldName;
      }

      public short getThriftFieldId() {
        return _thriftId;
      }

      public String getFieldName() {
        return _fieldName;
      }
    }

    // isset id assignments
    public static final Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
    static {
      Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new EnumMap<_Fields, org.apache.thrift.meta_data.FieldMetaData>(_Fields.class);
      tmpMap.put(_Fields.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 = Collections.unmodifiableMap(tmpMap);
      org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(getAllApplicationInterfaces_args.class, metaDataMap);
    }

    public getAllApplicationInterfaces_args() {
    }

    public getAllApplicationInterfaces_args(
      org.apache.airavata.model.security.AuthzToken authzToken,
      String gatewayId)
    {
      this();
      this.authzToken = authzToken;
      this.gatewayId = gatewayId;
    }

    /**
     * Performs a deep copy on <i>other</i>.
     */
    public getAllApplicationInterfaces_args(getAllApplicationInterfaces_args other) {
      if (other.isSetAuthzToken()) {
        this.authzToken = new org.apache.airavata.model.security.AuthzToken(other.authzToken);
      }
      if (other.isSetGatewayId()) {
        this.gatewayId = other.gatewayId;
      }
    }

    public getAllApplicationInterfaces_args deepCopy() {
      return new getAllApplicationInterfaces_args(this);
    }

    @Override
    public void clear() {
      this.authzToken = null;
      this.gatewayId = null;
    }

    public org.apache.airavata.model.security.AuthzToken getAuthzToken() {
      return this.authzToken;
    }

    public getAllApplicationInterfaces_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 String getGatewayId() {
      return this.gatewayId;
    }

    public getAllApplicationInterfaces_args setGatewayId(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, 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((String)value);
        }
        break;

      }
    }

    public Object getFieldValue(_Fields field) {
      switch (field) {
      case AUTHZ_TOKEN:
        return getAuthzToken();

      case GATEWAY_ID:
        return getGatewayId();

      }
      throw new IllegalStateException();
    }

    /** Returns true if field corresponding to fieldID is set (has been assigned a value) and false otherwise */
    public boolean isSet(_Fields field) {
      if (field == null) {
        throw new IllegalArgumentException();
      }

      switch (field) {
      case AUTHZ_TOKEN:
        return isSetAuthzToken();
      case GATEWAY_ID:
        return isSetGatewayId();
      }
      throw new IllegalStateException();
    }

    @Override
    public boolean equals(Object that) {
      if (that == null)
        return false;
      if (that instanceof getAllApplicationInterfaces_args)
        return this.equals((getAllApplicationInterfaces_args)that);
      return false;
    }

    public boolean equals(getAllApplicationInterfaces_args that) {
      if (that == null)
        return false;

      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() {
      List<Object> list = new ArrayList<Object>();

      boolean present_authzToken = true && (isSetAuthzToken());
      list.add(present_authzToken);
      if (present_authzToken)
        list.add(authzToken);

      boolean present_gatewayId = true && (isSetGatewayId());
      list.add(present_gatewayId);
      if (present_gatewayId)
        list.add(gatewayId);

      return list.hashCode();
    }

    @Override
    public int compareTo(getAllApplicationInterfaces_args other) {
      if (!getClass().equals(other.getClass())) {
        return getClass().getName().compareTo(other.getClass().getName());
      }

      int lastComparison = 0;

      lastComparison = 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 = 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 {
      schemes.get(iprot.getScheme()).getScheme().read(iprot, this);
    }

    public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException {
      schemes.get(oprot.getScheme()).getScheme().write(oprot, this);
    }

    @Override
    public String toString() {
      StringBuilder sb = new StringBuilder("getAllApplicationInterfaces_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, 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 getAllApplicationInterfaces_argsStandardSchemeFactory implements SchemeFactory {
      public getAllApplicationInterfaces_argsStandardScheme getScheme() {
        return new getAllApplicationInterfaces_argsStandardScheme();
      }
    }

    private static class getAllApplicationInterfaces_argsStandardScheme extends StandardScheme<getAllApplicationInterfaces_args> {

      public void read(org.apache.thrift.protocol.TProtocol iprot, getAllApplicationInterfaces_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, getAllApplicationInterfaces_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 getAllApplicationInterfaces_argsTupleSchemeFactory implements SchemeFactory {
      public getAllApplicationInterfaces_argsTupleScheme getScheme() {
        return new getAllApplicationInterfaces_argsTupleScheme();
      }
    }

    private static class getAllApplicationInterfaces_argsTupleScheme extends TupleScheme<getAllApplicationInterfaces_args> {

      @Override
      public void write(org.apache.thrift.protocol.TProtocol prot, getAllApplicationInterfaces_args struct) throws org.apache.thrift.TException {
        TTupleProtocol oprot = (TTupleProtocol) prot;
        struct.authzToken.write(oprot);
        oprot.writeString(struct.gatewayId);
      }

      @Override
      public void read(org.apache.thrift.protocol.TProtocol prot, getAllApplicationInterfaces_args struct) throws org.apache.thrift.TException {
        TTupleProtocol iprot = (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);
      }
    }

  }

  public static class getAllApplicationInterfaces_result implements org.apache.thrift.TBase<getAllApplicationInterfaces_result, getAllApplicationInterfaces_result._Fields>, java.io.Serializable, Cloneable, Comparable<getAllApplicationInterfaces_result>   {
    private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("getAllApplicationInterfaces_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 IRE_FIELD_DESC = new org.apache.thrift.protocol.TField("ire", org.apache.thrift.protocol.TType.STRUCT, (short)1);
    private static final org.apache.thrift.protocol.TField ACE_FIELD_DESC = new org.apache.thrift.protocol.TField("ace", org.apache.thrift.protocol.TType.STRUCT, (short)2);
    private static final org.apache.thrift.protocol.TField ASE_FIELD_DESC = new org.apache.thrift.protocol.TField("ase", org.apache.thrift.protocol.TType.STRUCT, (short)3);
    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)4);

    private static final Map<Class<? extends IScheme>, SchemeFactory> schemes = new HashMap<Class<? extends IScheme>, SchemeFactory>();
    static {
      schemes.put(StandardScheme.class, new getAllApplicationInterfaces_resultStandardSchemeFactory());
      schemes.put(TupleScheme.class, new getAllApplicationInterfaces_resultTupleSchemeFactory());
    }

    public List<org.apache.airavata.model.appcatalog.appinterface.ApplicationInterfaceDescription> success; // required
    public org.apache.airavata.model.error.InvalidRequestException ire; // required
    public org.apache.airavata.model.error.AiravataClientException ace; // required
    public org.apache.airavata.model.error.AiravataSystemException ase; // 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"),
      IRE((short)1, "ire"),
      ACE((short)2, "ace"),
      ASE((short)3, "ase"),
      AE((short)4, "ae");

      private static final Map<String, _Fields> byName = new HashMap<String, _Fields>();

      static {
        for (_Fields field : EnumSet.allOf(_Fields.class)) {
          byName.put(field.getFieldName(), field);
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, or null if its not found.
       */
      public static _Fields findByThriftId(int fieldId) {
        switch(fieldId) {
          case 0: // SUCCESS
            return SUCCESS;
          case 1: // IRE
            return IRE;
          case 2: // ACE
            return ACE;
          case 3: // ASE
            return ASE;
          case 4: // 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 IllegalArgumentException("Field " + fieldId + " doesn't exist!");
        return fields;
      }

      /**
       * Find the _Fields constant that matches name, or null if its not found.
       */
      public static _Fields findByName(String name) {
        return byName.get(name);
      }

      private final short _thriftId;
      private final String _fieldName;

      _Fields(short thriftId, String fieldName) {
        _thriftId = thriftId;
        _fieldName = fieldName;
      }

      public short getThriftFieldId() {
        return _thriftId;
      }

      public String getFieldName() {
        return _fieldName;
      }
    }

    // isset id assignments
    public static final Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
    static {
      Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new EnumMap<_Fields, org.apache.thrift.meta_data.FieldMetaData>(_Fields.class);
      tmpMap.put(_Fields.SUCCESS, new org.apache.thrift.meta_data.FieldMetaData("success", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.ListMetaData(org.apache.thrift.protocol.TType.LIST, 
              new org.apache.thrift.meta_data.StructMetaData(org.apache.thrift.protocol.TType.STRUCT, org.apache.airavata.model.appcatalog.appinterface.ApplicationInterfaceDescription.class))));
      tmpMap.put(_Fields.IRE, new org.apache.thrift.meta_data.FieldMetaData("ire", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRUCT)));
      tmpMap.put(_Fields.ACE, new org.apache.thrift.meta_data.FieldMetaData("ace", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRUCT)));
      tmpMap.put(_Fields.ASE, new org.apache.thrift.meta_data.FieldMetaData("ase", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRUCT)));
      tmpMap.put(_Fields.AE, new org.apache.thrift.meta_data.FieldMetaData("ae", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRUCT)));
      metaDataMap = Collections.unmodifiableMap(tmpMap);
      org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(getAllApplicationInterfaces_result.class, metaDataMap);
    }

    public getAllApplicationInterfaces_result() {
    }

    public getAllApplicationInterfaces_result(
      List<org.apache.airavata.model.appcatalog.appinterface.ApplicationInterfaceDescription> success,
      org.apache.airavata.model.error.InvalidRequestException ire,
      org.apache.airavata.model.error.AiravataClientException ace,
      org.apache.airavata.model.error.AiravataSystemException ase,
      org.apache.airavata.model.error.AuthorizationException ae)
    {
      this();
      this.success = success;
      this.ire = ire;
      this.ace = ace;
      this.ase = ase;
      this.ae = ae;
    }

    /**
     * Performs a deep copy on <i>other</i>.
     */
    public getAllApplicationInterfaces_result(getAllApplicationInterfaces_result other) {
      if (other.isSetSuccess()) {
        List<org.apache.airavata.model.appcatalog.appinterface.ApplicationInterfaceDescription> __this__success = new ArrayList<org.apache.airavata.model.appcatalog.appinterface.ApplicationInterfaceDescription>(other.success.size());
        for (org.apache.airavata.model.appcatalog.appinterface.ApplicationInterfaceDescription other_element : other.success) {
          __this__success.add(new org.apache.airavata.model.appcatalog.appinterface.ApplicationInterfaceDescription(other_element));
        }
        this.success = __this__success;
      }
      if (other.isSetIre()) {
        this.ire = new org.apache.airavata.model.error.InvalidRequestException(other.ire);
      }
      if (other.isSetAce()) {
        this.ace = new org.apache.airavata.model.error.AiravataClientException(other.ace);
      }
      if (other.isSetAse()) {
        this.ase = new org.apache.airavata.model.error.AiravataSystemException(other.ase);
      }
      if (other.isSetAe()) {
        this.ae = new org.apache.airavata.model.error.AuthorizationException(other.ae);
      }
    }

    public getAllApplicationInterfaces_result deepCopy() {
      return new getAllApplicationInterfaces_result(this);
    }

    @Override
    public void clear() {
      this.success = null;
      this.ire = null;
      this.ace = null;
      this.ase = null;
      this.ae = null;
    }

    public int getSuccessSize() {
      return (this.success == null) ? 0 : this.success.size();
    }

    public java.util.Iterator<org.apache.airavata.model.appcatalog.appinterface.ApplicationInterfaceDescription> getSuccessIterator() {
      return (this.success == null) ? null : this.success.iterator();
    }

    public void addToSuccess(org.apache.airavata.model.appcatalog.appinterface.ApplicationInterfaceDescription elem) {
      if (this.success == null) {
        this.success = new ArrayList<org.apache.airavata.model.appcatalog.appinterface.ApplicationInterfaceDescription>();
      }
      this.success.add(elem);
    }

    public List<org.apache.airavata.model.appcatalog.appinterface.ApplicationInterfaceDescription> getSuccess() {
      return this.success;
    }

    public getAllApplicationInterfaces_result setSuccess(List<org.apache.airavata.model.appcatalog.appinterface.ApplicationInterfaceDescription> 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.model.error.InvalidRequestException getIre() {
      return this.ire;
    }

    public getAllApplicationInterfaces_result setIre(org.apache.airavata.model.error.InvalidRequestException ire) {
      this.ire = ire;
      return this;
    }

    public void unsetIre() {
      this.ire = null;
    }

    /** Returns true if field ire is set (has been assigned a value) and false otherwise */
    public boolean isSetIre() {
      return this.ire != null;
    }

    public void setIreIsSet(boolean value) {
      if (!value) {
        this.ire = null;
      }
    }

    public org.apache.airavata.model.error.AiravataClientException getAce() {
      return this.ace;
    }

    public getAllApplicationInterfaces_result setAce(org.apache.airavata.model.error.AiravataClientException ace) {
      this.ace = ace;
      return this;
    }

    public void unsetAce() {
      this.ace = null;
    }

    /** Returns true if field ace is set (has been assigned a value) and false otherwise */
    public boolean isSetAce() {
      return this.ace != null;
    }

    public void setAceIsSet(boolean value) {
      if (!value) {
        this.ace = null;
      }
    }

    public org.apache.airavata.model.error.AiravataSystemException getAse() {
      return this.ase;
    }

    public getAllApplicationInterfaces_result setAse(org.apache.airavata.model.error.AiravataSystemException ase) {
      this.ase = ase;
      return this;
    }

    public void unsetAse() {
      this.ase = null;
    }

    /** Returns true if field ase is set (has been assigned a value) and false otherwise */
    public boolean isSetAse() {
      return this.ase != null;
    }

    public void setAseIsSet(boolean value) {
      if (!value) {
        this.ase = null;
      }
    }

    public org.apache.airavata.model.error.AuthorizationException getAe() {
      return this.ae;
    }

    public getAllApplicationInterfaces_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, Object value) {
      switch (field) {
      case SUCCESS:
        if (value == null) {
          unsetSuccess();
        } else {
          setSuccess((List<org.apache.airavata.model.appcatalog.appinterface.ApplicationInterfaceDescription>)value);
        }
        break;

      case IRE:
        if (value == null) {
          unsetIre();
        } else {
          setIre((org.apache.airavata.model.error.InvalidRequestException)value);
        }
        break;

      case ACE:
        if (value == null) {
          unsetAce();
        } else {
          setAce((org.apache.airavata.model.error.AiravataClientException)value);
        }
        break;

      case ASE:
        if (value == null) {
          unsetAse();
        } else {
          setAse((org.apache.airavata.model.error.AiravataSystemException)value);
        }
        break;

      case AE:
        if (value == null) {
          unsetAe();
        } else {
          setAe((org.apache.airavata.model.error.AuthorizationException)value);
        }
        break;

      }
    }

    public Object getFieldValue(_Fields field) {
      switch (field) {
      case SUCCESS:
        return getSuccess();

      case IRE:
        return getIre();

      case ACE:
        return getAce();

      case ASE:
        return getAse();

      case AE:
        return getAe();

      }
      throw new IllegalStateException();
    }

    /** Returns true if field corresponding to fieldID is set (has been assigned a value) and false otherwise */
    public boolean isSet(_Fields field) {
      if (field == null) {
        throw new IllegalArgumentException();
      }

      switch (field) {
      case SUCCESS:
        return isSetSuccess();
      case IRE:
        return isSetIre();
      case ACE:
        return isSetAce();
      case ASE:
        return isSetAse();
      case AE:
        return isSetAe();
      }
      throw new IllegalStateException();
    }

    @Override
    public boolean equals(Object that) {
      if (that == null)
        return false;
      if (that instanceof getAllApplicationInterfaces_result)
        return this.equals((getAllApplicationInterfaces_result)that);
      return false;
    }

    public boolean equals(getAllApplicationInterfaces_result that) {
      if (that == null)
        return false;

      boolean this_present_success = true && this.isSetSuccess();
      boolean that_present_success = true && that.isSetSuccess();
      if (this_present_success || that_present_success) {
        if (!(this_present_success && that_present_success))
          return false;
        if (!this.success.equals(that.success))
          return false;
      }

      boolean this_present_ire = true && this.isSetIre();
      boolean that_present_ire = true && that.isSetIre();
      if (this_present_ire || that_present_ire) {
        if (!(this_present_ire && that_present_ire))
          return false;
        if (!this.ire.equals(that.ire))
          return false;
      }

      boolean this_present_ace = true && this.isSetAce();
      boolean that_present_ace = true && that.isSetAce();
      if (this_present_ace || that_present_ace) {
        if (!(this_present_ace && that_present_ace))
          return false;
        if (!this.ace.equals(that.ace))
          return false;
      }

      boolean this_present_ase = true && this.isSetAse();
      boolean that_present_ase = true && that.isSetAse();
      if (this_present_ase || that_present_ase) {
        if (!(this_present_ase && that_present_ase))
          return false;
        if (!this.ase.equals(that.ase))
          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() {
      List<Object> list = new ArrayList<Object>();

      boolean present_success = true && (isSetSuccess());
      list.add(present_success);
      if (present_success)
        list.add(success);

      boolean present_ire = true && (isSetIre());
      list.add(present_ire);
      if (present_ire)
        list.add(ire);

      boolean present_ace = true && (isSetAce());
      list.add(present_ace);
      if (present_ace)
        list.add(ace);

      boolean present_ase = true && (isSetAse());
      list.add(present_ase);
      if (present_ase)
        list.add(ase);

      boolean present_ae = true && (isSetAe());
      list.add(present_ae);
      if (present_ae)
        list.add(ae);

      return list.hashCode();
    }

    @Override
    public int compareTo(getAllApplicationInterfaces_result other) {
      if (!getClass().equals(other.getClass())) {
        return getClass().getName().compareTo(other.getClass().getName());
      }

      int lastComparison = 0;

      lastComparison = Boolean.valueOf(isSetSuccess()).compareTo(other.isSetSuccess());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetSuccess()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.success, other.success);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = Boolean.valueOf(isSetIre()).compareTo(other.isSetIre());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetIre()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.ire, other.ire);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = Boolean.valueOf(isSetAce()).compareTo(other.isSetAce());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetAce()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.ace, other.ace);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = Boolean.valueOf(isSetAse()).compareTo(other.isSetAse());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetAse()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.ase, other.ase);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = 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 {
      schemes.get(iprot.getScheme()).getScheme().read(iprot, this);
    }

    public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException {
      schemes.get(oprot.getScheme()).getScheme().write(oprot, this);
      }

    @Override
    public String toString() {
      StringBuilder sb = new StringBuilder("getAllApplicationInterfaces_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("ire:");
      if (this.ire == null) {
        sb.append("null");
      } else {
        sb.append(this.ire);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("ace:");
      if (this.ace == null) {
        sb.append("null");
      } else {
        sb.append(this.ace);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("ase:");
      if (this.ase == null) {
        sb.append("null");
      } else {
        sb.append(this.ase);
      }
      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, 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 getAllApplicationInterfaces_resultStandardSchemeFactory implements SchemeFactory {
      public getAllApplicationInterfaces_resultStandardScheme getScheme() {
        return new getAllApplicationInterfaces_resultStandardScheme();
      }
    }

    private static class getAllApplicationInterfaces_resultStandardScheme extends StandardScheme<getAllApplicationInterfaces_result> {

      public void read(org.apache.thrift.protocol.TProtocol iprot, getAllApplicationInterfaces_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 _list184 = iprot.readListBegin();
                  struct.success = new ArrayList<org.apache.airavata.model.appcatalog.appinterface.ApplicationInterfaceDescription>(_list184.size);
                  org.apache.airavata.model.appcatalog.appinterface.ApplicationInterfaceDescription _elem185;
                  for (int _i186 = 0; _i186 < _list184.size; ++_i186)
                  {
                    _elem185 = new org.apache.airavata.model.appcatalog.appinterface.ApplicationInterfaceDescription();
                    _elem185.read(iprot);
                    struct.success.add(_elem185);
                  }
                  iprot.readListEnd();
                }
                struct.setSuccessIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 1: // IRE
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.ire = new org.apache.airavata.model.error.InvalidRequestException();
                struct.ire.read(iprot);
                struct.setIreIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 2: // ACE
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.ace = new org.apache.airavata.model.error.AiravataClientException();
                struct.ace.read(iprot);
                struct.setAceIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 3: // ASE
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.ase = new org.apache.airavata.model.error.AiravataSystemException();
                struct.ase.read(iprot);
                struct.setAseIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 4: // 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, getAllApplicationInterfaces_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.appcatalog.appinterface.ApplicationInterfaceDescription _iter187 : struct.success)
            {
              _iter187.write(oprot);
            }
            oprot.writeListEnd();
          }
          oprot.writeFieldEnd();
        }
        if (struct.ire != null) {
          oprot.writeFieldBegin(IRE_FIELD_DESC);
          struct.ire.write(oprot);
          oprot.writeFieldEnd();
        }
        if (struct.ace != null) {
          oprot.writeFieldBegin(ACE_FIELD_DESC);
          struct.ace.write(oprot);
          oprot.writeFieldEnd();
        }
        if (struct.ase != null) {
          oprot.writeFieldBegin(ASE_FIELD_DESC);
          struct.ase.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 getAllApplicationInterfaces_resultTupleSchemeFactory implements SchemeFactory {
      public getAllApplicationInterfaces_resultTupleScheme getScheme() {
        return new getAllApplicationInterfaces_resultTupleScheme();
      }
    }

    private static class getAllApplicationInterfaces_resultTupleScheme extends TupleScheme<getAllApplicationInterfaces_result> {

      @Override
      public void write(org.apache.thrift.protocol.TProtocol prot, getAllApplicationInterfaces_result struct) throws org.apache.thrift.TException {
        TTupleProtocol oprot = (TTupleProtocol) prot;
        BitSet optionals = new BitSet();
        if (struct.isSetSuccess()) {
          optionals.set(0);
        }
        if (struct.isSetIre()) {
          optionals.set(1);
        }
        if (struct.isSetAce()) {
          optionals.set(2);
        }
        if (struct.isSetAse()) {
          optionals.set(3);
        }
        if (struct.isSetAe()) {
          optionals.set(4);
        }
        oprot.writeBitSet(optionals, 5);
        if (struct.isSetSuccess()) {
          {
            oprot.writeI32(struct.success.size());
            for (org.apache.airavata.model.appcatalog.appinterface.ApplicationInterfaceDescription _iter188 : struct.success)
            {
              _iter188.write(oprot);
            }
          }
        }
        if (struct.isSetIre()) {
          struct.ire.write(oprot);
        }
        if (struct.isSetAce()) {
          struct.ace.write(oprot);
        }
        if (struct.isSetAse()) {
          struct.ase.write(oprot);
        }
        if (struct.isSetAe()) {
          struct.ae.write(oprot);
        }
      }

      @Override
      public void read(org.apache.thrift.protocol.TProtocol prot, getAllApplicationInterfaces_result struct) throws org.apache.thrift.TException {
        TTupleProtocol iprot = (TTupleProtocol) prot;
        BitSet incoming = iprot.readBitSet(5);
        if (incoming.get(0)) {
          {
            org.apache.thrift.protocol.TList _list189 = new org.apache.thrift.protocol.TList(org.apache.thrift.protocol.TType.STRUCT, iprot.readI32());
            struct.success = new ArrayList<org.apache.airavata.model.appcatalog.appinterface.ApplicationInterfaceDescription>(_list189.size);
            org.apache.airavata.model.appcatalog.appinterface.ApplicationInterfaceDescription _elem190;
            for (int _i191 = 0; _i191 < _list189.size; ++_i191)
            {
              _elem190 = new org.apache.airavata.model.appcatalog.appinterface.ApplicationInterfaceDescription();
              _elem190.read(iprot);
              struct.success.add(_elem190);
            }
          }
          struct.setSuccessIsSet(true);
        }
        if (incoming.get(1)) {
          struct.ire = new org.apache.airavata.model.error.InvalidRequestException();
          struct.ire.read(iprot);
          struct.setIreIsSet(true);
        }
        if (incoming.get(2)) {
          struct.ace = new org.apache.airavata.model.error.AiravataClientException();
          struct.ace.read(iprot);
          struct.setAceIsSet(true);
        }
        if (incoming.get(3)) {
          struct.ase = new org.apache.airavata.model.error.AiravataSystemException();
          struct.ase.read(iprot);
          struct.setAseIsSet(true);
        }
        if (incoming.get(4)) {
          struct.ae = new org.apache.airavata.model.error.AuthorizationException();
          struct.ae.read(iprot);
          struct.setAeIsSet(true);
        }
      }
    }

  }

  public static class getApplicationInputs_args implements org.apache.thrift.TBase<getApplicationInputs_args, getApplicationInputs_args._Fields>, java.io.Serializable, Cloneable, Comparable<getApplicationInputs_args>   {
    private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("getApplicationInputs_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 APP_INTERFACE_ID_FIELD_DESC = new org.apache.thrift.protocol.TField("appInterfaceId", org.apache.thrift.protocol.TType.STRING, (short)2);

    private static final Map<Class<? extends IScheme>, SchemeFactory> schemes = new HashMap<Class<? extends IScheme>, SchemeFactory>();
    static {
      schemes.put(StandardScheme.class, new getApplicationInputs_argsStandardSchemeFactory());
      schemes.put(TupleScheme.class, new getApplicationInputs_argsTupleSchemeFactory());
    }

    public org.apache.airavata.model.security.AuthzToken authzToken; // required
    public String appInterfaceId; // required

    /** 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"),
      APP_INTERFACE_ID((short)2, "appInterfaceId");

      private static final Map<String, _Fields> byName = new HashMap<String, _Fields>();

      static {
        for (_Fields field : EnumSet.allOf(_Fields.class)) {
          byName.put(field.getFieldName(), field);
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, or null if its not found.
       */
      public static _Fields findByThriftId(int fieldId) {
        switch(fieldId) {
          case 1: // AUTHZ_TOKEN
            return AUTHZ_TOKEN;
          case 2: // APP_INTERFACE_ID
            return APP_INTERFACE_ID;
          default:
            return null;
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, throwing an exception
       * if it is not found.
       */
      public static _Fields findByThriftIdOrThrow(int fieldId) {
        _Fields fields = findByThriftId(fieldId);
        if (fields == null) throw new IllegalArgumentException("Field " + fieldId + " doesn't exist!");
        return fields;
      }

      /**
       * Find the _Fields constant that matches name, or null if its not found.
       */
      public static _Fields findByName(String name) {
        return byName.get(name);
      }

      private final short _thriftId;
      private final String _fieldName;

      _Fields(short thriftId, String fieldName) {
        _thriftId = thriftId;
        _fieldName = fieldName;
      }

      public short getThriftFieldId() {
        return _thriftId;
      }

      public String getFieldName() {
        return _fieldName;
      }
    }

    // isset id assignments
    public static final Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
    static {
      Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new EnumMap<_Fields, org.apache.thrift.meta_data.FieldMetaData>(_Fields.class);
      tmpMap.put(_Fields.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.APP_INTERFACE_ID, new org.apache.thrift.meta_data.FieldMetaData("appInterfaceId", org.apache.thrift.TFieldRequirementType.REQUIRED, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING)));
      metaDataMap = Collections.unmodifiableMap(tmpMap);
      org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(getApplicationInputs_args.class, metaDataMap);
    }

    public getApplicationInputs_args() {
    }

    public getApplicationInputs_args(
      org.apache.airavata.model.security.AuthzToken authzToken,
      String appInterfaceId)
    {
      this();
      this.authzToken = authzToken;
      this.appInterfaceId = appInterfaceId;
    }

    /**
     * Performs a deep copy on <i>other</i>.
     */
    public getApplicationInputs_args(getApplicationInputs_args other) {
      if (other.isSetAuthzToken()) {
        this.authzToken = new org.apache.airavata.model.security.AuthzToken(other.authzToken);
      }
      if (other.isSetAppInterfaceId()) {
        this.appInterfaceId = other.appInterfaceId;
      }
    }

    public getApplicationInputs_args deepCopy() {
      return new getApplicationInputs_args(this);
    }

    @Override
    public void clear() {
      this.authzToken = null;
      this.appInterfaceId = null;
    }

    public org.apache.airavata.model.security.AuthzToken getAuthzToken() {
      return this.authzToken;
    }

    public getApplicationInputs_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 String getAppInterfaceId() {
      return this.appInterfaceId;
    }

    public getApplicationInputs_args setAppInterfaceId(String appInterfaceId) {
      this.appInterfaceId = appInterfaceId;
      return this;
    }

    public void unsetAppInterfaceId() {
      this.appInterfaceId = null;
    }

    /** Returns true if field appInterfaceId is set (has been assigned a value) and false otherwise */
    public boolean isSetAppInterfaceId() {
      return this.appInterfaceId != null;
    }

    public void setAppInterfaceIdIsSet(boolean value) {
      if (!value) {
        this.appInterfaceId = null;
      }
    }

    public void setFieldValue(_Fields field, Object value) {
      switch (field) {
      case AUTHZ_TOKEN:
        if (value == null) {
          unsetAuthzToken();
        } else {
          setAuthzToken((org.apache.airavata.model.security.AuthzToken)value);
        }
        break;

      case APP_INTERFACE_ID:
        if (value == null) {
          unsetAppInterfaceId();
        } else {
          setAppInterfaceId((String)value);
        }
        break;

      }
    }

    public Object getFieldValue(_Fields field) {
      switch (field) {
      case AUTHZ_TOKEN:
        return getAuthzToken();

      case APP_INTERFACE_ID:
        return getAppInterfaceId();

      }
      throw new IllegalStateException();
    }

    /** Returns true if field corresponding to fieldID is set (has been assigned a value) and false otherwise */
    public boolean isSet(_Fields field) {
      if (field == null) {
        throw new IllegalArgumentException();
      }

      switch (field) {
      case AUTHZ_TOKEN:
        return isSetAuthzToken();
      case APP_INTERFACE_ID:
        return isSetAppInterfaceId();
      }
      throw new IllegalStateException();
    }

    @Override
    public boolean equals(Object that) {
      if (that == null)
        return false;
      if (that instanceof getApplicationInputs_args)
        return this.equals((getApplicationInputs_args)that);
      return false;
    }

    public boolean equals(getApplicationInputs_args that) {
      if (that == null)
        return false;

      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_appInterfaceId = true && this.isSetAppInterfaceId();
      boolean that_present_appInterfaceId = true && that.isSetAppInterfaceId();
      if (this_present_appInterfaceId || that_present_appInterfaceId) {
        if (!(this_present_appInterfaceId && that_present_appInterfaceId))
          return false;
        if (!this.appInterfaceId.equals(that.appInterfaceId))
          return false;
      }

      return true;
    }

    @Override
    public int hashCode() {
      List<Object> list = new ArrayList<Object>();

      boolean present_authzToken = true && (isSetAuthzToken());
      list.add(present_authzToken);
      if (present_authzToken)
        list.add(authzToken);

      boolean present_appInterfaceId = true && (isSetAppInterfaceId());
      list.add(present_appInterfaceId);
      if (present_appInterfaceId)
        list.add(appInterfaceId);

      return list.hashCode();
    }

    @Override
    public int compareTo(getApplicationInputs_args other) {
      if (!getClass().equals(other.getClass())) {
        return getClass().getName().compareTo(other.getClass().getName());
      }

      int lastComparison = 0;

      lastComparison = 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 = Boolean.valueOf(isSetAppInterfaceId()).compareTo(other.isSetAppInterfaceId());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetAppInterfaceId()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.appInterfaceId, other.appInterfaceId);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      return 0;
    }

    public _Fields fieldForId(int fieldId) {
      return _Fields.findByThriftId(fieldId);
    }

    public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
      schemes.get(iprot.getScheme()).getScheme().read(iprot, this);
    }

    public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException {
      schemes.get(oprot.getScheme()).getScheme().write(oprot, this);
    }

    @Override
    public String toString() {
      StringBuilder sb = new StringBuilder("getApplicationInputs_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("appInterfaceId:");
      if (this.appInterfaceId == null) {
        sb.append("null");
      } else {
        sb.append(this.appInterfaceId);
      }
      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 (appInterfaceId == null) {
        throw new org.apache.thrift.protocol.TProtocolException("Required field 'appInterfaceId' 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, 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 getApplicationInputs_argsStandardSchemeFactory implements SchemeFactory {
      public getApplicationInputs_argsStandardScheme getScheme() {
        return new getApplicationInputs_argsStandardScheme();
      }
    }

    private static class getApplicationInputs_argsStandardScheme extends StandardScheme<getApplicationInputs_args> {

      public void read(org.apache.thrift.protocol.TProtocol iprot, getApplicationInputs_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: // APP_INTERFACE_ID
              if (schemeField.type == org.apache.thrift.protocol.TType.STRING) {
                struct.appInterfaceId = iprot.readString();
                struct.setAppInterfaceIdIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            default:
              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
          }
          iprot.readFieldEnd();
        }
        iprot.readStructEnd();

        // check for required fields of primitive type, which can't be checked in the validate method
        struct.validate();
      }

      public void write(org.apache.thrift.protocol.TProtocol oprot, getApplicationInputs_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.appInterfaceId != null) {
          oprot.writeFieldBegin(APP_INTERFACE_ID_FIELD_DESC);
          oprot.writeString(struct.appInterfaceId);
          oprot.writeFieldEnd();
        }
        oprot.writeFieldStop();
        oprot.writeStructEnd();
      }

    }

    private static class getApplicationInputs_argsTupleSchemeFactory implements SchemeFactory {
      public getApplicationInputs_argsTupleScheme getScheme() {
        return new getApplicationInputs_argsTupleScheme();
      }
    }

    private static class getApplicationInputs_argsTupleScheme extends TupleScheme<getApplicationInputs_args> {

      @Override
      public void write(org.apache.thrift.protocol.TProtocol prot, getApplicationInputs_args struct) throws org.apache.thrift.TException {
        TTupleProtocol oprot = (TTupleProtocol) prot;
        struct.authzToken.write(oprot);
        oprot.writeString(struct.appInterfaceId);
      }

      @Override
      public void read(org.apache.thrift.protocol.TProtocol prot, getApplicationInputs_args struct) throws org.apache.thrift.TException {
        TTupleProtocol iprot = (TTupleProtocol) prot;
        struct.authzToken = new org.apache.airavata.model.security.AuthzToken();
        struct.authzToken.read(iprot);
        struct.setAuthzTokenIsSet(true);
        struct.appInterfaceId = iprot.readString();
        struct.setAppInterfaceIdIsSet(true);
      }
    }

  }

  public static class getApplicationInputs_result implements org.apache.thrift.TBase<getApplicationInputs_result, getApplicationInputs_result._Fields>, java.io.Serializable, Cloneable, Comparable<getApplicationInputs_result>   {
    private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("getApplicationInputs_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 IRE_FIELD_DESC = new org.apache.thrift.protocol.TField("ire", org.apache.thrift.protocol.TType.STRUCT, (short)1);
    private static final org.apache.thrift.protocol.TField ACE_FIELD_DESC = new org.apache.thrift.protocol.TField("ace", org.apache.thrift.protocol.TType.STRUCT, (short)2);
    private static final org.apache.thrift.protocol.TField ASE_FIELD_DESC = new org.apache.thrift.protocol.TField("ase", org.apache.thrift.protocol.TType.STRUCT, (short)3);
    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)4);

    private static final Map<Class<? extends IScheme>, SchemeFactory> schemes = new HashMap<Class<? extends IScheme>, SchemeFactory>();
    static {
      schemes.put(StandardScheme.class, new getApplicationInputs_resultStandardSchemeFactory());
      schemes.put(TupleScheme.class, new getApplicationInputs_resultTupleSchemeFactory());
    }

    public List<org.apache.airavata.model.application.io.InputDataObjectType> success; // required
    public org.apache.airavata.model.error.InvalidRequestException ire; // required
    public org.apache.airavata.model.error.AiravataClientException ace; // required
    public org.apache.airavata.model.error.AiravataSystemException ase; // 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"),
      IRE((short)1, "ire"),
      ACE((short)2, "ace"),
      ASE((short)3, "ase"),
      AE((short)4, "ae");

      private static final Map<String, _Fields> byName = new HashMap<String, _Fields>();

      static {
        for (_Fields field : EnumSet.allOf(_Fields.class)) {
          byName.put(field.getFieldName(), field);
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, or null if its not found.
       */
      public static _Fields findByThriftId(int fieldId) {
        switch(fieldId) {
          case 0: // SUCCESS
            return SUCCESS;
          case 1: // IRE
            return IRE;
          case 2: // ACE
            return ACE;
          case 3: // ASE
            return ASE;
          case 4: // 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 IllegalArgumentException("Field " + fieldId + " doesn't exist!");
        return fields;
      }

      /**
       * Find the _Fields constant that matches name, or null if its not found.
       */
      public static _Fields findByName(String name) {
        return byName.get(name);
      }

      private final short _thriftId;
      private final String _fieldName;

      _Fields(short thriftId, String fieldName) {
        _thriftId = thriftId;
        _fieldName = fieldName;
      }

      public short getThriftFieldId() {
        return _thriftId;
      }

      public String getFieldName() {
        return _fieldName;
      }
    }

    // isset id assignments
    public static final Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
    static {
      Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new EnumMap<_Fields, org.apache.thrift.meta_data.FieldMetaData>(_Fields.class);
      tmpMap.put(_Fields.SUCCESS, new org.apache.thrift.meta_data.FieldMetaData("success", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.ListMetaData(org.apache.thrift.protocol.TType.LIST, 
              new org.apache.thrift.meta_data.StructMetaData(org.apache.thrift.protocol.TType.STRUCT, org.apache.airavata.model.application.io.InputDataObjectType.class))));
      tmpMap.put(_Fields.IRE, new org.apache.thrift.meta_data.FieldMetaData("ire", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRUCT)));
      tmpMap.put(_Fields.ACE, new org.apache.thrift.meta_data.FieldMetaData("ace", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRUCT)));
      tmpMap.put(_Fields.ASE, new org.apache.thrift.meta_data.FieldMetaData("ase", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRUCT)));
      tmpMap.put(_Fields.AE, new org.apache.thrift.meta_data.FieldMetaData("ae", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRUCT)));
      metaDataMap = Collections.unmodifiableMap(tmpMap);
      org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(getApplicationInputs_result.class, metaDataMap);
    }

    public getApplicationInputs_result() {
    }

    public getApplicationInputs_result(
      List<org.apache.airavata.model.application.io.InputDataObjectType> success,
      org.apache.airavata.model.error.InvalidRequestException ire,
      org.apache.airavata.model.error.AiravataClientException ace,
      org.apache.airavata.model.error.AiravataSystemException ase,
      org.apache.airavata.model.error.AuthorizationException ae)
    {
      this();
      this.success = success;
      this.ire = ire;
      this.ace = ace;
      this.ase = ase;
      this.ae = ae;
    }

    /**
     * Performs a deep copy on <i>other</i>.
     */
    public getApplicationInputs_result(getApplicationInputs_result other) {
      if (other.isSetSuccess()) {
        List<org.apache.airavata.model.application.io.InputDataObjectType> __this__success = new ArrayList<org.apache.airavata.model.application.io.InputDataObjectType>(other.success.size());
        for (org.apache.airavata.model.application.io.InputDataObjectType other_element : other.success) {
          __this__success.add(new org.apache.airavata.model.application.io.InputDataObjectType(other_element));
        }
        this.success = __this__success;
      }
      if (other.isSetIre()) {
        this.ire = new org.apache.airavata.model.error.InvalidRequestException(other.ire);
      }
      if (other.isSetAce()) {
        this.ace = new org.apache.airavata.model.error.AiravataClientException(other.ace);
      }
      if (other.isSetAse()) {
        this.ase = new org.apache.airavata.model.error.AiravataSystemException(other.ase);
      }
      if (other.isSetAe()) {
        this.ae = new org.apache.airavata.model.error.AuthorizationException(other.ae);
      }
    }

    public getApplicationInputs_result deepCopy() {
      return new getApplicationInputs_result(this);
    }

    @Override
    public void clear() {
      this.success = null;
      this.ire = null;
      this.ace = null;
      this.ase = null;
      this.ae = null;
    }

    public int getSuccessSize() {
      return (this.success == null) ? 0 : this.success.size();
    }

    public java.util.Iterator<org.apache.airavata.model.application.io.InputDataObjectType> getSuccessIterator() {
      return (this.success == null) ? null : this.success.iterator();
    }

    public void addToSuccess(org.apache.airavata.model.application.io.InputDataObjectType elem) {
      if (this.success == null) {
        this.success = new ArrayList<org.apache.airavata.model.application.io.InputDataObjectType>();
      }
      this.success.add(elem);
    }

    public List<org.apache.airavata.model.application.io.InputDataObjectType> getSuccess() {
      return this.success;
    }

    public getApplicationInputs_result setSuccess(List<org.apache.airavata.model.application.io.InputDataObjectType> 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.model.error.InvalidRequestException getIre() {
      return this.ire;
    }

    public getApplicationInputs_result setIre(org.apache.airavata.model.error.InvalidRequestException ire) {
      this.ire = ire;
      return this;
    }

    public void unsetIre() {
      this.ire = null;
    }

    /** Returns true if field ire is set (has been assigned a value) and false otherwise */
    public boolean isSetIre() {
      return this.ire != null;
    }

    public void setIreIsSet(boolean value) {
      if (!value) {
        this.ire = null;
      }
    }

    public org.apache.airavata.model.error.AiravataClientException getAce() {
      return this.ace;
    }

    public getApplicationInputs_result setAce(org.apache.airavata.model.error.AiravataClientException ace) {
      this.ace = ace;
      return this;
    }

    public void unsetAce() {
      this.ace = null;
    }

    /** Returns true if field ace is set (has been assigned a value) and false otherwise */
    public boolean isSetAce() {
      return this.ace != null;
    }

    public void setAceIsSet(boolean value) {
      if (!value) {
        this.ace = null;
      }
    }

    public org.apache.airavata.model.error.AiravataSystemException getAse() {
      return this.ase;
    }

    public getApplicationInputs_result setAse(org.apache.airavata.model.error.AiravataSystemException ase) {
      this.ase = ase;
      return this;
    }

    public void unsetAse() {
      this.ase = null;
    }

    /** Returns true if field ase is set (has been assigned a value) and false otherwise */
    public boolean isSetAse() {
      return this.ase != null;
    }

    public void setAseIsSet(boolean value) {
      if (!value) {
        this.ase = null;
      }
    }

    public org.apache.airavata.model.error.AuthorizationException getAe() {
      return this.ae;
    }

    public getApplicationInputs_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, Object value) {
      switch (field) {
      case SUCCESS:
        if (value == null) {
          unsetSuccess();
        } else {
          setSuccess((List<org.apache.airavata.model.application.io.InputDataObjectType>)value);
        }
        break;

      case IRE:
        if (value == null) {
          unsetIre();
        } else {
          setIre((org.apache.airavata.model.error.InvalidRequestException)value);
        }
        break;

      case ACE:
        if (value == null) {
          unsetAce();
        } else {
          setAce((org.apache.airavata.model.error.AiravataClientException)value);
        }
        break;

      case ASE:
        if (value == null) {
          unsetAse();
        } else {
          setAse((org.apache.airavata.model.error.AiravataSystemException)value);
        }
        break;

      case AE:
        if (value == null) {
          unsetAe();
        } else {
          setAe((org.apache.airavata.model.error.AuthorizationException)value);
        }
        break;

      }
    }

    public Object getFieldValue(_Fields field) {
      switch (field) {
      case SUCCESS:
        return getSuccess();

      case IRE:
        return getIre();

      case ACE:
        return getAce();

      case ASE:
        return getAse();

      case AE:
        return getAe();

      }
      throw new IllegalStateException();
    }

    /** Returns true if field corresponding to fieldID is set (has been assigned a value) and false otherwise */
    public boolean isSet(_Fields field) {
      if (field == null) {
        throw new IllegalArgumentException();
      }

      switch (field) {
      case SUCCESS:
        return isSetSuccess();
      case IRE:
        return isSetIre();
      case ACE:
        return isSetAce();
      case ASE:
        return isSetAse();
      case AE:
        return isSetAe();
      }
      throw new IllegalStateException();
    }

    @Override
    public boolean equals(Object that) {
      if (that == null)
        return false;
      if (that instanceof getApplicationInputs_result)
        return this.equals((getApplicationInputs_result)that);
      return false;
    }

    public boolean equals(getApplicationInputs_result that) {
      if (that == null)
        return false;

      boolean this_present_success = true && this.isSetSuccess();
      boolean that_present_success = true && that.isSetSuccess();
      if (this_present_success || that_present_success) {
        if (!(this_present_success && that_present_success))
          return false;
        if (!this.success.equals(that.success))
          return false;
      }

      boolean this_present_ire = true && this.isSetIre();
      boolean that_present_ire = true && that.isSetIre();
      if (this_present_ire || that_present_ire) {
        if (!(this_present_ire && that_present_ire))
          return false;
        if (!this.ire.equals(that.ire))
          return false;
      }

      boolean this_present_ace = true && this.isSetAce();
      boolean that_present_ace = true && that.isSetAce();
      if (this_present_ace || that_present_ace) {
        if (!(this_present_ace && that_present_ace))
          return false;
        if (!this.ace.equals(that.ace))
          return false;
      }

      boolean this_present_ase = true && this.isSetAse();
      boolean that_present_ase = true && that.isSetAse();
      if (this_present_ase || that_present_ase) {
        if (!(this_present_ase && that_present_ase))
          return false;
        if (!this.ase.equals(that.ase))
          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() {
      List<Object> list = new ArrayList<Object>();

      boolean present_success = true && (isSetSuccess());
      list.add(present_success);
      if (present_success)
        list.add(success);

      boolean present_ire = true && (isSetIre());
      list.add(present_ire);
      if (present_ire)
        list.add(ire);

      boolean present_ace = true && (isSetAce());
      list.add(present_ace);
      if (present_ace)
        list.add(ace);

      boolean present_ase = true && (isSetAse());
      list.add(present_ase);
      if (present_ase)
        list.add(ase);

      boolean present_ae = true && (isSetAe());
      list.add(present_ae);
      if (present_ae)
        list.add(ae);

      return list.hashCode();
    }

    @Override
    public int compareTo(getApplicationInputs_result other) {
      if (!getClass().equals(other.getClass())) {
        return getClass().getName().compareTo(other.getClass().getName());
      }

      int lastComparison = 0;

      lastComparison = Boolean.valueOf(isSetSuccess()).compareTo(other.isSetSuccess());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetSuccess()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.success, other.success);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = Boolean.valueOf(isSetIre()).compareTo(other.isSetIre());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetIre()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.ire, other.ire);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = Boolean.valueOf(isSetAce()).compareTo(other.isSetAce());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetAce()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.ace, other.ace);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = Boolean.valueOf(isSetAse()).compareTo(other.isSetAse());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetAse()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.ase, other.ase);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = 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 {
      schemes.get(iprot.getScheme()).getScheme().read(iprot, this);
    }

    public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException {
      schemes.get(oprot.getScheme()).getScheme().write(oprot, this);
      }

    @Override
    public String toString() {
      StringBuilder sb = new StringBuilder("getApplicationInputs_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("ire:");
      if (this.ire == null) {
        sb.append("null");
      } else {
        sb.append(this.ire);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("ace:");
      if (this.ace == null) {
        sb.append("null");
      } else {
        sb.append(this.ace);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("ase:");
      if (this.ase == null) {
        sb.append("null");
      } else {
        sb.append(this.ase);
      }
      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, 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 getApplicationInputs_resultStandardSchemeFactory implements SchemeFactory {
      public getApplicationInputs_resultStandardScheme getScheme() {
        return new getApplicationInputs_resultStandardScheme();
      }
    }

    private static class getApplicationInputs_resultStandardScheme extends StandardScheme<getApplicationInputs_result> {

      public void read(org.apache.thrift.protocol.TProtocol iprot, getApplicationInputs_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 _list192 = iprot.readListBegin();
                  struct.success = new ArrayList<org.apache.airavata.model.application.io.InputDataObjectType>(_list192.size);
                  org.apache.airavata.model.application.io.InputDataObjectType _elem193;
                  for (int _i194 = 0; _i194 < _list192.size; ++_i194)
                  {
                    _elem193 = new org.apache.airavata.model.application.io.InputDataObjectType();
                    _elem193.read(iprot);
                    struct.success.add(_elem193);
                  }
                  iprot.readListEnd();
                }
                struct.setSuccessIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 1: // IRE
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.ire = new org.apache.airavata.model.error.InvalidRequestException();
                struct.ire.read(iprot);
                struct.setIreIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 2: // ACE
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.ace = new org.apache.airavata.model.error.AiravataClientException();
                struct.ace.read(iprot);
                struct.setAceIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 3: // ASE
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.ase = new org.apache.airavata.model.error.AiravataSystemException();
                struct.ase.read(iprot);
                struct.setAseIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 4: // 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, getApplicationInputs_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.application.io.InputDataObjectType _iter195 : struct.success)
            {
              _iter195.write(oprot);
            }
            oprot.writeListEnd();
          }
          oprot.writeFieldEnd();
        }
        if (struct.ire != null) {
          oprot.writeFieldBegin(IRE_FIELD_DESC);
          struct.ire.write(oprot);
          oprot.writeFieldEnd();
        }
        if (struct.ace != null) {
          oprot.writeFieldBegin(ACE_FIELD_DESC);
          struct.ace.write(oprot);
          oprot.writeFieldEnd();
        }
        if (struct.ase != null) {
          oprot.writeFieldBegin(ASE_FIELD_DESC);
          struct.ase.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 getApplicationInputs_resultTupleSchemeFactory implements SchemeFactory {
      public getApplicationInputs_resultTupleScheme getScheme() {
        return new getApplicationInputs_resultTupleScheme();
      }
    }

    private static class getApplicationInputs_resultTupleScheme extends TupleScheme<getApplicationInputs_result> {

      @Override
      public void write(org.apache.thrift.protocol.TProtocol prot, getApplicationInputs_result struct) throws org.apache.thrift.TException {
        TTupleProtocol oprot = (TTupleProtocol) prot;
        BitSet optionals = new BitSet();
        if (struct.isSetSuccess()) {
          optionals.set(0);
        }
        if (struct.isSetIre()) {
          optionals.set(1);
        }
        if (struct.isSetAce()) {
          optionals.set(2);
        }
        if (struct.isSetAse()) {
          optionals.set(3);
        }
        if (struct.isSetAe()) {
          optionals.set(4);
        }
        oprot.writeBitSet(optionals, 5);
        if (struct.isSetSuccess()) {
          {
            oprot.writeI32(struct.success.size());
            for (org.apache.airavata.model.application.io.InputDataObjectType _iter196 : struct.success)
            {
              _iter196.write(oprot);
            }
          }
        }
        if (struct.isSetIre()) {
          struct.ire.write(oprot);
        }
        if (struct.isSetAce()) {
          struct.ace.write(oprot);
        }
        if (struct.isSetAse()) {
          struct.ase.write(oprot);
        }
        if (struct.isSetAe()) {
          struct.ae.write(oprot);
        }
      }

      @Override
      public void read(org.apache.thrift.protocol.TProtocol prot, getApplicationInputs_result struct) throws org.apache.thrift.TException {
        TTupleProtocol iprot = (TTupleProtocol) prot;
        BitSet incoming = iprot.readBitSet(5);
        if (incoming.get(0)) {
          {
            org.apache.thrift.protocol.TList _list197 = new org.apache.thrift.protocol.TList(org.apache.thrift.protocol.TType.STRUCT, iprot.readI32());
            struct.success = new ArrayList<org.apache.airavata.model.application.io.InputDataObjectType>(_list197.size);
            org.apache.airavata.model.application.io.InputDataObjectType _elem198;
            for (int _i199 = 0; _i199 < _list197.size; ++_i199)
            {
              _elem198 = new org.apache.airavata.model.application.io.InputDataObjectType();
              _elem198.read(iprot);
              struct.success.add(_elem198);
            }
          }
          struct.setSuccessIsSet(true);
        }
        if (incoming.get(1)) {
          struct.ire = new org.apache.airavata.model.error.InvalidRequestException();
          struct.ire.read(iprot);
          struct.setIreIsSet(true);
        }
        if (incoming.get(2)) {
          struct.ace = new org.apache.airavata.model.error.AiravataClientException();
          struct.ace.read(iprot);
          struct.setAceIsSet(true);
        }
        if (incoming.get(3)) {
          struct.ase = new org.apache.airavata.model.error.AiravataSystemException();
          struct.ase.read(iprot);
          struct.setAseIsSet(true);
        }
        if (incoming.get(4)) {
          struct.ae = new org.apache.airavata.model.error.AuthorizationException();
          struct.ae.read(iprot);
          struct.setAeIsSet(true);
        }
      }
    }

  }

  public static class getApplicationOutputs_args implements org.apache.thrift.TBase<getApplicationOutputs_args, getApplicationOutputs_args._Fields>, java.io.Serializable, Cloneable, Comparable<getApplicationOutputs_args>   {
    private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("getApplicationOutputs_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 APP_INTERFACE_ID_FIELD_DESC = new org.apache.thrift.protocol.TField("appInterfaceId", org.apache.thrift.protocol.TType.STRING, (short)2);

    private static final Map<Class<? extends IScheme>, SchemeFactory> schemes = new HashMap<Class<? extends IScheme>, SchemeFactory>();
    static {
      schemes.put(StandardScheme.class, new getApplicationOutputs_argsStandardSchemeFactory());
      schemes.put(TupleScheme.class, new getApplicationOutputs_argsTupleSchemeFactory());
    }

    public org.apache.airavata.model.security.AuthzToken authzToken; // required
    public String appInterfaceId; // required

    /** 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"),
      APP_INTERFACE_ID((short)2, "appInterfaceId");

      private static final Map<String, _Fields> byName = new HashMap<String, _Fields>();

      static {
        for (_Fields field : EnumSet.allOf(_Fields.class)) {
          byName.put(field.getFieldName(), field);
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, or null if its not found.
       */
      public static _Fields findByThriftId(int fieldId) {
        switch(fieldId) {
          case 1: // AUTHZ_TOKEN
            return AUTHZ_TOKEN;
          case 2: // APP_INTERFACE_ID
            return APP_INTERFACE_ID;
          default:
            return null;
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, throwing an exception
       * if it is not found.
       */
      public static _Fields findByThriftIdOrThrow(int fieldId) {
        _Fields fields = findByThriftId(fieldId);
        if (fields == null) throw new IllegalArgumentException("Field " + fieldId + " doesn't exist!");
        return fields;
      }

      /**
       * Find the _Fields constant that matches name, or null if its not found.
       */
      public static _Fields findByName(String name) {
        return byName.get(name);
      }

      private final short _thriftId;
      private final String _fieldName;

      _Fields(short thriftId, String fieldName) {
        _thriftId = thriftId;
        _fieldName = fieldName;
      }

      public short getThriftFieldId() {
        return _thriftId;
      }

      public String getFieldName() {
        return _fieldName;
      }
    }

    // isset id assignments
    public static final Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
    static {
      Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new EnumMap<_Fields, org.apache.thrift.meta_data.FieldMetaData>(_Fields.class);
      tmpMap.put(_Fields.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.APP_INTERFACE_ID, new org.apache.thrift.meta_data.FieldMetaData("appInterfaceId", org.apache.thrift.TFieldRequirementType.REQUIRED, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING)));
      metaDataMap = Collections.unmodifiableMap(tmpMap);
      org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(getApplicationOutputs_args.class, metaDataMap);
    }

    public getApplicationOutputs_args() {
    }

    public getApplicationOutputs_args(
      org.apache.airavata.model.security.AuthzToken authzToken,
      String appInterfaceId)
    {
      this();
      this.authzToken = authzToken;
      this.appInterfaceId = appInterfaceId;
    }

    /**
     * Performs a deep copy on <i>other</i>.
     */
    public getApplicationOutputs_args(getApplicationOutputs_args other) {
      if (other.isSetAuthzToken()) {
        this.authzToken = new org.apache.airavata.model.security.AuthzToken(other.authzToken);
      }
      if (other.isSetAppInterfaceId()) {
        this.appInterfaceId = other.appInterfaceId;
      }
    }

    public getApplicationOutputs_args deepCopy() {
      return new getApplicationOutputs_args(this);
    }

    @Override
    public void clear() {
      this.authzToken = null;
      this.appInterfaceId = null;
    }

    public org.apache.airavata.model.security.AuthzToken getAuthzToken() {
      return this.authzToken;
    }

    public getApplicationOutputs_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 String getAppInterfaceId() {
      return this.appInterfaceId;
    }

    public getApplicationOutputs_args setAppInterfaceId(String appInterfaceId) {
      this.appInterfaceId = appInterfaceId;
      return this;
    }

    public void unsetAppInterfaceId() {
      this.appInterfaceId = null;
    }

    /** Returns true if field appInterfaceId is set (has been assigned a value) and false otherwise */
    public boolean isSetAppInterfaceId() {
      return this.appInterfaceId != null;
    }

    public void setAppInterfaceIdIsSet(boolean value) {
      if (!value) {
        this.appInterfaceId = null;
      }
    }

    public void setFieldValue(_Fields field, Object value) {
      switch (field) {
      case AUTHZ_TOKEN:
        if (value == null) {
          unsetAuthzToken();
        } else {
          setAuthzToken((org.apache.airavata.model.security.AuthzToken)value);
        }
        break;

      case APP_INTERFACE_ID:
        if (value == null) {
          unsetAppInterfaceId();
        } else {
          setAppInterfaceId((String)value);
        }
        break;

      }
    }

    public Object getFieldValue(_Fields field) {
      switch (field) {
      case AUTHZ_TOKEN:
        return getAuthzToken();

      case APP_INTERFACE_ID:
        return getAppInterfaceId();

      }
      throw new IllegalStateException();
    }

    /** Returns true if field corresponding to fieldID is set (has been assigned a value) and false otherwise */
    public boolean isSet(_Fields field) {
      if (field == null) {
        throw new IllegalArgumentException();
      }

      switch (field) {
      case AUTHZ_TOKEN:
        return isSetAuthzToken();
      case APP_INTERFACE_ID:
        return isSetAppInterfaceId();
      }
      throw new IllegalStateException();
    }

    @Override
    public boolean equals(Object that) {
      if (that == null)
        return false;
      if (that instanceof getApplicationOutputs_args)
        return this.equals((getApplicationOutputs_args)that);
      return false;
    }

    public boolean equals(getApplicationOutputs_args that) {
      if (that == null)
        return false;

      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_appInterfaceId = true && this.isSetAppInterfaceId();
      boolean that_present_appInterfaceId = true && that.isSetAppInterfaceId();
      if (this_present_appInterfaceId || that_present_appInterfaceId) {
        if (!(this_present_appInterfaceId && that_present_appInterfaceId))
          return false;
        if (!this.appInterfaceId.equals(that.appInterfaceId))
          return false;
      }

      return true;
    }

    @Override
    public int hashCode() {
      List<Object> list = new ArrayList<Object>();

      boolean present_authzToken = true && (isSetAuthzToken());
      list.add(present_authzToken);
      if (present_authzToken)
        list.add(authzToken);

      boolean present_appInterfaceId = true && (isSetAppInterfaceId());
      list.add(present_appInterfaceId);
      if (present_appInterfaceId)
        list.add(appInterfaceId);

      return list.hashCode();
    }

    @Override
    public int compareTo(getApplicationOutputs_args other) {
      if (!getClass().equals(other.getClass())) {
        return getClass().getName().compareTo(other.getClass().getName());
      }

      int lastComparison = 0;

      lastComparison = 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 = Boolean.valueOf(isSetAppInterfaceId()).compareTo(other.isSetAppInterfaceId());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetAppInterfaceId()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.appInterfaceId, other.appInterfaceId);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      return 0;
    }

    public _Fields fieldForId(int fieldId) {
      return _Fields.findByThriftId(fieldId);
    }

    public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
      schemes.get(iprot.getScheme()).getScheme().read(iprot, this);
    }

    public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException {
      schemes.get(oprot.getScheme()).getScheme().write(oprot, this);
    }

    @Override
    public String toString() {
      StringBuilder sb = new StringBuilder("getApplicationOutputs_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("appInterfaceId:");
      if (this.appInterfaceId == null) {
        sb.append("null");
      } else {
        sb.append(this.appInterfaceId);
      }
      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 (appInterfaceId == null) {
        throw new org.apache.thrift.protocol.TProtocolException("Required field 'appInterfaceId' 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, 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 getApplicationOutputs_argsStandardSchemeFactory implements SchemeFactory {
      public getApplicationOutputs_argsStandardScheme getScheme() {
        return new getApplicationOutputs_argsStandardScheme();
      }
    }

    private static class getApplicationOutputs_argsStandardScheme extends StandardScheme<getApplicationOutputs_args> {

      public void read(org.apache.thrift.protocol.TProtocol iprot, getApplicationOutputs_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: // APP_INTERFACE_ID
              if (schemeField.type == org.apache.thrift.protocol.TType.STRING) {
                struct.appInterfaceId = iprot.readString();
                struct.setAppInterfaceIdIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            default:
              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
          }
          iprot.readFieldEnd();
        }
        iprot.readStructEnd();

        // check for required fields of primitive type, which can't be checked in the validate method
        struct.validate();
      }

      public void write(org.apache.thrift.protocol.TProtocol oprot, getApplicationOutputs_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.appInterfaceId != null) {
          oprot.writeFieldBegin(APP_INTERFACE_ID_FIELD_DESC);
          oprot.writeString(struct.appInterfaceId);
          oprot.writeFieldEnd();
        }
        oprot.writeFieldStop();
        oprot.writeStructEnd();
      }

    }

    private static class getApplicationOutputs_argsTupleSchemeFactory implements SchemeFactory {
      public getApplicationOutputs_argsTupleScheme getScheme() {
        return new getApplicationOutputs_argsTupleScheme();
      }
    }

    private static class getApplicationOutputs_argsTupleScheme extends TupleScheme<getApplicationOutputs_args> {

      @Override
      public void write(org.apache.thrift.protocol.TProtocol prot, getApplicationOutputs_args struct) throws org.apache.thrift.TException {
        TTupleProtocol oprot = (TTupleProtocol) prot;
        struct.authzToken.write(oprot);
        oprot.writeString(struct.appInterfaceId);
      }

      @Override
      public void read(org.apache.thrift.protocol.TProtocol prot, getApplicationOutputs_args struct) throws org.apache.thrift.TException {
        TTupleProtocol iprot = (TTupleProtocol) prot;
        struct.authzToken = new org.apache.airavata.model.security.AuthzToken();
        struct.authzToken.read(iprot);
        struct.setAuthzTokenIsSet(true);
        struct.appInterfaceId = iprot.readString();
        struct.setAppInterfaceIdIsSet(true);
      }
    }

  }

  public static class getApplicationOutputs_result implements org.apache.thrift.TBase<getApplicationOutputs_result, getApplicationOutputs_result._Fields>, java.io.Serializable, Cloneable, Comparable<getApplicationOutputs_result>   {
    private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("getApplicationOutputs_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 IRE_FIELD_DESC = new org.apache.thrift.protocol.TField("ire", org.apache.thrift.protocol.TType.STRUCT, (short)1);
    private static final org.apache.thrift.protocol.TField ACE_FIELD_DESC = new org.apache.thrift.protocol.TField("ace", org.apache.thrift.protocol.TType.STRUCT, (short)2);
    private static final org.apache.thrift.protocol.TField ASE_FIELD_DESC = new org.apache.thrift.protocol.TField("ase", org.apache.thrift.protocol.TType.STRUCT, (short)3);
    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)4);

    private static final Map<Class<? extends IScheme>, SchemeFactory> schemes = new HashMap<Class<? extends IScheme>, SchemeFactory>();
    static {
      schemes.put(StandardScheme.class, new getApplicationOutputs_resultStandardSchemeFactory());
      schemes.put(TupleScheme.class, new getApplicationOutputs_resultTupleSchemeFactory());
    }

    public List<org.apache.airavata.model.application.io.OutputDataObjectType> success; // required
    public org.apache.airavata.model.error.InvalidRequestException ire; // required
    public org.apache.airavata.model.error.AiravataClientException ace; // required
    public org.apache.airavata.model.error.AiravataSystemException ase; // 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"),
      IRE((short)1, "ire"),
      ACE((short)2, "ace"),
      ASE((short)3, "ase"),
      AE((short)4, "ae");

      private static final Map<String, _Fields> byName = new HashMap<String, _Fields>();

      static {
        for (_Fields field : EnumSet.allOf(_Fields.class)) {
          byName.put(field.getFieldName(), field);
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, or null if its not found.
       */
      public static _Fields findByThriftId(int fieldId) {
        switch(fieldId) {
          case 0: // SUCCESS
            return SUCCESS;
          case 1: // IRE
            return IRE;
          case 2: // ACE
            return ACE;
          case 3: // ASE
            return ASE;
          case 4: // 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 IllegalArgumentException("Field " + fieldId + " doesn't exist!");
        return fields;
      }

      /**
       * Find the _Fields constant that matches name, or null if its not found.
       */
      public static _Fields findByName(String name) {
        return byName.get(name);
      }

      private final short _thriftId;
      private final String _fieldName;

      _Fields(short thriftId, String fieldName) {
        _thriftId = thriftId;
        _fieldName = fieldName;
      }

      public short getThriftFieldId() {
        return _thriftId;
      }

      public String getFieldName() {
        return _fieldName;
      }
    }

    // isset id assignments
    public static final Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
    static {
      Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new EnumMap<_Fields, org.apache.thrift.meta_data.FieldMetaData>(_Fields.class);
      tmpMap.put(_Fields.SUCCESS, new org.apache.thrift.meta_data.FieldMetaData("success", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.ListMetaData(org.apache.thrift.protocol.TType.LIST, 
              new org.apache.thrift.meta_data.StructMetaData(org.apache.thrift.protocol.TType.STRUCT, org.apache.airavata.model.application.io.OutputDataObjectType.class))));
      tmpMap.put(_Fields.IRE, new org.apache.thrift.meta_data.FieldMetaData("ire", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRUCT)));
      tmpMap.put(_Fields.ACE, new org.apache.thrift.meta_data.FieldMetaData("ace", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRUCT)));
      tmpMap.put(_Fields.ASE, new org.apache.thrift.meta_data.FieldMetaData("ase", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRUCT)));
      tmpMap.put(_Fields.AE, new org.apache.thrift.meta_data.FieldMetaData("ae", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRUCT)));
      metaDataMap = Collections.unmodifiableMap(tmpMap);
      org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(getApplicationOutputs_result.class, metaDataMap);
    }

    public getApplicationOutputs_result() {
    }

    public getApplicationOutputs_result(
      List<org.apache.airavata.model.application.io.OutputDataObjectType> success,
      org.apache.airavata.model.error.InvalidRequestException ire,
      org.apache.airavata.model.error.AiravataClientException ace,
      org.apache.airavata.model.error.AiravataSystemException ase,
      org.apache.airavata.model.error.AuthorizationException ae)
    {
      this();
      this.success = success;
      this.ire = ire;
      this.ace = ace;
      this.ase = ase;
      this.ae = ae;
    }

    /**
     * Performs a deep copy on <i>other</i>.
     */
    public getApplicationOutputs_result(getApplicationOutputs_result other) {
      if (other.isSetSuccess()) {
        List<org.apache.airavata.model.application.io.OutputDataObjectType> __this__success = new ArrayList<org.apache.airavata.model.application.io.OutputDataObjectType>(other.success.size());
        for (org.apache.airavata.model.application.io.OutputDataObjectType other_element : other.success) {
          __this__success.add(new org.apache.airavata.model.application.io.OutputDataObjectType(other_element));
        }
        this.success = __this__success;
      }
      if (other.isSetIre()) {
        this.ire = new org.apache.airavata.model.error.InvalidRequestException(other.ire);
      }
      if (other.isSetAce()) {
        this.ace = new org.apache.airavata.model.error.AiravataClientException(other.ace);
      }
      if (other.isSetAse()) {
        this.ase = new org.apache.airavata.model.error.AiravataSystemException(other.ase);
      }
      if (other.isSetAe()) {
        this.ae = new org.apache.airavata.model.error.AuthorizationException(other.ae);
      }
    }

    public getApplicationOutputs_result deepCopy() {
      return new getApplicationOutputs_result(this);
    }

    @Override
    public void clear() {
      this.success = null;
      this.ire = null;
      this.ace = null;
      this.ase = null;
      this.ae = null;
    }

    public int getSuccessSize() {
      return (this.success == null) ? 0 : this.success.size();
    }

    public java.util.Iterator<org.apache.airavata.model.application.io.OutputDataObjectType> getSuccessIterator() {
      return (this.success == null) ? null : this.success.iterator();
    }

    public void addToSuccess(org.apache.airavata.model.application.io.OutputDataObjectType elem) {
      if (this.success == null) {
        this.success = new ArrayList<org.apache.airavata.model.application.io.OutputDataObjectType>();
      }
      this.success.add(elem);
    }

    public List<org.apache.airavata.model.application.io.OutputDataObjectType> getSuccess() {
      return this.success;
    }

    public getApplicationOutputs_result setSuccess(List<org.apache.airavata.model.application.io.OutputDataObjectType> 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.model.error.InvalidRequestException getIre() {
      return this.ire;
    }

    public getApplicationOutputs_result setIre(org.apache.airavata.model.error.InvalidRequestException ire) {
      this.ire = ire;
      return this;
    }

    public void unsetIre() {
      this.ire = null;
    }

    /** Returns true if field ire is set (has been assigned a value) and false otherwise */
    public boolean isSetIre() {
      return this.ire != null;
    }

    public void setIreIsSet(boolean value) {
      if (!value) {
        this.ire = null;
      }
    }

    public org.apache.airavata.model.error.AiravataClientException getAce() {
      return this.ace;
    }

    public getApplicationOutputs_result setAce(org.apache.airavata.model.error.AiravataClientException ace) {
      this.ace = ace;
      return this;
    }

    public void unsetAce() {
      this.ace = null;
    }

    /** Returns true if field ace is set (has been assigned a value) and false otherwise */
    public boolean isSetAce() {
      return this.ace != null;
    }

    public void setAceIsSet(boolean value) {
      if (!value) {
        this.ace = null;
      }
    }

    public org.apache.airavata.model.error.AiravataSystemException getAse() {
      return this.ase;
    }

    public getApplicationOutputs_result setAse(org.apache.airavata.model.error.AiravataSystemException ase) {
      this.ase = ase;
      return this;
    }

    public void unsetAse() {
      this.ase = null;
    }

    /** Returns true if field ase is set (has been assigned a value) and false otherwise */
    public boolean isSetAse() {
      return this.ase != null;
    }

    public void setAseIsSet(boolean value) {
      if (!value) {
        this.ase = null;
      }
    }

    public org.apache.airavata.model.error.AuthorizationException getAe() {
      return this.ae;
    }

    public getApplicationOutputs_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, Object value) {
      switch (field) {
      case SUCCESS:
        if (value == null) {
          unsetSuccess();
        } else {
          setSuccess((List<org.apache.airavata.model.application.io.OutputDataObjectType>)value);
        }
        break;

      case IRE:
        if (value == null) {
          unsetIre();
        } else {
          setIre((org.apache.airavata.model.error.InvalidRequestException)value);
        }
        break;

      case ACE:
        if (value == null) {
          unsetAce();
        } else {
          setAce((org.apache.airavata.model.error.AiravataClientException)value);
        }
        break;

      case ASE:
        if (value == null) {
          unsetAse();
        } else {
          setAse((org.apache.airavata.model.error.AiravataSystemException)value);
        }
        break;

      case AE:
        if (value == null) {
          unsetAe();
        } else {
          setAe((org.apache.airavata.model.error.AuthorizationException)value);
        }
        break;

      }
    }

    public Object getFieldValue(_Fields field) {
      switch (field) {
      case SUCCESS:
        return getSuccess();

      case IRE:
        return getIre();

      case ACE:
        return getAce();

      case ASE:
        return getAse();

      case AE:
        return getAe();

      }
      throw new IllegalStateException();
    }

    /** Returns true if field corresponding to fieldID is set (has been assigned a value) and false otherwise */
    public boolean isSet(_Fields field) {
      if (field == null) {
        throw new IllegalArgumentException();
      }

      switch (field) {
      case SUCCESS:
        return isSetSuccess();
      case IRE:
        return isSetIre();
      case ACE:
        return isSetAce();
      case ASE:
        return isSetAse();
      case AE:
        return isSetAe();
      }
      throw new IllegalStateException();
    }

    @Override
    public boolean equals(Object that) {
      if (that == null)
        return false;
      if (that instanceof getApplicationOutputs_result)
        return this.equals((getApplicationOutputs_result)that);
      return false;
    }

    public boolean equals(getApplicationOutputs_result that) {
      if (that == null)
        return false;

      boolean this_present_success = true && this.isSetSuccess();
      boolean that_present_success = true && that.isSetSuccess();
      if (this_present_success || that_present_success) {
        if (!(this_present_success && that_present_success))
          return false;
        if (!this.success.equals(that.success))
          return false;
      }

      boolean this_present_ire = true && this.isSetIre();
      boolean that_present_ire = true && that.isSetIre();
      if (this_present_ire || that_present_ire) {
        if (!(this_present_ire && that_present_ire))
          return false;
        if (!this.ire.equals(that.ire))
          return false;
      }

      boolean this_present_ace = true && this.isSetAce();
      boolean that_present_ace = true && that.isSetAce();
      if (this_present_ace || that_present_ace) {
        if (!(this_present_ace && that_present_ace))
          return false;
        if (!this.ace.equals(that.ace))
          return false;
      }

      boolean this_present_ase = true && this.isSetAse();
      boolean that_present_ase = true && that.isSetAse();
      if (this_present_ase || that_present_ase) {
        if (!(this_present_ase && that_present_ase))
          return false;
        if (!this.ase.equals(that.ase))
          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() {
      List<Object> list = new ArrayList<Object>();

      boolean present_success = true && (isSetSuccess());
      list.add(present_success);
      if (present_success)
        list.add(success);

      boolean present_ire = true && (isSetIre());
      list.add(present_ire);
      if (present_ire)
        list.add(ire);

      boolean present_ace = true && (isSetAce());
      list.add(present_ace);
      if (present_ace)
        list.add(ace);

      boolean present_ase = true && (isSetAse());
      list.add(present_ase);
      if (present_ase)
        list.add(ase);

      boolean present_ae = true && (isSetAe());
      list.add(present_ae);
      if (present_ae)
        list.add(ae);

      return list.hashCode();
    }

    @Override
    public int compareTo(getApplicationOutputs_result other) {
      if (!getClass().equals(other.getClass())) {
        return getClass().getName().compareTo(other.getClass().getName());
      }

      int lastComparison = 0;

      lastComparison = Boolean.valueOf(isSetSuccess()).compareTo(other.isSetSuccess());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetSuccess()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.success, other.success);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = Boolean.valueOf(isSetIre()).compareTo(other.isSetIre());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetIre()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.ire, other.ire);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = Boolean.valueOf(isSetAce()).compareTo(other.isSetAce());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetAce()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.ace, other.ace);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = Boolean.valueOf(isSetAse()).compareTo(other.isSetAse());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetAse()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.ase, other.ase);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = 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 {
      schemes.get(iprot.getScheme()).getScheme().read(iprot, this);
    }

    public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException {
      schemes.get(oprot.getScheme()).getScheme().write(oprot, this);
      }

    @Override
    public String toString() {
      StringBuilder sb = new StringBuilder("getApplicationOutputs_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("ire:");
      if (this.ire == null) {
        sb.append("null");
      } else {
        sb.append(this.ire);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("ace:");
      if (this.ace == null) {
        sb.append("null");
      } else {
        sb.append(this.ace);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("ase:");
      if (this.ase == null) {
        sb.append("null");
      } else {
        sb.append(this.ase);
      }
      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, 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 getApplicationOutputs_resultStandardSchemeFactory implements SchemeFactory {
      public getApplicationOutputs_resultStandardScheme getScheme() {
        return new getApplicationOutputs_resultStandardScheme();
      }
    }

    private static class getApplicationOutputs_resultStandardScheme extends StandardScheme<getApplicationOutputs_result> {

      public void read(org.apache.thrift.protocol.TProtocol iprot, getApplicationOutputs_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 _list200 = iprot.readListBegin();
                  struct.success = new ArrayList<org.apache.airavata.model.application.io.OutputDataObjectType>(_list200.size);
                  org.apache.airavata.model.application.io.OutputDataObjectType _elem201;
                  for (int _i202 = 0; _i202 < _list200.size; ++_i202)
                  {
                    _elem201 = new org.apache.airavata.model.application.io.OutputDataObjectType();
                    _elem201.read(iprot);
                    struct.success.add(_elem201);
                  }
                  iprot.readListEnd();
                }
                struct.setSuccessIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 1: // IRE
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.ire = new org.apache.airavata.model.error.InvalidRequestException();
                struct.ire.read(iprot);
                struct.setIreIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 2: // ACE
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.ace = new org.apache.airavata.model.error.AiravataClientException();
                struct.ace.read(iprot);
                struct.setAceIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 3: // ASE
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.ase = new org.apache.airavata.model.error.AiravataSystemException();
                struct.ase.read(iprot);
                struct.setAseIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 4: // 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, getApplicationOutputs_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.application.io.OutputDataObjectType _iter203 : struct.success)
            {
              _iter203.write(oprot);
            }
            oprot.writeListEnd();
          }
          oprot.writeFieldEnd();
        }
        if (struct.ire != null) {
          oprot.writeFieldBegin(IRE_FIELD_DESC);
          struct.ire.write(oprot);
          oprot.writeFieldEnd();
        }
        if (struct.ace != null) {
          oprot.writeFieldBegin(ACE_FIELD_DESC);
          struct.ace.write(oprot);
          oprot.writeFieldEnd();
        }
        if (struct.ase != null) {
          oprot.writeFieldBegin(ASE_FIELD_DESC);
          struct.ase.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 getApplicationOutputs_resultTupleSchemeFactory implements SchemeFactory {
      public getApplicationOutputs_resultTupleScheme getScheme() {
        return new getApplicationOutputs_resultTupleScheme();
      }
    }

    private static class getApplicationOutputs_resultTupleScheme extends TupleScheme<getApplicationOutputs_result> {

      @Override
      public void write(org.apache.thrift.protocol.TProtocol prot, getApplicationOutputs_result struct) throws org.apache.thrift.TException {
        TTupleProtocol oprot = (TTupleProtocol) prot;
        BitSet optionals = new BitSet();
        if (struct.isSetSuccess()) {
          optionals.set(0);
        }
        if (struct.isSetIre()) {
          optionals.set(1);
        }
        if (struct.isSetAce()) {
          optionals.set(2);
        }
        if (struct.isSetAse()) {
          optionals.set(3);
        }
        if (struct.isSetAe()) {
          optionals.set(4);
        }
        oprot.writeBitSet(optionals, 5);
        if (struct.isSetSuccess()) {
          {
            oprot.writeI32(struct.success.size());
            for (org.apache.airavata.model.application.io.OutputDataObjectType _iter204 : struct.success)
            {
              _iter204.write(oprot);
            }
          }
        }
        if (struct.isSetIre()) {
          struct.ire.write(oprot);
        }
        if (struct.isSetAce()) {
          struct.ace.write(oprot);
        }
        if (struct.isSetAse()) {
          struct.ase.write(oprot);
        }
        if (struct.isSetAe()) {
          struct.ae.write(oprot);
        }
      }

      @Override
      public void read(org.apache.thrift.protocol.TProtocol prot, getApplicationOutputs_result struct) throws org.apache.thrift.TException {
        TTupleProtocol iprot = (TTupleProtocol) prot;
        BitSet incoming = iprot.readBitSet(5);
        if (incoming.get(0)) {
          {
            org.apache.thrift.protocol.TList _list205 = new org.apache.thrift.protocol.TList(org.apache.thrift.protocol.TType.STRUCT, iprot.readI32());
            struct.success = new ArrayList<org.apache.airavata.model.application.io.OutputDataObjectType>(_list205.size);
            org.apache.airavata.model.application.io.OutputDataObjectType _elem206;
            for (int _i207 = 0; _i207 < _list205.size; ++_i207)
            {
              _elem206 = new org.apache.airavata.model.application.io.OutputDataObjectType();
              _elem206.read(iprot);
              struct.success.add(_elem206);
            }
          }
          struct.setSuccessIsSet(true);
        }
        if (incoming.get(1)) {
          struct.ire = new org.apache.airavata.model.error.InvalidRequestException();
          struct.ire.read(iprot);
          struct.setIreIsSet(true);
        }
        if (incoming.get(2)) {
          struct.ace = new org.apache.airavata.model.error.AiravataClientException();
          struct.ace.read(iprot);
          struct.setAceIsSet(true);
        }
        if (incoming.get(3)) {
          struct.ase = new org.apache.airavata.model.error.AiravataSystemException();
          struct.ase.read(iprot);
          struct.setAseIsSet(true);
        }
        if (incoming.get(4)) {
          struct.ae = new org.apache.airavata.model.error.AuthorizationException();
          struct.ae.read(iprot);
          struct.setAeIsSet(true);
        }
      }
    }

  }

  public static class getAvailableAppInterfaceComputeResources_args implements org.apache.thrift.TBase<getAvailableAppInterfaceComputeResources_args, getAvailableAppInterfaceComputeResources_args._Fields>, java.io.Serializable, Cloneable, Comparable<getAvailableAppInterfaceComputeResources_args>   {
    private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("getAvailableAppInterfaceComputeResources_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 APP_INTERFACE_ID_FIELD_DESC = new org.apache.thrift.protocol.TField("appInterfaceId", org.apache.thrift.protocol.TType.STRING, (short)2);

    private static final Map<Class<? extends IScheme>, SchemeFactory> schemes = new HashMap<Class<? extends IScheme>, SchemeFactory>();
    static {
      schemes.put(StandardScheme.class, new getAvailableAppInterfaceComputeResources_argsStandardSchemeFactory());
      schemes.put(TupleScheme.class, new getAvailableAppInterfaceComputeResources_argsTupleSchemeFactory());
    }

    public org.apache.airavata.model.security.AuthzToken authzToken; // required
    public String appInterfaceId; // required

    /** 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"),
      APP_INTERFACE_ID((short)2, "appInterfaceId");

      private static final Map<String, _Fields> byName = new HashMap<String, _Fields>();

      static {
        for (_Fields field : EnumSet.allOf(_Fields.class)) {
          byName.put(field.getFieldName(), field);
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, or null if its not found.
       */
      public static _Fields findByThriftId(int fieldId) {
        switch(fieldId) {
          case 1: // AUTHZ_TOKEN
            return AUTHZ_TOKEN;
          case 2: // APP_INTERFACE_ID
            return APP_INTERFACE_ID;
          default:
            return null;
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, throwing an exception
       * if it is not found.
       */
      public static _Fields findByThriftIdOrThrow(int fieldId) {
        _Fields fields = findByThriftId(fieldId);
        if (fields == null) throw new IllegalArgumentException("Field " + fieldId + " doesn't exist!");
        return fields;
      }

      /**
       * Find the _Fields constant that matches name, or null if its not found.
       */
      public static _Fields findByName(String name) {
        return byName.get(name);
      }

      private final short _thriftId;
      private final String _fieldName;

      _Fields(short thriftId, String fieldName) {
        _thriftId = thriftId;
        _fieldName = fieldName;
      }

      public short getThriftFieldId() {
        return _thriftId;
      }

      public String getFieldName() {
        return _fieldName;
      }
    }

    // isset id assignments
    public static final Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
    static {
      Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new EnumMap<_Fields, org.apache.thrift.meta_data.FieldMetaData>(_Fields.class);
      tmpMap.put(_Fields.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.APP_INTERFACE_ID, new org.apache.thrift.meta_data.FieldMetaData("appInterfaceId", org.apache.thrift.TFieldRequirementType.REQUIRED, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING)));
      metaDataMap = Collections.unmodifiableMap(tmpMap);
      org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(getAvailableAppInterfaceComputeResources_args.class, metaDataMap);
    }

    public getAvailableAppInterfaceComputeResources_args() {
    }

    public getAvailableAppInterfaceComputeResources_args(
      org.apache.airavata.model.security.AuthzToken authzToken,
      String appInterfaceId)
    {
      this();
      this.authzToken = authzToken;
      this.appInterfaceId = appInterfaceId;
    }

    /**
     * Performs a deep copy on <i>other</i>.
     */
    public getAvailableAppInterfaceComputeResources_args(getAvailableAppInterfaceComputeResources_args other) {
      if (other.isSetAuthzToken()) {
        this.authzToken = new org.apache.airavata.model.security.AuthzToken(other.authzToken);
      }
      if (other.isSetAppInterfaceId()) {
        this.appInterfaceId = other.appInterfaceId;
      }
    }

    public getAvailableAppInterfaceComputeResources_args deepCopy() {
      return new getAvailableAppInterfaceComputeResources_args(this);
    }

    @Override
    public void clear() {
      this.authzToken = null;
      this.appInterfaceId = null;
    }

    public org.apache.airavata.model.security.AuthzToken getAuthzToken() {
      return this.authzToken;
    }

    public getAvailableAppInterfaceComputeResources_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 String getAppInterfaceId() {
      return this.appInterfaceId;
    }

    public getAvailableAppInterfaceComputeResources_args setAppInterfaceId(String appInterfaceId) {
      this.appInterfaceId = appInterfaceId;
      return this;
    }

    public void unsetAppInterfaceId() {
      this.appInterfaceId = null;
    }

    /** Returns true if field appInterfaceId is set (has been assigned a value) and false otherwise */
    public boolean isSetAppInterfaceId() {
      return this.appInterfaceId != null;
    }

    public void setAppInterfaceIdIsSet(boolean value) {
      if (!value) {
        this.appInterfaceId = null;
      }
    }

    public void setFieldValue(_Fields field, Object value) {
      switch (field) {
      case AUTHZ_TOKEN:
        if (value == null) {
          unsetAuthzToken();
        } else {
          setAuthzToken((org.apache.airavata.model.security.AuthzToken)value);
        }
        break;

      case APP_INTERFACE_ID:
        if (value == null) {
          unsetAppInterfaceId();
        } else {
          setAppInterfaceId((String)value);
        }
        break;

      }
    }

    public Object getFieldValue(_Fields field) {
      switch (field) {
      case AUTHZ_TOKEN:
        return getAuthzToken();

      case APP_INTERFACE_ID:
        return getAppInterfaceId();

      }
      throw new IllegalStateException();
    }

    /** Returns true if field corresponding to fieldID is set (has been assigned a value) and false otherwise */
    public boolean isSet(_Fields field) {
      if (field == null) {
        throw new IllegalArgumentException();
      }

      switch (field) {
      case AUTHZ_TOKEN:
        return isSetAuthzToken();
      case APP_INTERFACE_ID:
        return isSetAppInterfaceId();
      }
      throw new IllegalStateException();
    }

    @Override
    public boolean equals(Object that) {
      if (that == null)
        return false;
      if (that instanceof getAvailableAppInterfaceComputeResources_args)
        return this.equals((getAvailableAppInterfaceComputeResources_args)that);
      return false;
    }

    public boolean equals(getAvailableAppInterfaceComputeResources_args that) {
      if (that == null)
        return false;

      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_appInterfaceId = true && this.isSetAppInterfaceId();
      boolean that_present_appInterfaceId = true && that.isSetAppInterfaceId();
      if (this_present_appInterfaceId || that_present_appInterfaceId) {
        if (!(this_present_appInterfaceId && that_present_appInterfaceId))
          return false;
        if (!this.appInterfaceId.equals(that.appInterfaceId))
          return false;
      }

      return true;
    }

    @Override
    public int hashCode() {
      List<Object> list = new ArrayList<Object>();

      boolean present_authzToken = true && (isSetAuthzToken());
      list.add(present_authzToken);
      if (present_authzToken)
        list.add(authzToken);

      boolean present_appInterfaceId = true && (isSetAppInterfaceId());
      list.add(present_appInterfaceId);
      if (present_appInterfaceId)
        list.add(appInterfaceId);

      return list.hashCode();
    }

    @Override
    public int compareTo(getAvailableAppInterfaceComputeResources_args other) {
      if (!getClass().equals(other.getClass())) {
        return getClass().getName().compareTo(other.getClass().getName());
      }

      int lastComparison = 0;

      lastComparison = 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 = Boolean.valueOf(isSetAppInterfaceId()).compareTo(other.isSetAppInterfaceId());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetAppInterfaceId()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.appInterfaceId, other.appInterfaceId);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      return 0;
    }

    public _Fields fieldForId(int fieldId) {
      return _Fields.findByThriftId(fieldId);
    }

    public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
      schemes.get(iprot.getScheme()).getScheme().read(iprot, this);
    }

    public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException {
      schemes.get(oprot.getScheme()).getScheme().write(oprot, this);
    }

    @Override
    public String toString() {
      StringBuilder sb = new StringBuilder("getAvailableAppInterfaceComputeResources_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("appInterfaceId:");
      if (this.appInterfaceId == null) {
        sb.append("null");
      } else {
        sb.append(this.appInterfaceId);
      }
      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 (appInterfaceId == null) {
        throw new org.apache.thrift.protocol.TProtocolException("Required field 'appInterfaceId' 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, 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 getAvailableAppInterfaceComputeResources_argsStandardSchemeFactory implements SchemeFactory {
      public getAvailableAppInterfaceComputeResources_argsStandardScheme getScheme() {
        return new getAvailableAppInterfaceComputeResources_argsStandardScheme();
      }
    }

    private static class getAvailableAppInterfaceComputeResources_argsStandardScheme extends StandardScheme<getAvailableAppInterfaceComputeResources_args> {

      public void read(org.apache.thrift.protocol.TProtocol iprot, getAvailableAppInterfaceComputeResources_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: // APP_INTERFACE_ID
              if (schemeField.type == org.apache.thrift.protocol.TType.STRING) {
                struct.appInterfaceId = iprot.readString();
                struct.setAppInterfaceIdIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            default:
              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
          }
          iprot.readFieldEnd();
        }
        iprot.readStructEnd();

        // check for required fields of primitive type, which can't be checked in the validate method
        struct.validate();
      }

      public void write(org.apache.thrift.protocol.TProtocol oprot, getAvailableAppInterfaceComputeResources_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.appInterfaceId != null) {
          oprot.writeFieldBegin(APP_INTERFACE_ID_FIELD_DESC);
          oprot.writeString(struct.appInterfaceId);
          oprot.writeFieldEnd();
        }
        oprot.writeFieldStop();
        oprot.writeStructEnd();
      }

    }

    private static class getAvailableAppInterfaceComputeResources_argsTupleSchemeFactory implements SchemeFactory {
      public getAvailableAppInterfaceComputeResources_argsTupleScheme getScheme() {
        return new getAvailableAppInterfaceComputeResources_argsTupleScheme();
      }
    }

    private static class getAvailableAppInterfaceComputeResources_argsTupleScheme extends TupleScheme<getAvailableAppInterfaceComputeResources_args> {

      @Override
      public void write(org.apache.thrift.protocol.TProtocol prot, getAvailableAppInterfaceComputeResources_args struct) throws org.apache.thrift.TException {
        TTupleProtocol oprot = (TTupleProtocol) prot;
        struct.authzToken.write(oprot);
        oprot.writeString(struct.appInterfaceId);
      }

      @Override
      public void read(org.apache.thrift.protocol.TProtocol prot, getAvailableAppInterfaceComputeResources_args struct) throws org.apache.thrift.TException {
        TTupleProtocol iprot = (TTupleProtocol) prot;
        struct.authzToken = new org.apache.airavata.model.security.AuthzToken();
        struct.authzToken.read(iprot);
        struct.setAuthzTokenIsSet(true);
        struct.appInterfaceId = iprot.readString();
        struct.setAppInterfaceIdIsSet(true);
      }
    }

  }

  public static class getAvailableAppInterfaceComputeResources_result implements org.apache.thrift.TBase<getAvailableAppInterfaceComputeResources_result, getAvailableAppInterfaceComputeResources_result._Fields>, java.io.Serializable, Cloneable, Comparable<getAvailableAppInterfaceComputeResources_result>   {
    private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("getAvailableAppInterfaceComputeResources_result");

    private static final org.apache.thrift.protocol.TField SUCCESS_FIELD_DESC = new org.apache.thrift.protocol.TField("success", org.apache.thrift.protocol.TType.MAP, (short)0);
    private static final org.apache.thrift.protocol.TField IRE_FIELD_DESC = new org.apache.thrift.protocol.TField("ire", org.apache.thrift.protocol.TType.STRUCT, (short)1);
    private static final org.apache.thrift.protocol.TField ACE_FIELD_DESC = new org.apache.thrift.protocol.TField("ace", org.apache.thrift.protocol.TType.STRUCT, (short)2);
    private static final org.apache.thrift.protocol.TField ASE_FIELD_DESC = new org.apache.thrift.protocol.TField("ase", org.apache.thrift.protocol.TType.STRUCT, (short)3);
    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)4);

    private static final Map<Class<? extends IScheme>, SchemeFactory> schemes = new HashMap<Class<? extends IScheme>, SchemeFactory>();
    static {
      schemes.put(StandardScheme.class, new getAvailableAppInterfaceComputeResources_resultStandardSchemeFactory());
      schemes.put(TupleScheme.class, new getAvailableAppInterfaceComputeResources_resultTupleSchemeFactory());
    }

    public Map<String,String> success; // required
    public org.apache.airavata.model.error.InvalidRequestException ire; // required
    public org.apache.airavata.model.error.AiravataClientException ace; // required
    public org.apache.airavata.model.error.AiravataSystemException ase; // 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"),
      IRE((short)1, "ire"),
      ACE((short)2, "ace"),
      ASE((short)3, "ase"),
      AE((short)4, "ae");

      private static final Map<String, _Fields> byName = new HashMap<String, _Fields>();

      static {
        for (_Fields field : EnumSet.allOf(_Fields.class)) {
          byName.put(field.getFieldName(), field);
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, or null if its not found.
       */
      public static _Fields findByThriftId(int fieldId) {
        switch(fieldId) {
          case 0: // SUCCESS
            return SUCCESS;
          case 1: // IRE
            return IRE;
          case 2: // ACE
            return ACE;
          case 3: // ASE
            return ASE;
          case 4: // 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 IllegalArgumentException("Field " + fieldId + " doesn't exist!");
        return fields;
      }

      /**
       * Find the _Fields constant that matches name, or null if its not found.
       */
      public static _Fields findByName(String name) {
        return byName.get(name);
      }

      private final short _thriftId;
      private final String _fieldName;

      _Fields(short thriftId, String fieldName) {
        _thriftId = thriftId;
        _fieldName = fieldName;
      }

      public short getThriftFieldId() {
        return _thriftId;
      }

      public String getFieldName() {
        return _fieldName;
      }
    }

    // isset id assignments
    public static final Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
    static {
      Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new EnumMap<_Fields, org.apache.thrift.meta_data.FieldMetaData>(_Fields.class);
      tmpMap.put(_Fields.SUCCESS, new org.apache.thrift.meta_data.FieldMetaData("success", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.MapMetaData(org.apache.thrift.protocol.TType.MAP, 
              new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING), 
              new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING))));
      tmpMap.put(_Fields.IRE, new org.apache.thrift.meta_data.FieldMetaData("ire", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRUCT)));
      tmpMap.put(_Fields.ACE, new org.apache.thrift.meta_data.FieldMetaData("ace", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRUCT)));
      tmpMap.put(_Fields.ASE, new org.apache.thrift.meta_data.FieldMetaData("ase", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRUCT)));
      tmpMap.put(_Fields.AE, new org.apache.thrift.meta_data.FieldMetaData("ae", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRUCT)));
      metaDataMap = Collections.unmodifiableMap(tmpMap);
      org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(getAvailableAppInterfaceComputeResources_result.class, metaDataMap);
    }

    public getAvailableAppInterfaceComputeResources_result() {
    }

    public getAvailableAppInterfaceComputeResources_result(
      Map<String,String> success,
      org.apache.airavata.model.error.InvalidRequestException ire,
      org.apache.airavata.model.error.AiravataClientException ace,
      org.apache.airavata.model.error.AiravataSystemException ase,
      org.apache.airavata.model.error.AuthorizationException ae)
    {
      this();
      this.success = success;
      this.ire = ire;
      this.ace = ace;
      this.ase = ase;
      this.ae = ae;
    }

    /**
     * Performs a deep copy on <i>other</i>.
     */
    public getAvailableAppInterfaceComputeResources_result(getAvailableAppInterfaceComputeResources_result other) {
      if (other.isSetSuccess()) {
        Map<String,String> __this__success = new HashMap<String,String>(other.success);
        this.success = __this__success;
      }
      if (other.isSetIre()) {
        this.ire = new org.apache.airavata.model.error.InvalidRequestException(other.ire);
      }
      if (other.isSetAce()) {
        this.ace = new org.apache.airavata.model.error.AiravataClientException(other.ace);
      }
      if (other.isSetAse()) {
        this.ase = new org.apache.airavata.model.error.AiravataSystemException(other.ase);
      }
      if (other.isSetAe()) {
        this.ae = new org.apache.airavata.model.error.AuthorizationException(other.ae);
      }
    }

    public getAvailableAppInterfaceComputeResources_result deepCopy() {
      return new getAvailableAppInterfaceComputeResources_result(this);
    }

    @Override
    public void clear() {
      this.success = null;
      this.ire = null;
      this.ace = null;
      this.ase = null;
      this.ae = null;
    }

    public int getSuccessSize() {
      return (this.success == null) ? 0 : this.success.size();
    }

    public void putToSuccess(String key, String val) {
      if (this.success == null) {
        this.success = new HashMap<String,String>();
      }
      this.success.put(key, val);
    }

    public Map<String,String> getSuccess() {
      return this.success;
    }

    public getAvailableAppInterfaceComputeResources_result setSuccess(Map<String,String> success) {
      this.success = success;
      return this;
    }

    public void unsetSuccess() {
      this.success = null;
    }

    /** Returns true if field success is set (has been assigned a value) and false otherwise */
    public boolean isSetSuccess() {
      return this.success != null;
    }

    public void setSuccessIsSet(boolean value) {
      if (!value) {
        this.success = null;
      }
    }

    public org.apache.airavata.model.error.InvalidRequestException getIre() {
      return this.ire;
    }

    public getAvailableAppInterfaceComputeResources_result setIre(org.apache.airavata.model.error.InvalidRequestException ire) {
      this.ire = ire;
      return this;
    }

    public void unsetIre() {
      this.ire = null;
    }

    /** Returns true if field ire is set (has been assigned a value) and false otherwise */
    public boolean isSetIre() {
      return this.ire != null;
    }

    public void setIreIsSet(boolean value) {
      if (!value) {
        this.ire = null;
      }
    }

    public org.apache.airavata.model.error.AiravataClientException getAce() {
      return this.ace;
    }

    public getAvailableAppInterfaceComputeResources_result setAce(org.apache.airavata.model.error.AiravataClientException ace) {
      this.ace = ace;
      return this;
    }

    public void unsetAce() {
      this.ace = null;
    }

    /** Returns true if field ace is set (has been assigned a value) and false otherwise */
    public boolean isSetAce() {
      return this.ace != null;
    }

    public void setAceIsSet(boolean value) {
      if (!value) {
        this.ace = null;
      }
    }

    public org.apache.airavata.model.error.AiravataSystemException getAse() {
      return this.ase;
    }

    public getAvailableAppInterfaceComputeResources_result setAse(org.apache.airavata.model.error.AiravataSystemException ase) {
      this.ase = ase;
      return this;
    }

    public void unsetAse() {
      this.ase = null;
    }

    /** Returns true if field ase is set (has been assigned a value) and false otherwise */
    public boolean isSetAse() {
      return this.ase != null;
    }

    public void setAseIsSet(boolean value) {
      if (!value) {
        this.ase = null;
      }
    }

    public org.apache.airavata.model.error.AuthorizationException getAe() {
      return this.ae;
    }

    public getAvailableAppInterfaceComputeResources_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, Object value) {
      switch (field) {
      case SUCCESS:
        if (value == null) {
          unsetSuccess();
        } else {
          setSuccess((Map<String,String>)value);
        }
        break;

      case IRE:
        if (value == null) {
          unsetIre();
        } else {
          setIre((org.apache.airavata.model.error.InvalidRequestException)value);
        }
        break;

      case ACE:
        if (value == null) {
          unsetAce();
        } else {
          setAce((org.apache.airavata.model.error.AiravataClientException)value);
        }
        break;

      case ASE:
        if (value == null) {
          unsetAse();
        } else {
          setAse((org.apache.airavata.model.error.AiravataSystemException)value);
        }
        break;

      case AE:
        if (value == null) {
          unsetAe();
        } else {
          setAe((org.apache.airavata.model.error.AuthorizationException)value);
        }
        break;

      }
    }

    public Object getFieldValue(_Fields field) {
      switch (field) {
      case SUCCESS:
        return getSuccess();

      case IRE:
        return getIre();

      case ACE:
        return getAce();

      case ASE:
        return getAse();

      case AE:
        return getAe();

      }
      throw new IllegalStateException();
    }

    /** Returns true if field corresponding to fieldID is set (has been assigned a value) and false otherwise */
    public boolean isSet(_Fields field) {
      if (field == null) {
        throw new IllegalArgumentException();
      }

      switch (field) {
      case SUCCESS:
        return isSetSuccess();
      case IRE:
        return isSetIre();
      case ACE:
        return isSetAce();
      case ASE:
        return isSetAse();
      case AE:
        return isSetAe();
      }
      throw new IllegalStateException();
    }

    @Override
    public boolean equals(Object that) {
      if (that == null)
        return false;
      if (that instanceof getAvailableAppInterfaceComputeResources_result)
        return this.equals((getAvailableAppInterfaceComputeResources_result)that);
      return false;
    }

    public boolean equals(getAvailableAppInterfaceComputeResources_result that) {
      if (that == null)
        return false;

      boolean this_present_success = true && this.isSetSuccess();
      boolean that_present_success = true && that.isSetSuccess();
      if (this_present_success || that_present_success) {
        if (!(this_present_success && that_present_success))
          return false;
        if (!this.success.equals(that.success))
          return false;
      }

      boolean this_present_ire = true && this.isSetIre();
      boolean that_present_ire = true && that.isSetIre();
      if (this_present_ire || that_present_ire) {
        if (!(this_present_ire && that_present_ire))
          return false;
        if (!this.ire.equals(that.ire))
          return false;
      }

      boolean this_present_ace = true && this.isSetAce();
      boolean that_present_ace = true && that.isSetAce();
      if (this_present_ace || that_present_ace) {
        if (!(this_present_ace && that_present_ace))
          return false;
        if (!this.ace.equals(that.ace))
          return false;
      }

      boolean this_present_ase = true && this.isSetAse();
      boolean that_present_ase = true && that.isSetAse();
      if (this_present_ase || that_present_ase) {
        if (!(this_present_ase && that_present_ase))
          return false;
        if (!this.ase.equals(that.ase))
          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() {
      List<Object> list = new ArrayList<Object>();

      boolean present_success = true && (isSetSuccess());
      list.add(present_success);
      if (present_success)
        list.add(success);

      boolean present_ire = true && (isSetIre());
      list.add(present_ire);
      if (present_ire)
        list.add(ire);

      boolean present_ace = true && (isSetAce());
      list.add(present_ace);
      if (present_ace)
        list.add(ace);

      boolean present_ase = true && (isSetAse());
      list.add(present_ase);
      if (present_ase)
        list.add(ase);

      boolean present_ae = true && (isSetAe());
      list.add(present_ae);
      if (present_ae)
        list.add(ae);

      return list.hashCode();
    }

    @Override
    public int compareTo(getAvailableAppInterfaceComputeResources_result other) {
      if (!getClass().equals(other.getClass())) {
        return getClass().getName().compareTo(other.getClass().getName());
      }

      int lastComparison = 0;

      lastComparison = Boolean.valueOf(isSetSuccess()).compareTo(other.isSetSuccess());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetSuccess()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.success, other.success);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = Boolean.valueOf(isSetIre()).compareTo(other.isSetIre());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetIre()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.ire, other.ire);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = Boolean.valueOf(isSetAce()).compareTo(other.isSetAce());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetAce()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.ace, other.ace);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = Boolean.valueOf(isSetAse()).compareTo(other.isSetAse());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetAse()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.ase, other.ase);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = 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 {
      schemes.get(iprot.getScheme()).getScheme().read(iprot, this);
    }

    public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException {
      schemes.get(oprot.getScheme()).getScheme().write(oprot, this);
      }

    @Override
    public String toString() {
      StringBuilder sb = new StringBuilder("getAvailableAppInterfaceComputeResources_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("ire:");
      if (this.ire == null) {
        sb.append("null");
      } else {
        sb.append(this.ire);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("ace:");
      if (this.ace == null) {
        sb.append("null");
      } else {
        sb.append(this.ace);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("ase:");
      if (this.ase == null) {
        sb.append("null");
      } else {
        sb.append(this.ase);
      }
      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, 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 getAvailableAppInterfaceComputeResources_resultStandardSchemeFactory implements SchemeFactory {
      public getAvailableAppInterfaceComputeResources_resultStandardScheme getScheme() {
        return new getAvailableAppInterfaceComputeResources_resultStandardScheme();
      }
    }

    private static class getAvailableAppInterfaceComputeResources_resultStandardScheme extends StandardScheme<getAvailableAppInterfaceComputeResources_result> {

      public void read(org.apache.thrift.protocol.TProtocol iprot, getAvailableAppInterfaceComputeResources_result struct) throws org.apache.thrift.TException {
        org.apache.thrift.protocol.TField schemeField;
        iprot.readStructBegin();
        while (true)
        {
          schemeField = iprot.readFieldBegin();
          if (schemeField.type == org.apache.thrift.protocol.TType.STOP) { 
            break;
          }
          switch (schemeField.id) {
            case 0: // SUCCESS
              if (schemeField.type == org.apache.thrift.protocol.TType.MAP) {
                {
                  org.apache.thrift.protocol.TMap _map208 = iprot.readMapBegin();
                  struct.success = new HashMap<String,String>(2*_map208.size);
                  String _key209;
                  String _val210;
                  for (int _i211 = 0; _i211 < _map208.size; ++_i211)
                  {
                    _key209 = iprot.readString();
                    _val210 = iprot.readString();
                    struct.success.put(_key209, _val210);
                  }
                  iprot.readMapEnd();
                }
                struct.setSuccessIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 1: // IRE
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.ire = new org.apache.airavata.model.error.InvalidRequestException();
                struct.ire.read(iprot);
                struct.setIreIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 2: // ACE
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.ace = new org.apache.airavata.model.error.AiravataClientException();
                struct.ace.read(iprot);
                struct.setAceIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 3: // ASE
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.ase = new org.apache.airavata.model.error.AiravataSystemException();
                struct.ase.read(iprot);
                struct.setAseIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 4: // 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, getAvailableAppInterfaceComputeResources_result struct) throws org.apache.thrift.TException {
        struct.validate();

        oprot.writeStructBegin(STRUCT_DESC);
        if (struct.success != null) {
          oprot.writeFieldBegin(SUCCESS_FIELD_DESC);
          {
            oprot.writeMapBegin(new org.apache.thrift.protocol.TMap(org.apache.thrift.protocol.TType.STRING, org.apache.thrift.protocol.TType.STRING, struct.success.size()));
            for (Map.Entry<String, String> _iter212 : struct.success.entrySet())
            {
              oprot.writeString(_iter212.getKey());
              oprot.writeString(_iter212.getValue());
            }
            oprot.writeMapEnd();
          }
          oprot.writeFieldEnd();
        }
        if (struct.ire != null) {
          oprot.writeFieldBegin(IRE_FIELD_DESC);
          struct.ire.write(oprot);
          oprot.writeFieldEnd();
        }
        if (struct.ace != null) {
          oprot.writeFieldBegin(ACE_FIELD_DESC);
          struct.ace.write(oprot);
          oprot.writeFieldEnd();
        }
        if (struct.ase != null) {
          oprot.writeFieldBegin(ASE_FIELD_DESC);
          struct.ase.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 getAvailableAppInterfaceComputeResources_resultTupleSchemeFactory implements SchemeFactory {
      public getAvailableAppInterfaceComputeResources_resultTupleScheme getScheme() {
        return new getAvailableAppInterfaceComputeResources_resultTupleScheme();
      }
    }

    private static class getAvailableAppInterfaceComputeResources_resultTupleScheme extends TupleScheme<getAvailableAppInterfaceComputeResources_result> {

      @Override
      public void write(org.apache.thrift.protocol.TProtocol prot, getAvailableAppInterfaceComputeResources_result struct) throws org.apache.thrift.TException {
        TTupleProtocol oprot = (TTupleProtocol) prot;
        BitSet optionals = new BitSet();
        if (struct.isSetSuccess()) {
          optionals.set(0);
        }
        if (struct.isSetIre()) {
          optionals.set(1);
        }
        if (struct.isSetAce()) {
          optionals.set(2);
        }
        if (struct.isSetAse()) {
          optionals.set(3);
        }
        if (struct.isSetAe()) {
          optionals.set(4);
        }
        oprot.writeBitSet(optionals, 5);
        if (struct.isSetSuccess()) {
          {
            oprot.writeI32(struct.success.size());
            for (Map.Entry<String, String> _iter213 : struct.success.entrySet())
            {
              oprot.writeString(_iter213.getKey());
              oprot.writeString(_iter213.getValue());
            }
          }
        }
        if (struct.isSetIre()) {
          struct.ire.write(oprot);
        }
        if (struct.isSetAce()) {
          struct.ace.write(oprot);
        }
        if (struct.isSetAse()) {
          struct.ase.write(oprot);
        }
        if (struct.isSetAe()) {
          struct.ae.write(oprot);
        }
      }

      @Override
      public void read(org.apache.thrift.protocol.TProtocol prot, getAvailableAppInterfaceComputeResources_result struct) throws org.apache.thrift.TException {
        TTupleProtocol iprot = (TTupleProtocol) prot;
        BitSet incoming = iprot.readBitSet(5);
        if (incoming.get(0)) {
          {
            org.apache.thrift.protocol.TMap _map214 = new org.apache.thrift.protocol.TMap(org.apache.thrift.protocol.TType.STRING, org.apache.thrift.protocol.TType.STRING, iprot.readI32());
            struct.success = new HashMap<String,String>(2*_map214.size);
            String _key215;
            String _val216;
            for (int _i217 = 0; _i217 < _map214.size; ++_i217)
            {
              _key215 = iprot.readString();
              _val216 = iprot.readString();
              struct.success.put(_key215, _val216);
            }
          }
          struct.setSuccessIsSet(true);
        }
        if (incoming.get(1)) {
          struct.ire = new org.apache.airavata.model.error.InvalidRequestException();
          struct.ire.read(iprot);
          struct.setIreIsSet(true);
        }
        if (incoming.get(2)) {
          struct.ace = new org.apache.airavata.model.error.AiravataClientException();
          struct.ace.read(iprot);
          struct.setAceIsSet(true);
        }
        if (incoming.get(3)) {
          struct.ase = new org.apache.airavata.model.error.AiravataSystemException();
          struct.ase.read(iprot);
          struct.setAseIsSet(true);
        }
        if (incoming.get(4)) {
          struct.ae = new org.apache.airavata.model.error.AuthorizationException();
          struct.ae.read(iprot);
          struct.setAeIsSet(true);
        }
      }
    }

  }

  public static class registerComputeResource_args implements org.apache.thrift.TBase<registerComputeResource_args, registerComputeResource_args._Fields>, java.io.Serializable, Cloneable, Comparable<registerComputeResource_args>   {
    private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("registerComputeResource_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 COMPUTE_RESOURCE_DESCRIPTION_FIELD_DESC = new org.apache.thrift.protocol.TField("computeResourceDescription", org.apache.thrift.protocol.TType.STRUCT, (short)2);

    private static final Map<Class<? extends IScheme>, SchemeFactory> schemes = new HashMap<Class<? extends IScheme>, SchemeFactory>();
    static {
      schemes.put(StandardScheme.class, new registerComputeResource_argsStandardSchemeFactory());
      schemes.put(TupleScheme.class, new registerComputeResource_argsTupleSchemeFactory());
    }

    public org.apache.airavata.model.security.AuthzToken authzToken; // required
    public org.apache.airavata.model.appcatalog.computeresource.ComputeResourceDescription computeResourceDescription; // required

    /** 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"),
      COMPUTE_RESOURCE_DESCRIPTION((short)2, "computeResourceDescription");

      private static final Map<String, _Fields> byName = new HashMap<String, _Fields>();

      static {
        for (_Fields field : EnumSet.allOf(_Fields.class)) {
          byName.put(field.getFieldName(), field);
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, or null if its not found.
       */
      public static _Fields findByThriftId(int fieldId) {
        switch(fieldId) {
          case 1: // AUTHZ_TOKEN
            return AUTHZ_TOKEN;
          case 2: // COMPUTE_RESOURCE_DESCRIPTION
            return COMPUTE_RESOURCE_DESCRIPTION;
          default:
            return null;
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, throwing an exception
       * if it is not found.
       */
      public static _Fields findByThriftIdOrThrow(int fieldId) {
        _Fields fields = findByThriftId(fieldId);
        if (fields == null) throw new IllegalArgumentException("Field " + fieldId + " doesn't exist!");
        return fields;
      }

      /**
       * Find the _Fields constant that matches name, or null if its not found.
       */
      public static _Fields findByName(String name) {
        return byName.get(name);
      }

      private final short _thriftId;
      private final String _fieldName;

      _Fields(short thriftId, String fieldName) {
        _thriftId = thriftId;
        _fieldName = fieldName;
      }

      public short getThriftFieldId() {
        return _thriftId;
      }

      public String getFieldName() {
        return _fieldName;
      }
    }

    // isset id assignments
    public static final Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
    static {
      Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new EnumMap<_Fields, org.apache.thrift.meta_data.FieldMetaData>(_Fields.class);
      tmpMap.put(_Fields.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.COMPUTE_RESOURCE_DESCRIPTION, new org.apache.thrift.meta_data.FieldMetaData("computeResourceDescription", org.apache.thrift.TFieldRequirementType.REQUIRED, 
          new org.apache.thrift.meta_data.StructMetaData(org.apache.thrift.protocol.TType.STRUCT, org.apache.airavata.model.appcatalog.computeresource.ComputeResourceDescription.class)));
      metaDataMap = Collections.unmodifiableMap(tmpMap);
      org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(registerComputeResource_args.class, metaDataMap);
    }

    public registerComputeResource_args() {
    }

    public registerComputeResource_args(
      org.apache.airavata.model.security.AuthzToken authzToken,
      org.apache.airavata.model.appcatalog.computeresource.ComputeResourceDescription computeResourceDescription)
    {
      this();
      this.authzToken = authzToken;
      this.computeResourceDescription = computeResourceDescription;
    }

    /**
     * Performs a deep copy on <i>other</i>.
     */
    public registerComputeResource_args(registerComputeResource_args other) {
      if (other.isSetAuthzToken()) {
        this.authzToken = new org.apache.airavata.model.security.AuthzToken(other.authzToken);
      }
      if (other.isSetComputeResourceDescription()) {
        this.computeResourceDescription = new org.apache.airavata.model.appcatalog.computeresource.ComputeResourceDescription(other.computeResourceDescription);
      }
    }

    public registerComputeResource_args deepCopy() {
      return new registerComputeResource_args(this);
    }

    @Override
    public void clear() {
      this.authzToken = null;
      this.computeResourceDescription = null;
    }

    public org.apache.airavata.model.security.AuthzToken getAuthzToken() {
      return this.authzToken;
    }

    public registerComputeResource_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.appcatalog.computeresource.ComputeResourceDescription getComputeResourceDescription() {
      return this.computeResourceDescription;
    }

    public registerComputeResource_args setComputeResourceDescription(org.apache.airavata.model.appcatalog.computeresource.ComputeResourceDescription computeResourceDescription) {
      this.computeResourceDescription = computeResourceDescription;
      return this;
    }

    public void unsetComputeResourceDescription() {
      this.computeResourceDescription = null;
    }

    /** Returns true if field computeResourceDescription is set (has been assigned a value) and false otherwise */
    public boolean isSetComputeResourceDescription() {
      return this.computeResourceDescription != null;
    }

    public void setComputeResourceDescriptionIsSet(boolean value) {
      if (!value) {
        this.computeResourceDescription = null;
      }
    }

    public void setFieldValue(_Fields field, Object value) {
      switch (field) {
      case AUTHZ_TOKEN:
        if (value == null) {
          unsetAuthzToken();
        } else {
          setAuthzToken((org.apache.airavata.model.security.AuthzToken)value);
        }
        break;

      case COMPUTE_RESOURCE_DESCRIPTION:
        if (value == null) {
          unsetComputeResourceDescription();
        } else {
          setComputeResourceDescription((org.apache.airavata.model.appcatalog.computeresource.ComputeResourceDescription)value);
        }
        break;

      }
    }

    public Object getFieldValue(_Fields field) {
      switch (field) {
      case AUTHZ_TOKEN:
        return getAuthzToken();

      case COMPUTE_RESOURCE_DESCRIPTION:
        return getComputeResourceDescription();

      }
      throw new IllegalStateException();
    }

    /** Returns true if field corresponding to fieldID is set (has been assigned a value) and false otherwise */
    public boolean isSet(_Fields field) {
      if (field == null) {
        throw new IllegalArgumentException();
      }

      switch (field) {
      case AUTHZ_TOKEN:
        return isSetAuthzToken();
      case COMPUTE_RESOURCE_DESCRIPTION:
        return isSetComputeResourceDescription();
      }
      throw new IllegalStateException();
    }

    @Override
    public boolean equals(Object that) {
      if (that == null)
        return false;
      if (that instanceof registerComputeResource_args)
        return this.equals((registerComputeResource_args)that);
      return false;
    }

    public boolean equals(registerComputeResource_args that) {
      if (that == null)
        return false;

      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_computeResourceDescription = true && this.isSetComputeResourceDescription();
      boolean that_present_computeResourceDescription = true && that.isSetComputeResourceDescription();
      if (this_present_computeResourceDescription || that_present_computeResourceDescription) {
        if (!(this_present_computeResourceDescription && that_present_computeResourceDescription))
          return false;
        if (!this.computeResourceDescription.equals(that.computeResourceDescription))
          return false;
      }

      return true;
    }

    @Override
    public int hashCode() {
      List<Object> list = new ArrayList<Object>();

      boolean present_authzToken = true && (isSetAuthzToken());
      list.add(present_authzToken);
      if (present_authzToken)
        list.add(authzToken);

      boolean present_computeResourceDescription = true && (isSetComputeResourceDescription());
      list.add(present_computeResourceDescription);
      if (present_computeResourceDescription)
        list.add(computeResourceDescription);

      return list.hashCode();
    }

    @Override
    public int compareTo(registerComputeResource_args other) {
      if (!getClass().equals(other.getClass())) {
        return getClass().getName().compareTo(other.getClass().getName());
      }

      int lastComparison = 0;

      lastComparison = 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 = Boolean.valueOf(isSetComputeResourceDescription()).compareTo(other.isSetComputeResourceDescription());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetComputeResourceDescription()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.computeResourceDescription, other.computeResourceDescription);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      return 0;
    }

    public _Fields fieldForId(int fieldId) {
      return _Fields.findByThriftId(fieldId);
    }

    public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
      schemes.get(iprot.getScheme()).getScheme().read(iprot, this);
    }

    public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException {
      schemes.get(oprot.getScheme()).getScheme().write(oprot, this);
    }

    @Override
    public String toString() {
      StringBuilder sb = new StringBuilder("registerComputeResource_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("computeResourceDescription:");
      if (this.computeResourceDescription == null) {
        sb.append("null");
      } else {
        sb.append(this.computeResourceDescription);
      }
      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 (computeResourceDescription == null) {
        throw new org.apache.thrift.protocol.TProtocolException("Required field 'computeResourceDescription' was not present! Struct: " + toString());
      }
      // check for sub-struct validity
      if (authzToken != null) {
        authzToken.validate();
      }
      if (computeResourceDescription != null) {
        computeResourceDescription.validate();
      }
    }

    private void writeObject(java.io.ObjectOutputStream out) throws java.io.IOException {
      try {
        write(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(out)));
      } catch (org.apache.thrift.TException te) {
        throw new java.io.IOException(te);
      }
    }

    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, ClassNotFoundException {
      try {
        read(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(in)));
      } catch (org.apache.thrift.TException te) {
        throw new java.io.IOException(te);
      }
    }

    private static class registerComputeResource_argsStandardSchemeFactory implements SchemeFactory {
      public registerComputeResource_argsStandardScheme getScheme() {
        return new registerComputeResource_argsStandardScheme();
      }
    }

    private static class registerComputeResource_argsStandardScheme extends StandardScheme<registerComputeResource_args> {

      public void read(org.apache.thrift.protocol.TProtocol iprot, registerComputeResource_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: // COMPUTE_RESOURCE_DESCRIPTION
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.computeResourceDescription = new org.apache.airavata.model.appcatalog.computeresource.ComputeResourceDescription();
                struct.computeResourceDescription.read(iprot);
                struct.setComputeResourceDescriptionIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            default:
              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
          }
          iprot.readFieldEnd();
        }
        iprot.readStructEnd();

        // check for required fields of primitive type, which can't be checked in the validate method
        struct.validate();
      }

      public void write(org.apache.thrift.protocol.TProtocol oprot, registerComputeResource_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.computeResourceDescription != null) {
          oprot.writeFieldBegin(COMPUTE_RESOURCE_DESCRIPTION_FIELD_DESC);
          struct.computeResourceDescription.write(oprot);
          oprot.writeFieldEnd();
        }
        oprot.writeFieldStop();
        oprot.writeStructEnd();
      }

    }

    private static class registerComputeResource_argsTupleSchemeFactory implements SchemeFactory {
      public registerComputeResource_argsTupleScheme getScheme() {
        return new registerComputeResource_argsTupleScheme();
      }
    }

    private static class registerComputeResource_argsTupleScheme extends TupleScheme<registerComputeResource_args> {

      @Override
      public void write(org.apache.thrift.protocol.TProtocol prot, registerComputeResource_args struct) throws org.apache.thrift.TException {
        TTupleProtocol oprot = (TTupleProtocol) prot;
        struct.authzToken.write(oprot);
        struct.computeResourceDescription.write(oprot);
      }

      @Override
      public void read(org.apache.thrift.protocol.TProtocol prot, registerComputeResource_args struct) throws org.apache.thrift.TException {
        TTupleProtocol iprot = (TTupleProtocol) prot;
        struct.authzToken = new org.apache.airavata.model.security.AuthzToken();
        struct.authzToken.read(iprot);
        struct.setAuthzTokenIsSet(true);
        struct.computeResourceDescription = new org.apache.airavata.model.appcatalog.computeresource.ComputeResourceDescription();
        struct.computeResourceDescription.read(iprot);
        struct.setComputeResourceDescriptionIsSet(true);
      }
    }

  }

  public static class registerComputeResource_result implements org.apache.thrift.TBase<registerComputeResource_result, registerComputeResource_result._Fields>, java.io.Serializable, Cloneable, Comparable<registerComputeResource_result>   {
    private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("registerComputeResource_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 IRE_FIELD_DESC = new org.apache.thrift.protocol.TField("ire", org.apache.thrift.protocol.TType.STRUCT, (short)1);
    private static final org.apache.thrift.protocol.TField ACE_FIELD_DESC = new org.apache.thrift.protocol.TField("ace", org.apache.thrift.protocol.TType.STRUCT, (short)2);
    private static final org.apache.thrift.protocol.TField ASE_FIELD_DESC = new org.apache.thrift.protocol.TField("ase", org.apache.thrift.protocol.TType.STRUCT, (short)3);
    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)4);

    private static final Map<Class<? extends IScheme>, SchemeFactory> schemes = new HashMap<Class<? extends IScheme>, SchemeFactory>();
    static {
      schemes.put(StandardScheme.class, new registerComputeResource_resultStandardSchemeFactory());
      schemes.put(TupleScheme.class, new registerComputeResource_resultTupleSchemeFactory());
    }

    public String success; // required
    public org.apache.airavata.model.error.InvalidRequestException ire; // required
    public org.apache.airavata.model.error.AiravataClientException ace; // required
    public org.apache.airavata.model.error.AiravataSystemException ase; // 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"),
      IRE((short)1, "ire"),
      ACE((short)2, "ace"),
      ASE((short)3, "ase"),
      AE((short)4, "ae");

      private static final Map<String, _Fields> byName = new HashMap<String, _Fields>();

      static {
        for (_Fields field : EnumSet.allOf(_Fields.class)) {
          byName.put(field.getFieldName(), field);
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, or null if its not found.
       */
      public static _Fields findByThriftId(int fieldId) {
        switch(fieldId) {
          case 0: // SUCCESS
            return SUCCESS;
          case 1: // IRE
            return IRE;
          case 2: // ACE
            return ACE;
          case 3: // ASE
            return ASE;
          case 4: // 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 IllegalArgumentException("Field " + fieldId + " doesn't exist!");
        return fields;
      }

      /**
       * Find the _Fields constant that matches name, or null if its not found.
       */
      public static _Fields findByName(String name) {
        return byName.get(name);
      }

      private final short _thriftId;
      private final String _fieldName;

      _Fields(short thriftId, String fieldName) {
        _thriftId = thriftId;
        _fieldName = fieldName;
      }

      public short getThriftFieldId() {
        return _thriftId;
      }

      public String getFieldName() {
        return _fieldName;
      }
    }

    // isset id assignments
    public static final Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
    static {
      Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new EnumMap<_Fields, org.apache.thrift.meta_data.FieldMetaData>(_Fields.class);
      tmpMap.put(_Fields.SUCCESS, new org.apache.thrift.meta_data.FieldMetaData("success", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING)));
      tmpMap.put(_Fields.IRE, new org.apache.thrift.meta_data.FieldMetaData("ire", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRUCT)));
      tmpMap.put(_Fields.ACE, new org.apache.thrift.meta_data.FieldMetaData("ace", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRUCT)));
      tmpMap.put(_Fields.ASE, new org.apache.thrift.meta_data.FieldMetaData("ase", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRUCT)));
      tmpMap.put(_Fields.AE, new org.apache.thrift.meta_data.FieldMetaData("ae", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRUCT)));
      metaDataMap = Collections.unmodifiableMap(tmpMap);
      org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(registerComputeResource_result.class, metaDataMap);
    }

    public registerComputeResource_result() {
    }

    public registerComputeResource_result(
      String success,
      org.apache.airavata.model.error.InvalidRequestException ire,
      org.apache.airavata.model.error.AiravataClientException ace,
      org.apache.airavata.model.error.AiravataSystemException ase,
      org.apache.airavata.model.error.AuthorizationException ae)
    {
      this();
      this.success = success;
      this.ire = ire;
      this.ace = ace;
      this.ase = ase;
      this.ae = ae;
    }

    /**
     * Performs a deep copy on <i>other</i>.
     */
    public registerComputeResource_result(registerComputeResource_result other) {
      if (other.isSetSuccess()) {
        this.success = other.success;
      }
      if (other.isSetIre()) {
        this.ire = new org.apache.airavata.model.error.InvalidRequestException(other.ire);
      }
      if (other.isSetAce()) {
        this.ace = new org.apache.airavata.model.error.AiravataClientException(other.ace);
      }
      if (other.isSetAse()) {
        this.ase = new org.apache.airavata.model.error.AiravataSystemException(other.ase);
      }
      if (other.isSetAe()) {
        this.ae = new org.apache.airavata.model.error.AuthorizationException(other.ae);
      }
    }

    public registerComputeResource_result deepCopy() {
      return new registerComputeResource_result(this);
    }

    @Override
    public void clear() {
      this.success = null;
      this.ire = null;
      this.ace = null;
      this.ase = null;
      this.ae = null;
    }

    public String getSuccess() {
      return this.success;
    }

    public registerComputeResource_result setSuccess(String success) {
      this.success = success;
      return this;
    }

    public void unsetSuccess() {
      this.success = null;
    }

    /** Returns true if field success is set (has been assigned a value) and false otherwise */
    public boolean isSetSuccess() {
      return this.success != null;
    }

    public void setSuccessIsSet(boolean value) {
      if (!value) {
        this.success = null;
      }
    }

    public org.apache.airavata.model.error.InvalidRequestException getIre() {
      return this.ire;
    }

    public registerComputeResource_result setIre(org.apache.airavata.model.error.InvalidRequestException ire) {
      this.ire = ire;
      return this;
    }

    public void unsetIre() {
      this.ire = null;
    }

    /** Returns true if field ire is set (has been assigned a value) and false otherwise */
    public boolean isSetIre() {
      return this.ire != null;
    }

    public void setIreIsSet(boolean value) {
      if (!value) {
        this.ire = null;
      }
    }

    public org.apache.airavata.model.error.AiravataClientException getAce() {
      return this.ace;
    }

    public registerComputeResource_result setAce(org.apache.airavata.model.error.AiravataClientException ace) {
      this.ace = ace;
      return this;
    }

    public void unsetAce() {
      this.ace = null;
    }

    /** Returns true if field ace is set (has been assigned a value) and false otherwise */
    public boolean isSetAce() {
      return this.ace != null;
    }

    public void setAceIsSet(boolean value) {
      if (!value) {
        this.ace = null;
      }
    }

    public org.apache.airavata.model.error.AiravataSystemException getAse() {
      return this.ase;
    }

    public registerComputeResource_result setAse(org.apache.airavata.model.error.AiravataSystemException ase) {
      this.ase = ase;
      return this;
    }

    public void unsetAse() {
      this.ase = null;
    }

    /** Returns true if field ase is set (has been assigned a value) and false otherwise */
    public boolean isSetAse() {
      return this.ase != null;
    }

    public void setAseIsSet(boolean value) {
      if (!value) {
        this.ase = null;
      }
    }

    public org.apache.airavata.model.error.AuthorizationException getAe() {
      return this.ae;
    }

    public registerComputeResource_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, Object value) {
      switch (field) {
      case SUCCESS:
        if (value == null) {
          unsetSuccess();
        } else {
          setSuccess((String)value);
        }
        break;

      case IRE:
        if (value == null) {
          unsetIre();
        } else {
          setIre((org.apache.airavata.model.error.InvalidRequestException)value);
        }
        break;

      case ACE:
        if (value == null) {
          unsetAce();
        } else {
          setAce((org.apache.airavata.model.error.AiravataClientException)value);
        }
        break;

      case ASE:
        if (value == null) {
          unsetAse();
        } else {
          setAse((org.apache.airavata.model.error.AiravataSystemException)value);
        }
        break;

      case AE:
        if (value == null) {
          unsetAe();
        } else {
          setAe((org.apache.airavata.model.error.AuthorizationException)value);
        }
        break;

      }
    }

    public Object getFieldValue(_Fields field) {
      switch (field) {
      case SUCCESS:
        return getSuccess();

      case IRE:
        return getIre();

      case ACE:
        return getAce();

      case ASE:
        return getAse();

      case AE:
        return getAe();

      }
      throw new IllegalStateException();
    }

    /** Returns true if field corresponding to fieldID is set (has been assigned a value) and false otherwise */
    public boolean isSet(_Fields field) {
      if (field == null) {
        throw new IllegalArgumentException();
      }

      switch (field) {
      case SUCCESS:
        return isSetSuccess();
      case IRE:
        return isSetIre();
      case ACE:
        return isSetAce();
      case ASE:
        return isSetAse();
      case AE:
        return isSetAe();
      }
      throw new IllegalStateException();
    }

    @Override
    public boolean equals(Object that) {
      if (that == null)
        return false;
      if (that instanceof registerComputeResource_result)
        return this.equals((registerComputeResource_result)that);
      return false;
    }

    public boolean equals(registerComputeResource_result that) {
      if (that == null)
        return false;

      boolean this_present_success = true && this.isSetSuccess();
      boolean that_present_success = true && that.isSetSuccess();
      if (this_present_success || that_present_success) {
        if (!(this_present_success && that_present_success))
          return false;
        if (!this.success.equals(that.success))
          return false;
      }

      boolean this_present_ire = true && this.isSetIre();
      boolean that_present_ire = true && that.isSetIre();
      if (this_present_ire || that_present_ire) {
        if (!(this_present_ire && that_present_ire))
          return false;
        if (!this.ire.equals(that.ire))
          return false;
      }

      boolean this_present_ace = true && this.isSetAce();
      boolean that_present_ace = true && that.isSetAce();
      if (this_present_ace || that_present_ace) {
        if (!(this_present_ace && that_present_ace))
          return false;
        if (!this.ace.equals(that.ace))
          return false;
      }

      boolean this_present_ase = true && this.isSetAse();
      boolean that_present_ase = true && that.isSetAse();
      if (this_present_ase || that_present_ase) {
        if (!(this_present_ase && that_present_ase))
          return false;
        if (!this.ase.equals(that.ase))
          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() {
      List<Object> list = new ArrayList<Object>();

      boolean present_success = true && (isSetSuccess());
      list.add(present_success);
      if (present_success)
        list.add(success);

      boolean present_ire = true && (isSetIre());
      list.add(present_ire);
      if (present_ire)
        list.add(ire);

      boolean present_ace = true && (isSetAce());
      list.add(present_ace);
      if (present_ace)
        list.add(ace);

      boolean present_ase = true && (isSetAse());
      list.add(present_ase);
      if (present_ase)
        list.add(ase);

      boolean present_ae = true && (isSetAe());
      list.add(present_ae);
      if (present_ae)
        list.add(ae);

      return list.hashCode();
    }

    @Override
    public int compareTo(registerComputeResource_result other) {
      if (!getClass().equals(other.getClass())) {
        return getClass().getName().compareTo(other.getClass().getName());
      }

      int lastComparison = 0;

      lastComparison = Boolean.valueOf(isSetSuccess()).compareTo(other.isSetSuccess());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetSuccess()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.success, other.success);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = Boolean.valueOf(isSetIre()).compareTo(other.isSetIre());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetIre()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.ire, other.ire);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = Boolean.valueOf(isSetAce()).compareTo(other.isSetAce());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetAce()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.ace, other.ace);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = Boolean.valueOf(isSetAse()).compareTo(other.isSetAse());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetAse()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.ase, other.ase);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = 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 {
      schemes.get(iprot.getScheme()).getScheme().read(iprot, this);
    }

    public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException {
      schemes.get(oprot.getScheme()).getScheme().write(oprot, this);
      }

    @Override
    public String toString() {
      StringBuilder sb = new StringBuilder("registerComputeResource_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("ire:");
      if (this.ire == null) {
        sb.append("null");
      } else {
        sb.append(this.ire);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("ace:");
      if (this.ace == null) {
        sb.append("null");
      } else {
        sb.append(this.ace);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("ase:");
      if (this.ase == null) {
        sb.append("null");
      } else {
        sb.append(this.ase);
      }
      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, 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 registerComputeResource_resultStandardSchemeFactory implements SchemeFactory {
      public registerComputeResource_resultStandardScheme getScheme() {
        return new registerComputeResource_resultStandardScheme();
      }
    }

    private static class registerComputeResource_resultStandardScheme extends StandardScheme<registerComputeResource_result> {

      public void read(org.apache.thrift.protocol.TProtocol iprot, registerComputeResource_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: // IRE
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.ire = new org.apache.airavata.model.error.InvalidRequestException();
                struct.ire.read(iprot);
                struct.setIreIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 2: // ACE
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.ace = new org.apache.airavata.model.error.AiravataClientException();
                struct.ace.read(iprot);
                struct.setAceIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 3: // ASE
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.ase = new org.apache.airavata.model.error.AiravataSystemException();
                struct.ase.read(iprot);
                struct.setAseIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 4: // 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, registerComputeResource_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.ire != null) {
          oprot.writeFieldBegin(IRE_FIELD_DESC);
          struct.ire.write(oprot);
          oprot.writeFieldEnd();
        }
        if (struct.ace != null) {
          oprot.writeFieldBegin(ACE_FIELD_DESC);
          struct.ace.write(oprot);
          oprot.writeFieldEnd();
        }
        if (struct.ase != null) {
          oprot.writeFieldBegin(ASE_FIELD_DESC);
          struct.ase.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 registerComputeResource_resultTupleSchemeFactory implements SchemeFactory {
      public registerComputeResource_resultTupleScheme getScheme() {
        return new registerComputeResource_resultTupleScheme();
      }
    }

    private static class registerComputeResource_resultTupleScheme extends TupleScheme<registerComputeResource_result> {

      @Override
      public void write(org.apache.thrift.protocol.TProtocol prot, registerComputeResource_result struct) throws org.apache.thrift.TException {
        TTupleProtocol oprot = (TTupleProtocol) prot;
        BitSet optionals = new BitSet();
        if (struct.isSetSuccess()) {
          optionals.set(0);
        }
        if (struct.isSetIre()) {
          optionals.set(1);
        }
        if (struct.isSetAce()) {
          optionals.set(2);
        }
        if (struct.isSetAse()) {
          optionals.set(3);
        }
        if (struct.isSetAe()) {
          optionals.set(4);
        }
        oprot.writeBitSet(optionals, 5);
        if (struct.isSetSuccess()) {
          oprot.writeString(struct.success);
        }
        if (struct.isSetIre()) {
          struct.ire.write(oprot);
        }
        if (struct.isSetAce()) {
          struct.ace.write(oprot);
        }
        if (struct.isSetAse()) {
          struct.ase.write(oprot);
        }
        if (struct.isSetAe()) {
          struct.ae.write(oprot);
        }
      }

      @Override
      public void read(org.apache.thrift.protocol.TProtocol prot, registerComputeResource_result struct) throws org.apache.thrift.TException {
        TTupleProtocol iprot = (TTupleProtocol) prot;
        BitSet incoming = iprot.readBitSet(5);
        if (incoming.get(0)) {
          struct.success = iprot.readString();
          struct.setSuccessIsSet(true);
        }
        if (incoming.get(1)) {
          struct.ire = new org.apache.airavata.model.error.InvalidRequestException();
          struct.ire.read(iprot);
          struct.setIreIsSet(true);
        }
        if (incoming.get(2)) {
          struct.ace = new org.apache.airavata.model.error.AiravataClientException();
          struct.ace.read(iprot);
          struct.setAceIsSet(true);
        }
        if (incoming.get(3)) {
          struct.ase = new org.apache.airavata.model.error.AiravataSystemException();
          struct.ase.read(iprot);
          struct.setAseIsSet(true);
        }
        if (incoming.get(4)) {
          struct.ae = new org.apache.airavata.model.error.AuthorizationException();
          struct.ae.read(iprot);
          struct.setAeIsSet(true);
        }
      }
    }

  }

  public static class getComputeResource_args implements org.apache.thrift.TBase<getComputeResource_args, getComputeResource_args._Fields>, java.io.Serializable, Cloneable, Comparable<getComputeResource_args>   {
    private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("getComputeResource_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 COMPUTE_RESOURCE_ID_FIELD_DESC = new org.apache.thrift.protocol.TField("computeResourceId", org.apache.thrift.protocol.TType.STRING, (short)2);

    private static final Map<Class<? extends IScheme>, SchemeFactory> schemes = new HashMap<Class<? extends IScheme>, SchemeFactory>();
    static {
      schemes.put(StandardScheme.class, new getComputeResource_argsStandardSchemeFactory());
      schemes.put(TupleScheme.class, new getComputeResource_argsTupleSchemeFactory());
    }

    public org.apache.airavata.model.security.AuthzToken authzToken; // required
    public String computeResourceId; // required

    /** 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"),
      COMPUTE_RESOURCE_ID((short)2, "computeResourceId");

      private static final Map<String, _Fields> byName = new HashMap<String, _Fields>();

      static {
        for (_Fields field : EnumSet.allOf(_Fields.class)) {
          byName.put(field.getFieldName(), field);
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, or null if its not found.
       */
      public static _Fields findByThriftId(int fieldId) {
        switch(fieldId) {
          case 1: // AUTHZ_TOKEN
            return AUTHZ_TOKEN;
          case 2: // COMPUTE_RESOURCE_ID
            return COMPUTE_RESOURCE_ID;
          default:
            return null;
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, throwing an exception
       * if it is not found.
       */
      public static _Fields findByThriftIdOrThrow(int fieldId) {
        _Fields fields = findByThriftId(fieldId);
        if (fields == null) throw new IllegalArgumentException("Field " + fieldId + " doesn't exist!");
        return fields;
      }

      /**
       * Find the _Fields constant that matches name, or null if its not found.
       */
      public static _Fields findByName(String name) {
        return byName.get(name);
      }

      private final short _thriftId;
      private final String _fieldName;

      _Fields(short thriftId, String fieldName) {
        _thriftId = thriftId;
        _fieldName = fieldName;
      }

      public short getThriftFieldId() {
        return _thriftId;
      }

      public String getFieldName() {
        return _fieldName;
      }
    }

    // isset id assignments
    public static final Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
    static {
      Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new EnumMap<_Fields, org.apache.thrift.meta_data.FieldMetaData>(_Fields.class);
      tmpMap.put(_Fields.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.COMPUTE_RESOURCE_ID, new org.apache.thrift.meta_data.FieldMetaData("computeResourceId", org.apache.thrift.TFieldRequirementType.REQUIRED, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING)));
      metaDataMap = Collections.unmodifiableMap(tmpMap);
      org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(getComputeResource_args.class, metaDataMap);
    }

    public getComputeResource_args() {
    }

    public getComputeResource_args(
      org.apache.airavata.model.security.AuthzToken authzToken,
      String computeResourceId)
    {
      this();
      this.authzToken = authzToken;
      this.computeResourceId = computeResourceId;
    }

    /**
     * Performs a deep copy on <i>other</i>.
     */
    public getComputeResource_args(getComputeResource_args other) {
      if (other.isSetAuthzToken()) {
        this.authzToken = new org.apache.airavata.model.security.AuthzToken(other.authzToken);
      }
      if (other.isSetComputeResourceId()) {
        this.computeResourceId = other.computeResourceId;
      }
    }

    public getComputeResource_args deepCopy() {
      return new getComputeResource_args(this);
    }

    @Override
    public void clear() {
      this.authzToken = null;
      this.computeResourceId = null;
    }

    public org.apache.airavata.model.security.AuthzToken getAuthzToken() {
      return this.authzToken;
    }

    public getComputeResource_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 String getComputeResourceId() {
      return this.computeResourceId;
    }

    public getComputeResource_args setComputeResourceId(String computeResourceId) {
      this.computeResourceId = computeResourceId;
      return this;
    }

    public void unsetComputeResourceId() {
      this.computeResourceId = null;
    }

    /** Returns true if field computeResourceId is set (has been assigned a value) and false otherwise */
    public boolean isSetComputeResourceId() {
      return this.computeResourceId != null;
    }

    public void setComputeResourceIdIsSet(boolean value) {
      if (!value) {
        this.computeResourceId = null;
      }
    }

    public void setFieldValue(_Fields field, Object value) {
      switch (field) {
      case AUTHZ_TOKEN:
        if (value == null) {
          unsetAuthzToken();
        } else {
          setAuthzToken((org.apache.airavata.model.security.AuthzToken)value);
        }
        break;

      case COMPUTE_RESOURCE_ID:
        if (value == null) {
          unsetComputeResourceId();
        } else {
          setComputeResourceId((String)value);
        }
        break;

      }
    }

    public Object getFieldValue(_Fields field) {
      switch (field) {
      case AUTHZ_TOKEN:
        return getAuthzToken();

      case COMPUTE_RESOURCE_ID:
        return getComputeResourceId();

      }
      throw new IllegalStateException();
    }

    /** Returns true if field corresponding to fieldID is set (has been assigned a value) and false otherwise */
    public boolean isSet(_Fields field) {
      if (field == null) {
        throw new IllegalArgumentException();
      }

      switch (field) {
      case AUTHZ_TOKEN:
        return isSetAuthzToken();
      case COMPUTE_RESOURCE_ID:
        return isSetComputeResourceId();
      }
      throw new IllegalStateException();
    }

    @Override
    public boolean equals(Object that) {
      if (that == null)
        return false;
      if (that instanceof getComputeResource_args)
        return this.equals((getComputeResource_args)that);
      return false;
    }

    public boolean equals(getComputeResource_args that) {
      if (that == null)
        return false;

      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_computeResourceId = true && this.isSetComputeResourceId();
      boolean that_present_computeResourceId = true && that.isSetComputeResourceId();
      if (this_present_computeResourceId || that_present_computeResourceId) {
        if (!(this_present_computeResourceId && that_present_computeResourceId))
          return false;
        if (!this.computeResourceId.equals(that.computeResourceId))
          return false;
      }

      return true;
    }

    @Override
    public int hashCode() {
      List<Object> list = new ArrayList<Object>();

      boolean present_authzToken = true && (isSetAuthzToken());
      list.add(present_authzToken);
      if (present_authzToken)
        list.add(authzToken);

      boolean present_computeResourceId = true && (isSetComputeResourceId());
      list.add(present_computeResourceId);
      if (present_computeResourceId)
        list.add(computeResourceId);

      return list.hashCode();
    }

    @Override
    public int compareTo(getComputeResource_args other) {
      if (!getClass().equals(other.getClass())) {
        return getClass().getName().compareTo(other.getClass().getName());
      }

      int lastComparison = 0;

      lastComparison = 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 = Boolean.valueOf(isSetComputeResourceId()).compareTo(other.isSetComputeResourceId());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetComputeResourceId()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.computeResourceId, other.computeResourceId);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      return 0;
    }

    public _Fields fieldForId(int fieldId) {
      return _Fields.findByThriftId(fieldId);
    }

    public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
      schemes.get(iprot.getScheme()).getScheme().read(iprot, this);
    }

    public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException {
      schemes.get(oprot.getScheme()).getScheme().write(oprot, this);
    }

    @Override
    public String toString() {
      StringBuilder sb = new StringBuilder("getComputeResource_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("computeResourceId:");
      if (this.computeResourceId == null) {
        sb.append("null");
      } else {
        sb.append(this.computeResourceId);
      }
      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 (computeResourceId == null) {
        throw new org.apache.thrift.protocol.TProtocolException("Required field 'computeResourceId' 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, 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 getComputeResource_argsStandardSchemeFactory implements SchemeFactory {
      public getComputeResource_argsStandardScheme getScheme() {
        return new getComputeResource_argsStandardScheme();
      }
    }

    private static class getComputeResource_argsStandardScheme extends StandardScheme<getComputeResource_args> {

      public void read(org.apache.thrift.protocol.TProtocol iprot, getComputeResource_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: // COMPUTE_RESOURCE_ID
              if (schemeField.type == org.apache.thrift.protocol.TType.STRING) {
                struct.computeResourceId = iprot.readString();
                struct.setComputeResourceIdIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            default:
              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
          }
          iprot.readFieldEnd();
        }
        iprot.readStructEnd();

        // check for required fields of primitive type, which can't be checked in the validate method
        struct.validate();
      }

      public void write(org.apache.thrift.protocol.TProtocol oprot, getComputeResource_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.computeResourceId != null) {
          oprot.writeFieldBegin(COMPUTE_RESOURCE_ID_FIELD_DESC);
          oprot.writeString(struct.computeResourceId);
          oprot.writeFieldEnd();
        }
        oprot.writeFieldStop();
        oprot.writeStructEnd();
      }

    }

    private static class getComputeResource_argsTupleSchemeFactory implements SchemeFactory {
      public getComputeResource_argsTupleScheme getScheme() {
        return new getComputeResource_argsTupleScheme();
      }
    }

    private static class getComputeResource_argsTupleScheme extends TupleScheme<getComputeResource_args> {

      @Override
      public void write(org.apache.thrift.protocol.TProtocol prot, getComputeResource_args struct) throws org.apache.thrift.TException {
        TTupleProtocol oprot = (TTupleProtocol) prot;
        struct.authzToken.write(oprot);
        oprot.writeString(struct.computeResourceId);
      }

      @Override
      public void read(org.apache.thrift.protocol.TProtocol prot, getComputeResource_args struct) throws org.apache.thrift.TException {
        TTupleProtocol iprot = (TTupleProtocol) prot;
        struct.authzToken = new org.apache.airavata.model.security.AuthzToken();
        struct.authzToken.read(iprot);
        struct.setAuthzTokenIsSet(true);
        struct.computeResourceId = iprot.readString();
        struct.setComputeResourceIdIsSet(true);
      }
    }

  }

  public static class getComputeResource_result implements org.apache.thrift.TBase<getComputeResource_result, getComputeResource_result._Fields>, java.io.Serializable, Cloneable, Comparable<getComputeResource_result>   {
    private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("getComputeResource_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 IRE_FIELD_DESC = new org.apache.thrift.protocol.TField("ire", org.apache.thrift.protocol.TType.STRUCT, (short)1);
    private static final org.apache.thrift.protocol.TField ACE_FIELD_DESC = new org.apache.thrift.protocol.TField("ace", org.apache.thrift.protocol.TType.STRUCT, (short)2);
    private static final org.apache.thrift.protocol.TField ASE_FIELD_DESC = new org.apache.thrift.protocol.TField("ase", org.apache.thrift.protocol.TType.STRUCT, (short)3);
    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)4);

    private static final Map<Class<? extends IScheme>, SchemeFactory> schemes = new HashMap<Class<? extends IScheme>, SchemeFactory>();
    static {
      schemes.put(StandardScheme.class, new getComputeResource_resultStandardSchemeFactory());
      schemes.put(TupleScheme.class, new getComputeResource_resultTupleSchemeFactory());
    }

    public org.apache.airavata.model.appcatalog.computeresource.ComputeResourceDescription success; // required
    public org.apache.airavata.model.error.InvalidRequestException ire; // required
    public org.apache.airavata.model.error.AiravataClientException ace; // required
    public org.apache.airavata.model.error.AiravataSystemException ase; // 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"),
      IRE((short)1, "ire"),
      ACE((short)2, "ace"),
      ASE((short)3, "ase"),
      AE((short)4, "ae");

      private static final Map<String, _Fields> byName = new HashMap<String, _Fields>();

      static {
        for (_Fields field : EnumSet.allOf(_Fields.class)) {
          byName.put(field.getFieldName(), field);
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, or null if its not found.
       */
      public static _Fields findByThriftId(int fieldId) {
        switch(fieldId) {
          case 0: // SUCCESS
            return SUCCESS;
          case 1: // IRE
            return IRE;
          case 2: // ACE
            return ACE;
          case 3: // ASE
            return ASE;
          case 4: // 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 IllegalArgumentException("Field " + fieldId + " doesn't exist!");
        return fields;
      }

      /**
       * Find the _Fields constant that matches name, or null if its not found.
       */
      public static _Fields findByName(String name) {
        return byName.get(name);
      }

      private final short _thriftId;
      private final String _fieldName;

      _Fields(short thriftId, String fieldName) {
        _thriftId = thriftId;
        _fieldName = fieldName;
      }

      public short getThriftFieldId() {
        return _thriftId;
      }

      public String getFieldName() {
        return _fieldName;
      }
    }

    // isset id assignments
    public static final Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
    static {
      Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new EnumMap<_Fields, org.apache.thrift.meta_data.FieldMetaData>(_Fields.class);
      tmpMap.put(_Fields.SUCCESS, new org.apache.thrift.meta_data.FieldMetaData("success", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.StructMetaData(org.apache.thrift.protocol.TType.STRUCT, org.apache.airavata.model.appcatalog.computeresource.ComputeResourceDescription.class)));
      tmpMap.put(_Fields.IRE, new org.apache.thrift.meta_data.FieldMetaData("ire", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRUCT)));
      tmpMap.put(_Fields.ACE, new org.apache.thrift.meta_data.FieldMetaData("ace", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRUCT)));
      tmpMap.put(_Fields.ASE, new org.apache.thrift.meta_data.FieldMetaData("ase", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRUCT)));
      tmpMap.put(_Fields.AE, new org.apache.thrift.meta_data.FieldMetaData("ae", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRUCT)));
      metaDataMap = Collections.unmodifiableMap(tmpMap);
      org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(getComputeResource_result.class, metaDataMap);
    }

    public getComputeResource_result() {
    }

    public getComputeResource_result(
      org.apache.airavata.model.appcatalog.computeresource.ComputeResourceDescription success,
      org.apache.airavata.model.error.InvalidRequestException ire,
      org.apache.airavata.model.error.AiravataClientException ace,
      org.apache.airavata.model.error.AiravataSystemException ase,
      org.apache.airavata.model.error.AuthorizationException ae)
    {
      this();
      this.success = success;
      this.ire = ire;
      this.ace = ace;
      this.ase = ase;
      this.ae = ae;
    }

    /**
     * Performs a deep copy on <i>other</i>.
     */
    public getComputeResource_result(getComputeResource_result other) {
      if (other.isSetSuccess()) {
        this.success = new org.apache.airavata.model.appcatalog.computeresource.ComputeResourceDescription(other.success);
      }
      if (other.isSetIre()) {
        this.ire = new org.apache.airavata.model.error.InvalidRequestException(other.ire);
      }
      if (other.isSetAce()) {
        this.ace = new org.apache.airavata.model.error.AiravataClientException(other.ace);
      }
      if (other.isSetAse()) {
        this.ase = new org.apache.airavata.model.error.AiravataSystemException(other.ase);
      }
      if (other.isSetAe()) {
        this.ae = new org.apache.airavata.model.error.AuthorizationException(other.ae);
      }
    }

    public getComputeResource_result deepCopy() {
      return new getComputeResource_result(this);
    }

    @Override
    public void clear() {
      this.success = null;
      this.ire = null;
      this.ace = null;
      this.ase = null;
      this.ae = null;
    }

    public org.apache.airavata.model.appcatalog.computeresource.ComputeResourceDescription getSuccess() {
      return this.success;
    }

    public getComputeResource_result setSuccess(org.apache.airavata.model.appcatalog.computeresource.ComputeResourceDescription 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.model.error.InvalidRequestException getIre() {
      return this.ire;
    }

    public getComputeResource_result setIre(org.apache.airavata.model.error.InvalidRequestException ire) {
      this.ire = ire;
      return this;
    }

    public void unsetIre() {
      this.ire = null;
    }

    /** Returns true if field ire is set (has been assigned a value) and false otherwise */
    public boolean isSetIre() {
      return this.ire != null;
    }

    public void setIreIsSet(boolean value) {
      if (!value) {
        this.ire = null;
      }
    }

    public org.apache.airavata.model.error.AiravataClientException getAce() {
      return this.ace;
    }

    public getComputeResource_result setAce(org.apache.airavata.model.error.AiravataClientException ace) {
      this.ace = ace;
      return this;
    }

    public void unsetAce() {
      this.ace = null;
    }

    /** Returns true if field ace is set (has been assigned a value) and false otherwise */
    public boolean isSetAce() {
      return this.ace != null;
    }

    public void setAceIsSet(boolean value) {
      if (!value) {
        this.ace = null;
      }
    }

    public org.apache.airavata.model.error.AiravataSystemException getAse() {
      return this.ase;
    }

    public getComputeResource_result setAse(org.apache.airavata.model.error.AiravataSystemException ase) {
      this.ase = ase;
      return this;
    }

    public void unsetAse() {
      this.ase = null;
    }

    /** Returns true if field ase is set (has been assigned a value) and false otherwise */
    public boolean isSetAse() {
      return this.ase != null;
    }

    public void setAseIsSet(boolean value) {
      if (!value) {
        this.ase = null;
      }
    }

    public org.apache.airavata.model.error.AuthorizationException getAe() {
      return this.ae;
    }

    public getComputeResource_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, Object value) {
      switch (field) {
      case SUCCESS:
        if (value == null) {
          unsetSuccess();
        } else {
          setSuccess((org.apache.airavata.model.appcatalog.computeresource.ComputeResourceDescription)value);
        }
        break;

      case IRE:
        if (value == null) {
          unsetIre();
        } else {
          setIre((org.apache.airavata.model.error.InvalidRequestException)value);
        }
        break;

      case ACE:
        if (value == null) {
          unsetAce();
        } else {
          setAce((org.apache.airavata.model.error.AiravataClientException)value);
        }
        break;

      case ASE:
        if (value == null) {
          unsetAse();
        } else {
          setAse((org.apache.airavata.model.error.AiravataSystemException)value);
        }
        break;

      case AE:
        if (value == null) {
          unsetAe();
        } else {
          setAe((org.apache.airavata.model.error.AuthorizationException)value);
        }
        break;

      }
    }

    public Object getFieldValue(_Fields field) {
      switch (field) {
      case SUCCESS:
        return getSuccess();

      case IRE:
        return getIre();

      case ACE:
        return getAce();

      case ASE:
        return getAse();

      case AE:
        return getAe();

      }
      throw new IllegalStateException();
    }

    /** Returns true if field corresponding to fieldID is set (has been assigned a value) and false otherwise */
    public boolean isSet(_Fields field) {
      if (field == null) {
        throw new IllegalArgumentException();
      }

      switch (field) {
      case SUCCESS:
        return isSetSuccess();
      case IRE:
        return isSetIre();
      case ACE:
        return isSetAce();
      case ASE:
        return isSetAse();
      case AE:
        return isSetAe();
      }
      throw new IllegalStateException();
    }

    @Override
    public boolean equals(Object that) {
      if (that == null)
        return false;
      if (that instanceof getComputeResource_result)
        return this.equals((getComputeResource_result)that);
      return false;
    }

    public boolean equals(getComputeResource_result that) {
      if (that == null)
        return false;

      boolean this_present_success = true && this.isSetSuccess();
      boolean that_present_success = true && that.isSetSuccess();
      if (this_present_success || that_present_success) {
        if (!(this_present_success && that_present_success))
          return false;
        if (!this.success.equals(that.success))
          return false;
      }

      boolean this_present_ire = true && this.isSetIre();
      boolean that_present_ire = true && that.isSetIre();
      if (this_present_ire || that_present_ire) {
        if (!(this_present_ire && that_present_ire))
          return false;
        if (!this.ire.equals(that.ire))
          return false;
      }

      boolean this_present_ace = true && this.isSetAce();
      boolean that_present_ace = true && that.isSetAce();
      if (this_present_ace || that_present_ace) {
        if (!(this_present_ace && that_present_ace))
          return false;
        if (!this.ace.equals(that.ace))
          return false;
      }

      boolean this_present_ase = true && this.isSetAse();
      boolean that_present_ase = true && that.isSetAse();
      if (this_present_ase || that_present_ase) {
        if (!(this_present_ase && that_present_ase))
          return false;
        if (!this.ase.equals(that.ase))
          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() {
      List<Object> list = new ArrayList<Object>();

      boolean present_success = true && (isSetSuccess());
      list.add(present_success);
      if (present_success)
        list.add(success);

      boolean present_ire = true && (isSetIre());
      list.add(present_ire);
      if (present_ire)
        list.add(ire);

      boolean present_ace = true && (isSetAce());
      list.add(present_ace);
      if (present_ace)
        list.add(ace);

      boolean present_ase = true && (isSetAse());
      list.add(present_ase);
      if (present_ase)
        list.add(ase);

      boolean present_ae = true && (isSetAe());
      list.add(present_ae);
      if (present_ae)
        list.add(ae);

      return list.hashCode();
    }

    @Override
    public int compareTo(getComputeResource_result other) {
      if (!getClass().equals(other.getClass())) {
        return getClass().getName().compareTo(other.getClass().getName());
      }

      int lastComparison = 0;

      lastComparison = Boolean.valueOf(isSetSuccess()).compareTo(other.isSetSuccess());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetSuccess()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.success, other.success);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = Boolean.valueOf(isSetIre()).compareTo(other.isSetIre());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetIre()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.ire, other.ire);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = Boolean.valueOf(isSetAce()).compareTo(other.isSetAce());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetAce()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.ace, other.ace);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = Boolean.valueOf(isSetAse()).compareTo(other.isSetAse());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetAse()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.ase, other.ase);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = 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 {
      schemes.get(iprot.getScheme()).getScheme().read(iprot, this);
    }

    public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException {
      schemes.get(oprot.getScheme()).getScheme().write(oprot, this);
      }

    @Override
    public String toString() {
      StringBuilder sb = new StringBuilder("getComputeResource_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("ire:");
      if (this.ire == null) {
        sb.append("null");
      } else {
        sb.append(this.ire);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("ace:");
      if (this.ace == null) {
        sb.append("null");
      } else {
        sb.append(this.ace);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("ase:");
      if (this.ase == null) {
        sb.append("null");
      } else {
        sb.append(this.ase);
      }
      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, 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 getComputeResource_resultStandardSchemeFactory implements SchemeFactory {
      public getComputeResource_resultStandardScheme getScheme() {
        return new getComputeResource_resultStandardScheme();
      }
    }

    private static class getComputeResource_resultStandardScheme extends StandardScheme<getComputeResource_result> {

      public void read(org.apache.thrift.protocol.TProtocol iprot, getComputeResource_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.appcatalog.computeresource.ComputeResourceDescription();
                struct.success.read(iprot);
                struct.setSuccessIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 1: // IRE
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.ire = new org.apache.airavata.model.error.InvalidRequestException();
                struct.ire.read(iprot);
                struct.setIreIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 2: // ACE
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.ace = new org.apache.airavata.model.error.AiravataClientException();
                struct.ace.read(iprot);
                struct.setAceIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 3: // ASE
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.ase = new org.apache.airavata.model.error.AiravataSystemException();
                struct.ase.read(iprot);
                struct.setAseIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 4: // 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, getComputeResource_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.ire != null) {
          oprot.writeFieldBegin(IRE_FIELD_DESC);
          struct.ire.write(oprot);
          oprot.writeFieldEnd();
        }
        if (struct.ace != null) {
          oprot.writeFieldBegin(ACE_FIELD_DESC);
          struct.ace.write(oprot);
          oprot.writeFieldEnd();
        }
        if (struct.ase != null) {
          oprot.writeFieldBegin(ASE_FIELD_DESC);
          struct.ase.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 getComputeResource_resultTupleSchemeFactory implements SchemeFactory {
      public getComputeResource_resultTupleScheme getScheme() {
        return new getComputeResource_resultTupleScheme();
      }
    }

    private static class getComputeResource_resultTupleScheme extends TupleScheme<getComputeResource_result> {

      @Override
      public void write(org.apache.thrift.protocol.TProtocol prot, getComputeResource_result struct) throws org.apache.thrift.TException {
        TTupleProtocol oprot = (TTupleProtocol) prot;
        BitSet optionals = new BitSet();
        if (struct.isSetSuccess()) {
          optionals.set(0);
        }
        if (struct.isSetIre()) {
          optionals.set(1);
        }
        if (struct.isSetAce()) {
          optionals.set(2);
        }
        if (struct.isSetAse()) {
          optionals.set(3);
        }
        if (struct.isSetAe()) {
          optionals.set(4);
        }
        oprot.writeBitSet(optionals, 5);
        if (struct.isSetSuccess()) {
          struct.success.write(oprot);
        }
        if (struct.isSetIre()) {
          struct.ire.write(oprot);
        }
        if (struct.isSetAce()) {
          struct.ace.write(oprot);
        }
        if (struct.isSetAse()) {
          struct.ase.write(oprot);
        }
        if (struct.isSetAe()) {
          struct.ae.write(oprot);
        }
      }

      @Override
      public void read(org.apache.thrift.protocol.TProtocol prot, getComputeResource_result struct) throws org.apache.thrift.TException {
        TTupleProtocol iprot = (TTupleProtocol) prot;
        BitSet incoming = iprot.readBitSet(5);
        if (incoming.get(0)) {
          struct.success = new org.apache.airavata.model.appcatalog.computeresource.ComputeResourceDescription();
          struct.success.read(iprot);
          struct.setSuccessIsSet(true);
        }
        if (incoming.get(1)) {
          struct.ire = new org.apache.airavata.model.error.InvalidRequestException();
          struct.ire.read(iprot);
          struct.setIreIsSet(true);
        }
        if (incoming.get(2)) {
          struct.ace = new org.apache.airavata.model.error.AiravataClientException();
          struct.ace.read(iprot);
          struct.setAceIsSet(true);
        }
        if (incoming.get(3)) {
          struct.ase = new org.apache.airavata.model.error.AiravataSystemException();
          struct.ase.read(iprot);
          struct.setAseIsSet(true);
        }
        if (incoming.get(4)) {
          struct.ae = new org.apache.airavata.model.error.AuthorizationException();
          struct.ae.read(iprot);
          struct.setAeIsSet(true);
        }
      }
    }

  }

  public static class getAllComputeResourceNames_args implements org.apache.thrift.TBase<getAllComputeResourceNames_args, getAllComputeResourceNames_args._Fields>, java.io.Serializable, Cloneable, Comparable<getAllComputeResourceNames_args>   {
    private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("getAllComputeResourceNames_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 Map<Class<? extends IScheme>, SchemeFactory> schemes = new HashMap<Class<? extends IScheme>, SchemeFactory>();
    static {
      schemes.put(StandardScheme.class, new getAllComputeResourceNames_argsStandardSchemeFactory());
      schemes.put(TupleScheme.class, new getAllComputeResourceNames_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 Map<String, _Fields> byName = new HashMap<String, _Fields>();

      static {
        for (_Fields field : EnumSet.allOf(_Fields.class)) {
          byName.put(field.getFieldName(), field);
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, or null if its not found.
       */
      public static _Fields findByThriftId(int fieldId) {
        switch(fieldId) {
          case 1: // 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 IllegalArgumentException("Field " + fieldId + " doesn't exist!");
        return fields;
      }

      /**
       * Find the _Fields constant that matches name, or null if its not found.
       */
      public static _Fields findByName(String name) {
        return byName.get(name);
      }

      private final short _thriftId;
      private final String _fieldName;

      _Fields(short thriftId, String fieldName) {
        _thriftId = thriftId;
        _fieldName = fieldName;
      }

      public short getThriftFieldId() {
        return _thriftId;
      }

      public String getFieldName() {
        return _fieldName;
      }
    }

    // isset id assignments
    public static final Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
    static {
      Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new EnumMap<_Fields, org.apache.thrift.meta_data.FieldMetaData>(_Fields.class);
      tmpMap.put(_Fields.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 = Collections.unmodifiableMap(tmpMap);
      org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(getAllComputeResourceNames_args.class, metaDataMap);
    }

    public getAllComputeResourceNames_args() {
    }

    public getAllComputeResourceNames_args(
      org.apache.airavata.model.security.AuthzToken authzToken)
    {
      this();
      this.authzToken = authzToken;
    }

    /**
     * Performs a deep copy on <i>other</i>.
     */
    public getAllComputeResourceNames_args(getAllComputeResourceNames_args other) {
      if (other.isSetAuthzToken()) {
        this.authzToken = new org.apache.airavata.model.security.AuthzToken(other.authzToken);
      }
    }

    public getAllComputeResourceNames_args deepCopy() {
      return new getAllComputeResourceNames_args(this);
    }

    @Override
    public void clear() {
      this.authzToken = null;
    }

    public org.apache.airavata.model.security.AuthzToken getAuthzToken() {
      return this.authzToken;
    }

    public getAllComputeResourceNames_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, Object value) {
      switch (field) {
      case AUTHZ_TOKEN:
        if (value == null) {
          unsetAuthzToken();
        } else {
          setAuthzToken((org.apache.airavata.model.security.AuthzToken)value);
        }
        break;

      }
    }

    public Object getFieldValue(_Fields field) {
      switch (field) {
      case AUTHZ_TOKEN:
        return getAuthzToken();

      }
      throw new IllegalStateException();
    }

    /** Returns true if field corresponding to fieldID is set (has been assigned a value) and false otherwise */
    public boolean isSet(_Fields field) {
      if (field == null) {
        throw new IllegalArgumentException();
      }

      switch (field) {
      case AUTHZ_TOKEN:
        return isSetAuthzToken();
      }
      throw new IllegalStateException();
    }

    @Override
    public boolean equals(Object that) {
      if (that == null)
        return false;
      if (that instanceof getAllComputeResourceNames_args)
        return this.equals((getAllComputeResourceNames_args)that);
      return false;
    }

    public boolean equals(getAllComputeResourceNames_args that) {
      if (that == null)
        return false;

      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() {
      List<Object> list = new ArrayList<Object>();

      boolean present_authzToken = true && (isSetAuthzToken());
      list.add(present_authzToken);
      if (present_authzToken)
        list.add(authzToken);

      return list.hashCode();
    }

    @Override
    public int compareTo(getAllComputeResourceNames_args other) {
      if (!getClass().equals(other.getClass())) {
        return getClass().getName().compareTo(other.getClass().getName());
      }

      int lastComparison = 0;

      lastComparison = 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 {
      schemes.get(iprot.getScheme()).getScheme().read(iprot, this);
    }

    public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException {
      schemes.get(oprot.getScheme()).getScheme().write(oprot, this);
    }

    @Override
    public String toString() {
      StringBuilder sb = new StringBuilder("getAllComputeResourceNames_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, 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 getAllComputeResourceNames_argsStandardSchemeFactory implements SchemeFactory {
      public getAllComputeResourceNames_argsStandardScheme getScheme() {
        return new getAllComputeResourceNames_argsStandardScheme();
      }
    }

    private static class getAllComputeResourceNames_argsStandardScheme extends StandardScheme<getAllComputeResourceNames_args> {

      public void read(org.apache.thrift.protocol.TProtocol iprot, getAllComputeResourceNames_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, getAllComputeResourceNames_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 getAllComputeResourceNames_argsTupleSchemeFactory implements SchemeFactory {
      public getAllComputeResourceNames_argsTupleScheme getScheme() {
        return new getAllComputeResourceNames_argsTupleScheme();
      }
    }

    private static class getAllComputeResourceNames_argsTupleScheme extends TupleScheme<getAllComputeResourceNames_args> {

      @Override
      public void write(org.apache.thrift.protocol.TProtocol prot, getAllComputeResourceNames_args struct) throws org.apache.thrift.TException {
        TTupleProtocol oprot = (TTupleProtocol) prot;
        struct.authzToken.write(oprot);
      }

      @Override
      public void read(org.apache.thrift.protocol.TProtocol prot, getAllComputeResourceNames_args struct) throws org.apache.thrift.TException {
        TTupleProtocol iprot = (TTupleProtocol) prot;
        struct.authzToken = new org.apache.airavata.model.security.AuthzToken();
        struct.authzToken.read(iprot);
        struct.setAuthzTokenIsSet(true);
      }
    }

  }

  public static class getAllComputeResourceNames_result implements org.apache.thrift.TBase<getAllComputeResourceNames_result, getAllComputeResourceNames_result._Fields>, java.io.Serializable, Cloneable, Comparable<getAllComputeResourceNames_result>   {
    private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("getAllComputeResourceNames_result");

    private static final org.apache.thrift.protocol.TField SUCCESS_FIELD_DESC = new org.apache.thrift.protocol.TField("success", org.apache.thrift.protocol.TType.MAP, (short)0);
    private static final org.apache.thrift.protocol.TField IRE_FIELD_DESC = new org.apache.thrift.protocol.TField("ire", org.apache.thrift.protocol.TType.STRUCT, (short)1);
    private static final org.apache.thrift.protocol.TField ACE_FIELD_DESC = new org.apache.thrift.protocol.TField("ace", org.apache.thrift.protocol.TType.STRUCT, (short)2);
    private static final org.apache.thrift.protocol.TField ASE_FIELD_DESC = new org.apache.thrift.protocol.TField("ase", org.apache.thrift.protocol.TType.STRUCT, (short)3);
    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)4);

    private static final Map<Class<? extends IScheme>, SchemeFactory> schemes = new HashMap<Class<? extends IScheme>, SchemeFactory>();
    static {
      schemes.put(StandardScheme.class, new getAllComputeResourceNames_resultStandardSchemeFactory());
      schemes.put(TupleScheme.class, new getAllComputeResourceNames_resultTupleSchemeFactory());
    }

    public Map<String,String> success; // required
    public org.apache.airavata.model.error.InvalidRequestException ire; // required
    public org.apache.airavata.model.error.AiravataClientException ace; // required
    public org.apache.airavata.model.error.AiravataSystemException ase; // 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"),
      IRE((short)1, "ire"),
      ACE((short)2, "ace"),
      ASE((short)3, "ase"),
      AE((short)4, "ae");

      private static final Map<String, _Fields> byName = new HashMap<String, _Fields>();

      static {
        for (_Fields field : EnumSet.allOf(_Fields.class)) {
          byName.put(field.getFieldName(), field);
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, or null if its not found.
       */
      public static _Fields findByThriftId(int fieldId) {
        switch(fieldId) {
          case 0: // SUCCESS
            return SUCCESS;
          case 1: // IRE
            return IRE;
          case 2: // ACE
            return ACE;
          case 3: // ASE
            return ASE;
          case 4: // 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 IllegalArgumentException("Field " + fieldId + " doesn't exist!");
        return fields;
      }

      /**
       * Find the _Fields constant that matches name, or null if its not found.
       */
      public static _Fields findByName(String name) {
        return byName.get(name);
      }

      private final short _thriftId;
      private final String _fieldName;

      _Fields(short thriftId, String fieldName) {
        _thriftId = thriftId;
        _fieldName = fieldName;
      }

      public short getThriftFieldId() {
        return _thriftId;
      }

      public String getFieldName() {
        return _fieldName;
      }
    }

    // isset id assignments
    public static final Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
    static {
      Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new EnumMap<_Fields, org.apache.thrift.meta_data.FieldMetaData>(_Fields.class);
      tmpMap.put(_Fields.SUCCESS, new org.apache.thrift.meta_data.FieldMetaData("success", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.MapMetaData(org.apache.thrift.protocol.TType.MAP, 
              new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING), 
              new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING))));
      tmpMap.put(_Fields.IRE, new org.apache.thrift.meta_data.FieldMetaData("ire", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRUCT)));
      tmpMap.put(_Fields.ACE, new org.apache.thrift.meta_data.FieldMetaData("ace", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRUCT)));
      tmpMap.put(_Fields.ASE, new org.apache.thrift.meta_data.FieldMetaData("ase", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRUCT)));
      tmpMap.put(_Fields.AE, new org.apache.thrift.meta_data.FieldMetaData("ae", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRUCT)));
      metaDataMap = Collections.unmodifiableMap(tmpMap);
      org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(getAllComputeResourceNames_result.class, metaDataMap);
    }

    public getAllComputeResourceNames_result() {
    }

    public getAllComputeResourceNames_result(
      Map<String,String> success,
      org.apache.airavata.model.error.InvalidRequestException ire,
      org.apache.airavata.model.error.AiravataClientException ace,
      org.apache.airavata.model.error.AiravataSystemException ase,
      org.apache.airavata.model.error.AuthorizationException ae)
    {
      this();
      this.success = success;
      this.ire = ire;
      this.ace = ace;
      this.ase = ase;
      this.ae = ae;
    }

    /**
     * Performs a deep copy on <i>other</i>.
     */
    public getAllComputeResourceNames_result(getAllComputeResourceNames_result other) {
      if (other.isSetSuccess()) {
        Map<String,String> __this__success = new HashMap<String,String>(other.success);
        this.success = __this__success;
      }
      if (other.isSetIre()) {
        this.ire = new org.apache.airavata.model.error.InvalidRequestException(other.ire);
      }
      if (other.isSetAce()) {
        this.ace = new org.apache.airavata.model.error.AiravataClientException(other.ace);
      }
      if (other.isSetAse()) {
        this.ase = new org.apache.airavata.model.error.AiravataSystemException(other.ase);
      }
      if (other.isSetAe()) {
        this.ae = new org.apache.airavata.model.error.AuthorizationException(other.ae);
      }
    }

    public getAllComputeResourceNames_result deepCopy() {
      return new getAllComputeResourceNames_result(this);
    }

    @Override
    public void clear() {
      this.success = null;
      this.ire = null;
      this.ace = null;
      this.ase = null;
      this.ae = null;
    }

    public int getSuccessSize() {
      return (this.success == null) ? 0 : this.success.size();
    }

    public void putToSuccess(String key, String val) {
      if (this.success == null) {
        this.success = new HashMap<String,String>();
      }
      this.success.put(key, val);
    }

    public Map<String,String> getSuccess() {
      return this.success;
    }

    public getAllComputeResourceNames_result setSuccess(Map<String,String> success) {
      this.success = success;
      return this;
    }

    public void unsetSuccess() {
      this.success = null;
    }

    /** Returns true if field success is set (has been assigned a value) and false otherwise */
    public boolean isSetSuccess() {
      return this.success != null;
    }

    public void setSuccessIsSet(boolean value) {
      if (!value) {
        this.success = null;
      }
    }

    public org.apache.airavata.model.error.InvalidRequestException getIre() {
      return this.ire;
    }

    public getAllComputeResourceNames_result setIre(org.apache.airavata.model.error.InvalidRequestException ire) {
      this.ire = ire;
      return this;
    }

    public void unsetIre() {
      this.ire = null;
    }

    /** Returns true if field ire is set (has been assigned a value) and false otherwise */
    public boolean isSetIre() {
      return this.ire != null;
    }

    public void setIreIsSet(boolean value) {
      if (!value) {
        this.ire = null;
      }
    }

    public org.apache.airavata.model.error.AiravataClientException getAce() {
      return this.ace;
    }

    public getAllComputeResourceNames_result setAce(org.apache.airavata.model.error.AiravataClientException ace) {
      this.ace = ace;
      return this;
    }

    public void unsetAce() {
      this.ace = null;
    }

    /** Returns true if field ace is set (has been assigned a value) and false otherwise */
    public boolean isSetAce() {
      return this.ace != null;
    }

    public void setAceIsSet(boolean value) {
      if (!value) {
        this.ace = null;
      }
    }

    public org.apache.airavata.model.error.AiravataSystemException getAse() {
      return this.ase;
    }

    public getAllComputeResourceNames_result setAse(org.apache.airavata.model.error.AiravataSystemException ase) {
      this.ase = ase;
      return this;
    }

    public void unsetAse() {
      this.ase = null;
    }

    /** Returns true if field ase is set (has been assigned a value) and false otherwise */
    public boolean isSetAse() {
      return this.ase != null;
    }

    public void setAseIsSet(boolean value) {
      if (!value) {
        this.ase = null;
      }
    }

    public org.apache.airavata.model.error.AuthorizationException getAe() {
      return this.ae;
    }

    public getAllComputeResourceNames_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, Object value) {
      switch (field) {
      case SUCCESS:
        if (value == null) {
          unsetSuccess();
        } else {
          setSuccess((Map<String,String>)value);
        }
        break;

      case IRE:
        if (value == null) {
          unsetIre();
        } else {
          setIre((org.apache.airavata.model.error.InvalidRequestException)value);
        }
        break;

      case ACE:
        if (value == null) {
          unsetAce();
        } else {
          setAce((org.apache.airavata.model.error.AiravataClientException)value);
        }
        break;

      case ASE:
        if (value == null) {
          unsetAse();
        } else {
          setAse((org.apache.airavata.model.error.AiravataSystemException)value);
        }
        break;

      case AE:
        if (value == null) {
          unsetAe();
        } else {
          setAe((org.apache.airavata.model.error.AuthorizationException)value);
        }
        break;

      }
    }

    public Object getFieldValue(_Fields field) {
      switch (field) {
      case SUCCESS:
        return getSuccess();

      case IRE:
        return getIre();

      case ACE:
        return getAce();

      case ASE:
        return getAse();

      case AE:
        return getAe();

      }
      throw new IllegalStateException();
    }

    /** Returns true if field corresponding to fieldID is set (has been assigned a value) and false otherwise */
    public boolean isSet(_Fields field) {
      if (field == null) {
        throw new IllegalArgumentException();
      }

      switch (field) {
      case SUCCESS:
        return isSetSuccess();
      case IRE:
        return isSetIre();
      case ACE:
        return isSetAce();
      case ASE:
        return isSetAse();
      case AE:
        return isSetAe();
      }
      throw new IllegalStateException();
    }

    @Override
    public boolean equals(Object that) {
      if (that == null)
        return false;
      if (that instanceof getAllComputeResourceNames_result)
        return this.equals((getAllComputeResourceNames_result)that);
      return false;
    }

    public boolean equals(getAllComputeResourceNames_result that) {
      if (that == null)
        return false;

      boolean this_present_success = true && this.isSetSuccess();
      boolean that_present_success = true && that.isSetSuccess();
      if (this_present_success || that_present_success) {
        if (!(this_present_success && that_present_success))
          return false;
        if (!this.success.equals(that.success))
          return false;
      }

      boolean this_present_ire = true && this.isSetIre();
      boolean that_present_ire = true && that.isSetIre();
      if (this_present_ire || that_present_ire) {
        if (!(this_present_ire && that_present_ire))
          return false;
        if (!this.ire.equals(that.ire))
          return false;
      }

      boolean this_present_ace = true && this.isSetAce();
      boolean that_present_ace = true && that.isSetAce();
      if (this_present_ace || that_present_ace) {
        if (!(this_present_ace && that_present_ace))
          return false;
        if (!this.ace.equals(that.ace))
          return false;
      }

      boolean this_present_ase = true && this.isSetAse();
      boolean that_present_ase = true && that.isSetAse();
      if (this_present_ase || that_present_ase) {
        if (!(this_present_ase && that_present_ase))
          return false;
        if (!this.ase.equals(that.ase))
          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() {
      List<Object> list = new ArrayList<Object>();

      boolean present_success = true && (isSetSuccess());
      list.add(present_success);
      if (present_success)
        list.add(success);

      boolean present_ire = true && (isSetIre());
      list.add(present_ire);
      if (present_ire)
        list.add(ire);

      boolean present_ace = true && (isSetAce());
      list.add(present_ace);
      if (present_ace)
        list.add(ace);

      boolean present_ase = true && (isSetAse());
      list.add(present_ase);
      if (present_ase)
        list.add(ase);

      boolean present_ae = true && (isSetAe());
      list.add(present_ae);
      if (present_ae)
        list.add(ae);

      return list.hashCode();
    }

    @Override
    public int compareTo(getAllComputeResourceNames_result other) {
      if (!getClass().equals(other.getClass())) {
        return getClass().getName().compareTo(other.getClass().getName());
      }

      int lastComparison = 0;

      lastComparison = Boolean.valueOf(isSetSuccess()).compareTo(other.isSetSuccess());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetSuccess()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.success, other.success);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = Boolean.valueOf(isSetIre()).compareTo(other.isSetIre());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetIre()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.ire, other.ire);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = Boolean.valueOf(isSetAce()).compareTo(other.isSetAce());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetAce()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.ace, other.ace);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = Boolean.valueOf(isSetAse()).compareTo(other.isSetAse());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetAse()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.ase, other.ase);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = 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 {
      schemes.get(iprot.getScheme()).getScheme().read(iprot, this);
    }

    public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException {
      schemes.get(oprot.getScheme()).getScheme().write(oprot, this);
      }

    @Override
    public String toString() {
      StringBuilder sb = new StringBuilder("getAllComputeResourceNames_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("ire:");
      if (this.ire == null) {
        sb.append("null");
      } else {
        sb.append(this.ire);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("ace:");
      if (this.ace == null) {
        sb.append("null");
      } else {
        sb.append(this.ace);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("ase:");
      if (this.ase == null) {
        sb.append("null");
      } else {
        sb.append(this.ase);
      }
      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, 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 getAllComputeResourceNames_resultStandardSchemeFactory implements SchemeFactory {
      public getAllComputeResourceNames_resultStandardScheme getScheme() {
        return new getAllComputeResourceNames_resultStandardScheme();
      }
    }

    private static class getAllComputeResourceNames_resultStandardScheme extends StandardScheme<getAllComputeResourceNames_result> {

      public void read(org.apache.thrift.protocol.TProtocol iprot, getAllComputeResourceNames_result struct) throws org.apache.thrift.TException {
        org.apache.thrift.protocol.TField schemeField;
        iprot.readStructBegin();
        while (true)
        {
          schemeField = iprot.readFieldBegin();
          if (schemeField.type == org.apache.thrift.protocol.TType.STOP) { 
            break;
          }
          switch (schemeField.id) {
            case 0: // SUCCESS
              if (schemeField.type == org.apache.thrift.protocol.TType.MAP) {
                {
                  org.apache.thrift.protocol.TMap _map218 = iprot.readMapBegin();
                  struct.success = new HashMap<String,String>(2*_map218.size);
                  String _key219;
                  String _val220;
                  for (int _i221 = 0; _i221 < _map218.size; ++_i221)
                  {
                    _key219 = iprot.readString();
                    _val220 = iprot.readString();
                    struct.success.put(_key219, _val220);
                  }
                  iprot.readMapEnd();
                }
                struct.setSuccessIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 1: // IRE
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.ire = new org.apache.airavata.model.error.InvalidRequestException();
                struct.ire.read(iprot);
                struct.setIreIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 2: // ACE
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.ace = new org.apache.airavata.model.error.AiravataClientException();
                struct.ace.read(iprot);
                struct.setAceIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 3: // ASE
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.ase = new org.apache.airavata.model.error.AiravataSystemException();
                struct.ase.read(iprot);
                struct.setAseIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 4: // 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, getAllComputeResourceNames_result struct) throws org.apache.thrift.TException {
        struct.validate();

        oprot.writeStructBegin(STRUCT_DESC);
        if (struct.success != null) {
          oprot.writeFieldBegin(SUCCESS_FIELD_DESC);
          {
            oprot.writeMapBegin(new org.apache.thrift.protocol.TMap(org.apache.thrift.protocol.TType.STRING, org.apache.thrift.protocol.TType.STRING, struct.success.size()));
            for (Map.Entry<String, String> _iter222 : struct.success.entrySet())
            {
              oprot.writeString(_iter222.getKey());
              oprot.writeString(_iter222.getValue());
            }
            oprot.writeMapEnd();
          }
          oprot.writeFieldEnd();
        }
        if (struct.ire != null) {
          oprot.writeFieldBegin(IRE_FIELD_DESC);
          struct.ire.write(oprot);
          oprot.writeFieldEnd();
        }
        if (struct.ace != null) {
          oprot.writeFieldBegin(ACE_FIELD_DESC);
          struct.ace.write(oprot);
          oprot.writeFieldEnd();
        }
        if (struct.ase != null) {
          oprot.writeFieldBegin(ASE_FIELD_DESC);
          struct.ase.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 getAllComputeResourceNames_resultTupleSchemeFactory implements SchemeFactory {
      public getAllComputeResourceNames_resultTupleScheme getScheme() {
        return new getAllComputeResourceNames_resultTupleScheme();
      }
    }

    private static class getAllComputeResourceNames_resultTupleScheme extends TupleScheme<getAllComputeResourceNames_result> {

      @Override
      public void write(org.apache.thrift.protocol.TProtocol prot, getAllComputeResourceNames_result struct) throws org.apache.thrift.TException {
        TTupleProtocol oprot = (TTupleProtocol) prot;
        BitSet optionals = new BitSet();
        if (struct.isSetSuccess()) {
          optionals.set(0);
        }
        if (struct.isSetIre()) {
          optionals.set(1);
        }
        if (struct.isSetAce()) {
          optionals.set(2);
        }
        if (struct.isSetAse()) {
          optionals.set(3);
        }
        if (struct.isSetAe()) {
          optionals.set(4);
        }
        oprot.writeBitSet(optionals, 5);
        if (struct.isSetSuccess()) {
          {
            oprot.writeI32(struct.success.size());
            for (Map.Entry<String, String> _iter223 : struct.success.entrySet())
            {
              oprot.writeString(_iter223.getKey());
              oprot.writeString(_iter223.getValue());
            }
          }
        }
        if (struct.isSetIre()) {
          struct.ire.write(oprot);
        }
        if (struct.isSetAce()) {
          struct.ace.write(oprot);
        }
        if (struct.isSetAse()) {
          struct.ase.write(oprot);
        }
        if (struct.isSetAe()) {
          struct.ae.write(oprot);
        }
      }

      @Override
      public void read(org.apache.thrift.protocol.TProtocol prot, getAllComputeResourceNames_result struct) throws org.apache.thrift.TException {
        TTupleProtocol iprot = (TTupleProtocol) prot;
        BitSet incoming = iprot.readBitSet(5);
        if (incoming.get(0)) {
          {
            org.apache.thrift.protocol.TMap _map224 = new org.apache.thrift.protocol.TMap(org.apache.thrift.protocol.TType.STRING, org.apache.thrift.protocol.TType.STRING, iprot.readI32());
            struct.success = new HashMap<String,String>(2*_map224.size);
            String _key225;
            String _val226;
            for (int _i227 = 0; _i227 < _map224.size; ++_i227)
            {
              _key225 = iprot.readString();
              _val226 = iprot.readString();
              struct.success.put(_key225, _val226);
            }
          }
          struct.setSuccessIsSet(true);
        }
        if (incoming.get(1)) {
          struct.ire = new org.apache.airavata.model.error.InvalidRequestException();
          struct.ire.read(iprot);
          struct.setIreIsSet(true);
        }
        if (incoming.get(2)) {
          struct.ace = new org.apache.airavata.model.error.AiravataClientException();
          struct.ace.read(iprot);
          struct.setAceIsSet(true);
        }
        if (incoming.get(3)) {
          struct.ase = new org.apache.airavata.model.error.AiravataSystemException();
          struct.ase.read(iprot);
          struct.setAseIsSet(true);
        }
        if (incoming.get(4)) {
          struct.ae = new org.apache.airavata.model.error.AuthorizationException();
          struct.ae.read(iprot);
          struct.setAeIsSet(true);
        }
      }
    }

  }

  public static class updateComputeResource_args implements org.apache.thrift.TBase<updateComputeResource_args, updateComputeResource_args._Fields>, java.io.Serializable, Cloneable, Comparable<updateComputeResource_args>   {
    private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("updateComputeResource_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 COMPUTE_RESOURCE_ID_FIELD_DESC = new org.apache.thrift.protocol.TField("computeResourceId", org.apache.thrift.protocol.TType.STRING, (short)2);
    private static final org.apache.thrift.protocol.TField COMPUTE_RESOURCE_DESCRIPTION_FIELD_DESC = new org.apache.thrift.protocol.TField("computeResourceDescription", org.apache.thrift.protocol.TType.STRUCT, (short)3);

    private static final Map<Class<? extends IScheme>, SchemeFactory> schemes = new HashMap<Class<? extends IScheme>, SchemeFactory>();
    static {
      schemes.put(StandardScheme.class, new updateComputeResource_argsStandardSchemeFactory());
      schemes.put(TupleScheme.class, new updateComputeResource_argsTupleSchemeFactory());
    }

    public org.apache.airavata.model.security.AuthzToken authzToken; // required
    public String computeResourceId; // required
    public org.apache.airavata.model.appcatalog.computeresource.ComputeResourceDescription computeResourceDescription; // required

    /** 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"),
      COMPUTE_RESOURCE_ID((short)2, "computeResourceId"),
      COMPUTE_RESOURCE_DESCRIPTION((short)3, "computeResourceDescription");

      private static final Map<String, _Fields> byName = new HashMap<String, _Fields>();

      static {
        for (_Fields field : EnumSet.allOf(_Fields.class)) {
          byName.put(field.getFieldName(), field);
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, or null if its not found.
       */
      public static _Fields findByThriftId(int fieldId) {
        switch(fieldId) {
          case 1: // AUTHZ_TOKEN
            return AUTHZ_TOKEN;
          case 2: // COMPUTE_RESOURCE_ID
            return COMPUTE_RESOURCE_ID;
          case 3: // COMPUTE_RESOURCE_DESCRIPTION
            return COMPUTE_RESOURCE_DESCRIPTION;
          default:
            return null;
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, throwing an exception
       * if it is not found.
       */
      public static _Fields findByThriftIdOrThrow(int fieldId) {
        _Fields fields = findByThriftId(fieldId);
        if (fields == null) throw new IllegalArgumentException("Field " + fieldId + " doesn't exist!");
        return fields;
      }

      /**
       * Find the _Fields constant that matches name, or null if its not found.
       */
      public static _Fields findByName(String name) {
        return byName.get(name);
      }

      private final short _thriftId;
      private final String _fieldName;

      _Fields(short thriftId, String fieldName) {
        _thriftId = thriftId;
        _fieldName = fieldName;
      }

      public short getThriftFieldId() {
        return _thriftId;
      }

      public String getFieldName() {
        return _fieldName;
      }
    }

    // isset id assignments
    public static final Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
    static {
      Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new EnumMap<_Fields, org.apache.thrift.meta_data.FieldMetaData>(_Fields.class);
      tmpMap.put(_Fields.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.COMPUTE_RESOURCE_ID, new org.apache.thrift.meta_data.FieldMetaData("computeResourceId", org.apache.thrift.TFieldRequirementType.REQUIRED, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING)));
      tmpMap.put(_Fields.COMPUTE_RESOURCE_DESCRIPTION, new org.apache.thrift.meta_data.FieldMetaData("computeResourceDescription", org.apache.thrift.TFieldRequirementType.REQUIRED, 
          new org.apache.thrift.meta_data.StructMetaData(org.apache.thrift.protocol.TType.STRUCT, org.apache.airavata.model.appcatalog.computeresource.ComputeResourceDescription.class)));
      metaDataMap = Collections.unmodifiableMap(tmpMap);
      org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(updateComputeResource_args.class, metaDataMap);
    }

    public updateComputeResource_args() {
    }

    public updateComputeResource_args(
      org.apache.airavata.model.security.AuthzToken authzToken,
      String computeResourceId,
      org.apache.airavata.model.appcatalog.computeresource.ComputeResourceDescription computeResourceDescription)
    {
      this();
      this.authzToken = authzToken;
      this.computeResourceId = computeResourceId;
      this.computeResourceDescription = computeResourceDescription;
    }

    /**
     * Performs a deep copy on <i>other</i>.
     */
    public updateComputeResource_args(updateComputeResource_args other) {
      if (other.isSetAuthzToken()) {
        this.authzToken = new org.apache.airavata.model.security.AuthzToken(other.authzToken);
      }
      if (other.isSetComputeResourceId()) {
        this.computeResourceId = other.computeResourceId;
      }
      if (other.isSetComputeResourceDescription()) {
        this.computeResourceDescription = new org.apache.airavata.model.appcatalog.computeresource.ComputeResourceDescription(other.computeResourceDescription);
      }
    }

    public updateComputeResource_args deepCopy() {
      return new updateComputeResource_args(this);
    }

    @Override
    public void clear() {
      this.authzToken = null;
      this.computeResourceId = null;
      this.computeResourceDescription = null;
    }

    public org.apache.airavata.model.security.AuthzToken getAuthzToken() {
      return this.authzToken;
    }

    public updateComputeResource_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 String getComputeResourceId() {
      return this.computeResourceId;
    }

    public updateComputeResource_args setComputeResourceId(String computeResourceId) {
      this.computeResourceId = computeResourceId;
      return this;
    }

    public void unsetComputeResourceId() {
      this.computeResourceId = null;
    }

    /** Returns true if field computeResourceId is set (has been assigned a value) and false otherwise */
    public boolean isSetComputeResourceId() {
      return this.computeResourceId != null;
    }

    public void setComputeResourceIdIsSet(boolean value) {
      if (!value) {
        this.computeResourceId = null;
      }
    }

    public org.apache.airavata.model.appcatalog.computeresource.ComputeResourceDescription getComputeResourceDescription() {
      return this.computeResourceDescription;
    }

    public updateComputeResource_args setComputeResourceDescription(org.apache.airavata.model.appcatalog.computeresource.ComputeResourceDescription computeResourceDescription) {
      this.computeResourceDescription = computeResourceDescription;
      return this;
    }

    public void unsetComputeResourceDescription() {
      this.computeResourceDescription = null;
    }

    /** Returns true if field computeResourceDescription is set (has been assigned a value) and false otherwise */
    public boolean isSetComputeResourceDescription() {
      return this.computeResourceDescription != null;
    }

    public void setComputeResourceDescriptionIsSet(boolean value) {
      if (!value) {
        this.computeResourceDescription = null;
      }
    }

    public void setFieldValue(_Fields field, Object value) {
      switch (field) {
      case AUTHZ_TOKEN:
        if (value == null) {
          unsetAuthzToken();
        } else {
          setAuthzToken((org.apache.airavata.model.security.AuthzToken)value);
        }
        break;

      case COMPUTE_RESOURCE_ID:
        if (value == null) {
          unsetComputeResourceId();
        } else {
          setComputeResourceId((String)value);
        }
        break;

      case COMPUTE_RESOURCE_DESCRIPTION:
        if (value == null) {
          unsetComputeResourceDescription();
        } else {
          setComputeResourceDescription((org.apache.airavata.model.appcatalog.computeresource.ComputeResourceDescription)value);
        }
        break;

      }
    }

    public Object getFieldValue(_Fields field) {
      switch (field) {
      case AUTHZ_TOKEN:
        return getAuthzToken();

      case COMPUTE_RESOURCE_ID:
        return getComputeResourceId();

      case COMPUTE_RESOURCE_DESCRIPTION:
        return getComputeResourceDescription();

      }
      throw new IllegalStateException();
    }

    /** Returns true if field corresponding to fieldID is set (has been assigned a value) and false otherwise */
    public boolean isSet(_Fields field) {
      if (field == null) {
        throw new IllegalArgumentException();
      }

      switch (field) {
      case AUTHZ_TOKEN:
        return isSetAuthzToken();
      case COMPUTE_RESOURCE_ID:
        return isSetComputeResourceId();
      case COMPUTE_RESOURCE_DESCRIPTION:
        return isSetComputeResourceDescription();
      }
      throw new IllegalStateException();
    }

    @Override
    public boolean equals(Object that) {
      if (that == null)
        return false;
      if (that instanceof updateComputeResource_args)
        return this.equals((updateComputeResource_args)that);
      return false;
    }

    public boolean equals(updateComputeResource_args that) {
      if (that == null)
        return false;

      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_computeResourceId = true && this.isSetComputeResourceId();
      boolean that_present_computeResourceId = true && that.isSetComputeResourceId();
      if (this_present_computeResourceId || that_present_computeResourceId) {
        if (!(this_present_computeResourceId && that_present_computeResourceId))
          return false;
        if (!this.computeResourceId.equals(that.computeResourceId))
          return false;
      }

      boolean this_present_computeResourceDescription = true && this.isSetComputeResourceDescription();
      boolean that_present_computeResourceDescription = true && that.isSetComputeResourceDescription();
      if (this_present_computeResourceDescription || that_present_computeResourceDescription) {
        if (!(this_present_computeResourceDescription && that_present_computeResourceDescription))
          return false;
        if (!this.computeResourceDescription.equals(that.computeResourceDescription))
          return false;
      }

      return true;
    }

    @Override
    public int hashCode() {
      List<Object> list = new ArrayList<Object>();

      boolean present_authzToken = true && (isSetAuthzToken());
      list.add(present_authzToken);
      if (present_authzToken)
        list.add(authzToken);

      boolean present_computeResourceId = true && (isSetComputeResourceId());
      list.add(present_computeResourceId);
      if (present_computeResourceId)
        list.add(computeResourceId);

      boolean present_computeResourceDescription = true && (isSetComputeResourceDescription());
      list.add(present_computeResourceDescription);
      if (present_computeResourceDescription)
        list.add(computeResourceDescription);

      return list.hashCode();
    }

    @Override
    public int compareTo(updateComputeResource_args other) {
      if (!getClass().equals(other.getClass())) {
        return getClass().getName().compareTo(other.getClass().getName());
      }

      int lastComparison = 0;

      lastComparison = 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 = Boolean.valueOf(isSetComputeResourceId()).compareTo(other.isSetComputeResourceId());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetComputeResourceId()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.computeResourceId, other.computeResourceId);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = Boolean.valueOf(isSetComputeResourceDescription()).compareTo(other.isSetComputeResourceDescription());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetComputeResourceDescription()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.computeResourceDescription, other.computeResourceDescription);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      return 0;
    }

    public _Fields fieldForId(int fieldId) {
      return _Fields.findByThriftId(fieldId);
    }

    public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
      schemes.get(iprot.getScheme()).getScheme().read(iprot, this);
    }

    public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException {
      schemes.get(oprot.getScheme()).getScheme().write(oprot, this);
    }

    @Override
    public String toString() {
      StringBuilder sb = new StringBuilder("updateComputeResource_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("computeResourceId:");
      if (this.computeResourceId == null) {
        sb.append("null");
      } else {
        sb.append(this.computeResourceId);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("computeResourceDescription:");
      if (this.computeResourceDescription == null) {
        sb.append("null");
      } else {
        sb.append(this.computeResourceDescription);
      }
      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 (computeResourceId == null) {
        throw new org.apache.thrift.protocol.TProtocolException("Required field 'computeResourceId' was not present! Struct: " + toString());
      }
      if (computeResourceDescription == null) {
        throw new org.apache.thrift.protocol.TProtocolException("Required field 'computeResourceDescription' was not present! Struct: " + toString());
      }
      // check for sub-struct validity
      if (authzToken != null) {
        authzToken.validate();
      }
      if (computeResourceDescription != null) {
        computeResourceDescription.validate();
      }
    }

    private void writeObject(java.io.ObjectOutputStream out) throws java.io.IOException {
      try {
        write(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(out)));
      } catch (org.apache.thrift.TException te) {
        throw new java.io.IOException(te);
      }
    }

    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, ClassNotFoundException {
      try {
        read(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(in)));
      } catch (org.apache.thrift.TException te) {
        throw new java.io.IOException(te);
      }
    }

    private static class updateComputeResource_argsStandardSchemeFactory implements SchemeFactory {
      public updateComputeResource_argsStandardScheme getScheme() {
        return new updateComputeResource_argsStandardScheme();
      }
    }

    private static class updateComputeResource_argsStandardScheme extends StandardScheme<updateComputeResource_args> {

      public void read(org.apache.thrift.protocol.TProtocol iprot, updateComputeResource_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: // COMPUTE_RESOURCE_ID
              if (schemeField.type == org.apache.thrift.protocol.TType.STRING) {
                struct.computeResourceId = iprot.readString();
                struct.setComputeResourceIdIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 3: // COMPUTE_RESOURCE_DESCRIPTION
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.computeResourceDescription = new org.apache.airavata.model.appcatalog.computeresource.ComputeResourceDescription();
                struct.computeResourceDescription.read(iprot);
                struct.setComputeResourceDescriptionIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            default:
              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
          }
          iprot.readFieldEnd();
        }
        iprot.readStructEnd();

        // check for required fields of primitive type, which can't be checked in the validate method
        struct.validate();
      }

      public void write(org.apache.thrift.protocol.TProtocol oprot, updateComputeResource_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.computeResourceId != null) {
          oprot.writeFieldBegin(COMPUTE_RESOURCE_ID_FIELD_DESC);
          oprot.writeString(struct.computeResourceId);
          oprot.writeFieldEnd();
        }
        if (struct.computeResourceDescription != null) {
          oprot.writeFieldBegin(COMPUTE_RESOURCE_DESCRIPTION_FIELD_DESC);
          struct.computeResourceDescription.write(oprot);
          oprot.writeFieldEnd();
        }
        oprot.writeFieldStop();
        oprot.writeStructEnd();
      }

    }

    private static class updateComputeResource_argsTupleSchemeFactory implements SchemeFactory {
      public updateComputeResource_argsTupleScheme getScheme() {
        return new updateComputeResource_argsTupleScheme();
      }
    }

    private static class updateComputeResource_argsTupleScheme extends TupleScheme<updateComputeResource_args> {

      @Override
      public void write(org.apache.thrift.protocol.TProtocol prot, updateComputeResource_args struct) throws org.apache.thrift.TException {
        TTupleProtocol oprot = (TTupleProtocol) prot;
        struct.authzToken.write(oprot);
        oprot.writeString(struct.computeResourceId);
        struct.computeResourceDescription.write(oprot);
      }

      @Override
      public void read(org.apache.thrift.protocol.TProtocol prot, updateComputeResource_args struct) throws org.apache.thrift.TException {
        TTupleProtocol iprot = (TTupleProtocol) prot;
        struct.authzToken = new org.apache.airavata.model.security.AuthzToken();
        struct.authzToken.read(iprot);
        struct.setAuthzTokenIsSet(true);
        struct.computeResourceId = iprot.readString();
        struct.setComputeResourceIdIsSet(true);
        struct.computeResourceDescription = new org.apache.airavata.model.appcatalog.computeresource.ComputeResourceDescription();
        struct.computeResourceDescription.read(iprot);
        struct.setComputeResourceDescriptionIsSet(true);
      }
    }

  }

  public static class updateComputeResource_result implements org.apache.thrift.TBase<updateComputeResource_result, updateComputeResource_result._Fields>, java.io.Serializable, Cloneable, Comparable<updateComputeResource_result>   {
    private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("updateComputeResource_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 IRE_FIELD_DESC = new org.apache.thrift.protocol.TField("ire", org.apache.thrift.protocol.TType.STRUCT, (short)1);
    private static final org.apache.thrift.protocol.TField ACE_FIELD_DESC = new org.apache.thrift.protocol.TField("ace", org.apache.thrift.protocol.TType.STRUCT, (short)2);
    private static final org.apache.thrift.protocol.TField ASE_FIELD_DESC = new org.apache.thrift.protocol.TField("ase", org.apache.thrift.protocol.TType.STRUCT, (short)3);
    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)4);

    private static final Map<Class<? extends IScheme>, SchemeFactory> schemes = new HashMap<Class<? extends IScheme>, SchemeFactory>();
    static {
      schemes.put(StandardScheme.class, new updateComputeResource_resultStandardSchemeFactory());
      schemes.put(TupleScheme.class, new updateComputeResource_resultTupleSchemeFactory());
    }

    public boolean success; // required
    public org.apache.airavata.model.error.InvalidRequestException ire; // required
    public org.apache.airavata.model.error.AiravataClientException ace; // required
    public org.apache.airavata.model.error.AiravataSystemException ase; // 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"),
      IRE((short)1, "ire"),
      ACE((short)2, "ace"),
      ASE((short)3, "ase"),
      AE((short)4, "ae");

      private static final Map<String, _Fields> byName = new HashMap<String, _Fields>();

      static {
        for (_Fields field : EnumSet.allOf(_Fields.class)) {
          byName.put(field.getFieldName(), field);
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, or null if its not found.
       */
      public static _Fields findByThriftId(int fieldId) {
        switch(fieldId) {
          case 0: // SUCCESS
            return SUCCESS;
          case 1: // IRE
            return IRE;
          case 2: // ACE
            return ACE;
          case 3: // ASE
            return ASE;
          case 4: // 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 IllegalArgumentException("Field " + fieldId + " doesn't exist!");
        return fields;
      }

      /**
       * Find the _Fields constant that matches name, or null if its not found.
       */
      public static _Fields findByName(String name) {
        return byName.get(name);
      }

      private final short _thriftId;
      private final String _fieldName;

      _Fields(short thriftId, String fieldName) {
        _thriftId = thriftId;
        _fieldName = fieldName;
      }

      public short getThriftFieldId() {
        return _thriftId;
      }

      public String getFieldName() {
        return _fieldName;
      }
    }

    // isset id assignments
    private static final int __SUCCESS_ISSET_ID = 0;
    private byte __isset_bitfield = 0;
    public static final Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
    static {
      Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new EnumMap<_Fields, org.apache.thrift.meta_data.FieldMetaData>(_Fields.class);
      tmpMap.put(_Fields.SUCCESS, new org.apache.thrift.meta_data.FieldMetaData("success", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.BOOL)));
      tmpMap.put(_Fields.IRE, new org.apache.thrift.meta_data.FieldMetaData("ire", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRUCT)));
      tmpMap.put(_Fields.ACE, new org.apache.thrift.meta_data.FieldMetaData("ace", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRUCT)));
      tmpMap.put(_Fields.ASE, new org.apache.thrift.meta_data.FieldMetaData("ase", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRUCT)));
      tmpMap.put(_Fields.AE, new org.apache.thrift.meta_data.FieldMetaData("ae", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRUCT)));
      metaDataMap = Collections.unmodifiableMap(tmpMap);
      org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(updateComputeResource_result.class, metaDataMap);
    }

    public updateComputeResource_result() {
    }

    public updateComputeResource_result(
      boolean success,
      org.apache.airavata.model.error.InvalidRequestException ire,
      org.apache.airavata.model.error.AiravataClientException ace,
      org.apache.airavata.model.error.AiravataSystemException ase,
      org.apache.airavata.model.error.AuthorizationException ae)
    {
      this();
      this.success = success;
      setSuccessIsSet(true);
      this.ire = ire;
      this.ace = ace;
      this.ase = ase;
      this.ae = ae;
    }

    /**
     * Performs a deep copy on <i>other</i>.
     */
    public updateComputeResource_result(updateComputeResource_result other) {
      __isset_bitfield = other.__isset_bitfield;
      this.success = other.success;
      if (other.isSetIre()) {
        this.ire = new org.apache.airavata.model.error.InvalidRequestException(other.ire);
      }
      if (other.isSetAce()) {
        this.ace = new org.apache.airavata.model.error.AiravataClientException(other.ace);
      }
      if (other.isSetAse()) {
        this.ase = new org.apache.airavata.model.error.AiravataSystemException(other.ase);
      }
      if (other.isSetAe()) {
        this.ae = new org.apache.airavata.model.error.AuthorizationException(other.ae);
      }
    }

    public updateComputeResource_result deepCopy() {
      return new updateComputeResource_result(this);
    }

    @Override
    public void clear() {
      setSuccessIsSet(false);
      this.success = false;
      this.ire = null;
      this.ace = null;
      this.ase = null;
      this.ae = null;
    }

    public boolean isSuccess() {
      return this.success;
    }

    public updateComputeResource_result setSuccess(boolean success) {
      this.success = success;
      setSuccessIsSet(true);
      return this;
    }

    public void unsetSuccess() {
      __isset_bitfield = EncodingUtils.clearBit(__isset_bitfield, __SUCCESS_ISSET_ID);
    }

    /** Returns true if field success is set (has been assigned a value) and false otherwise */
    public boolean isSetSuccess() {
      return EncodingUtils.testBit(__isset_bitfield, __SUCCESS_ISSET_ID);
    }

    public void setSuccessIsSet(boolean value) {
      __isset_bitfield = EncodingUtils.setBit(__isset_bitfield, __SUCCESS_ISSET_ID, value);
    }

    public org.apache.airavata.model.error.InvalidRequestException getIre() {
      return this.ire;
    }

    public updateComputeResource_result setIre(org.apache.airavata.model.error.InvalidRequestException ire) {
      this.ire = ire;
      return this;
    }

    public void unsetIre() {
      this.ire = null;
    }

    /** Returns true if field ire is set (has been assigned a value) and false otherwise */
    public boolean isSetIre() {
      return this.ire != null;
    }

    public void setIreIsSet(boolean value) {
      if (!value) {
        this.ire = null;
      }
    }

    public org.apache.airavata.model.error.AiravataClientException getAce() {
      return this.ace;
    }

    public updateComputeResource_result setAce(org.apache.airavata.model.error.AiravataClientException ace) {
      this.ace = ace;
      return this;
    }

    public void unsetAce() {
      this.ace = null;
    }

    /** Returns true if field ace is set (has been assigned a value) and false otherwise */
    public boolean isSetAce() {
      return this.ace != null;
    }

    public void setAceIsSet(boolean value) {
      if (!value) {
        this.ace = null;
      }
    }

    public org.apache.airavata.model.error.AiravataSystemException getAse() {
      return this.ase;
    }

    public updateComputeResource_result setAse(org.apache.airavata.model.error.AiravataSystemException ase) {
      this.ase = ase;
      return this;
    }

    public void unsetAse() {
      this.ase = null;
    }

    /** Returns true if field ase is set (has been assigned a value) and false otherwise */
    public boolean isSetAse() {
      return this.ase != null;
    }

    public void setAseIsSet(boolean value) {
      if (!value) {
        this.ase = null;
      }
    }

    public org.apache.airavata.model.error.AuthorizationException getAe() {
      return this.ae;
    }

    public updateComputeResource_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, Object value) {
      switch (field) {
      case SUCCESS:
        if (value == null) {
          unsetSuccess();
        } else {
          setSuccess((Boolean)value);
        }
        break;

      case IRE:
        if (value == null) {
          unsetIre();
        } else {
          setIre((org.apache.airavata.model.error.InvalidRequestException)value);
        }
        break;

      case ACE:
        if (value == null) {
          unsetAce();
        } else {
          setAce((org.apache.airavata.model.error.AiravataClientException)value);
        }
        break;

      case ASE:
        if (value == null) {
          unsetAse();
        } else {
          setAse((org.apache.airavata.model.error.AiravataSystemException)value);
        }
        break;

      case AE:
        if (value == null) {
          unsetAe();
        } else {
          setAe((org.apache.airavata.model.error.AuthorizationException)value);
        }
        break;

      }
    }

    public Object getFieldValue(_Fields field) {
      switch (field) {
      case SUCCESS:
        return Boolean.valueOf(isSuccess());

      case IRE:
        return getIre();

      case ACE:
        return getAce();

      case ASE:
        return getAse();

      case AE:
        return getAe();

      }
      throw new IllegalStateException();
    }

    /** Returns true if field corresponding to fieldID is set (has been assigned a value) and false otherwise */
    public boolean isSet(_Fields field) {
      if (field == null) {
        throw new IllegalArgumentException();
      }

      switch (field) {
      case SUCCESS:
        return isSetSuccess();
      case IRE:
        return isSetIre();
      case ACE:
        return isSetAce();
      case ASE:
        return isSetAse();
      case AE:
        return isSetAe();
      }
      throw new IllegalStateException();
    }

    @Override
    public boolean equals(Object that) {
      if (that == null)
        return false;
      if (that instanceof updateComputeResource_result)
        return this.equals((updateComputeResource_result)that);
      return false;
    }

    public boolean equals(updateComputeResource_result that) {
      if (that == null)
        return false;

      boolean this_present_success = true;
      boolean that_present_success = true;
      if (this_present_success || that_present_success) {
        if (!(this_present_success && that_present_success))
          return false;
        if (this.success != that.success)
          return false;
      }

      boolean this_present_ire = true && this.isSetIre();
      boolean that_present_ire = true && that.isSetIre();
      if (this_present_ire || that_present_ire) {
        if (!(this_present_ire && that_present_ire))
          return false;
        if (!this.ire.equals(that.ire))
          return false;
      }

      boolean this_present_ace = true && this.isSetAce();
      boolean that_present_ace = true && that.isSetAce();
      if (this_present_ace || that_present_ace) {
        if (!(this_present_ace && that_present_ace))
          return false;
        if (!this.ace.equals(that.ace))
          return false;
      }

      boolean this_present_ase = true && this.isSetAse();
      boolean that_present_ase = true && that.isSetAse();
      if (this_present_ase || that_present_ase) {
        if (!(this_present_ase && that_present_ase))
          return false;
        if (!this.ase.equals(that.ase))
          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() {
      List<Object> list = new ArrayList<Object>();

      boolean present_success = true;
      list.add(present_success);
      if (present_success)
        list.add(success);

      boolean present_ire = true && (isSetIre());
      list.add(present_ire);
      if (present_ire)
        list.add(ire);

      boolean present_ace = true && (isSetAce());
      list.add(present_ace);
      if (present_ace)
        list.add(ace);

      boolean present_ase = true && (isSetAse());
      list.add(present_ase);
      if (present_ase)
        list.add(ase);

      boolean present_ae = true && (isSetAe());
      list.add(present_ae);
      if (present_ae)
        list.add(ae);

      return list.hashCode();
    }

    @Override
    public int compareTo(updateComputeResource_result other) {
      if (!getClass().equals(other.getClass())) {
        return getClass().getName().compareTo(other.getClass().getName());
      }

      int lastComparison = 0;

      lastComparison = Boolean.valueOf(isSetSuccess()).compareTo(other.isSetSuccess());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetSuccess()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.success, other.success);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = Boolean.valueOf(isSetIre()).compareTo(other.isSetIre());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetIre()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.ire, other.ire);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = Boolean.valueOf(isSetAce()).compareTo(other.isSetAce());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetAce()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.ace, other.ace);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = Boolean.valueOf(isSetAse()).compareTo(other.isSetAse());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetAse()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.ase, other.ase);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = 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 {
      schemes.get(iprot.getScheme()).getScheme().read(iprot, this);
    }

    public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException {
      schemes.get(oprot.getScheme()).getScheme().write(oprot, this);
      }

    @Override
    public String toString() {
      StringBuilder sb = new StringBuilder("updateComputeResource_result(");
      boolean first = true;

      sb.append("success:");
      sb.append(this.success);
      first = false;
      if (!first) sb.append(", ");
      sb.append("ire:");
      if (this.ire == null) {
        sb.append("null");
      } else {
        sb.append(this.ire);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("ace:");
      if (this.ace == null) {
        sb.append("null");
      } else {
        sb.append(this.ace);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("ase:");
      if (this.ase == null) {
        sb.append("null");
      } else {
        sb.append(this.ase);
      }
      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, 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 updateComputeResource_resultStandardSchemeFactory implements SchemeFactory {
      public updateComputeResource_resultStandardScheme getScheme() {
        return new updateComputeResource_resultStandardScheme();
      }
    }

    private static class updateComputeResource_resultStandardScheme extends StandardScheme<updateComputeResource_result> {

      public void read(org.apache.thrift.protocol.TProtocol iprot, updateComputeResource_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: // IRE
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.ire = new org.apache.airavata.model.error.InvalidRequestException();
                struct.ire.read(iprot);
                struct.setIreIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 2: // ACE
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.ace = new org.apache.airavata.model.error.AiravataClientException();
                struct.ace.read(iprot);
                struct.setAceIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 3: // ASE
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.ase = new org.apache.airavata.model.error.AiravataSystemException();
                struct.ase.read(iprot);
                struct.setAseIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 4: // 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, updateComputeResource_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.ire != null) {
          oprot.writeFieldBegin(IRE_FIELD_DESC);
          struct.ire.write(oprot);
          oprot.writeFieldEnd();
        }
        if (struct.ace != null) {
          oprot.writeFieldBegin(ACE_FIELD_DESC);
          struct.ace.write(oprot);
          oprot.writeFieldEnd();
        }
        if (struct.ase != null) {
          oprot.writeFieldBegin(ASE_FIELD_DESC);
          struct.ase.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 updateComputeResource_resultTupleSchemeFactory implements SchemeFactory {
      public updateComputeResource_resultTupleScheme getScheme() {
        return new updateComputeResource_resultTupleScheme();
      }
    }

    private static class updateComputeResource_resultTupleScheme extends TupleScheme<updateComputeResource_result> {

      @Override
      public void write(org.apache.thrift.protocol.TProtocol prot, updateComputeResource_result struct) throws org.apache.thrift.TException {
        TTupleProtocol oprot = (TTupleProtocol) prot;
        BitSet optionals = new BitSet();
        if (struct.isSetSuccess()) {
          optionals.set(0);
        }
        if (struct.isSetIre()) {
          optionals.set(1);
        }
        if (struct.isSetAce()) {
          optionals.set(2);
        }
        if (struct.isSetAse()) {
          optionals.set(3);
        }
        if (struct.isSetAe()) {
          optionals.set(4);
        }
        oprot.writeBitSet(optionals, 5);
        if (struct.isSetSuccess()) {
          oprot.writeBool(struct.success);
        }
        if (struct.isSetIre()) {
          struct.ire.write(oprot);
        }
        if (struct.isSetAce()) {
          struct.ace.write(oprot);
        }
        if (struct.isSetAse()) {
          struct.ase.write(oprot);
        }
        if (struct.isSetAe()) {
          struct.ae.write(oprot);
        }
      }

      @Override
      public void read(org.apache.thrift.protocol.TProtocol prot, updateComputeResource_result struct) throws org.apache.thrift.TException {
        TTupleProtocol iprot = (TTupleProtocol) prot;
        BitSet incoming = iprot.readBitSet(5);
        if (incoming.get(0)) {
          struct.success = iprot.readBool();
          struct.setSuccessIsSet(true);
        }
        if (incoming.get(1)) {
          struct.ire = new org.apache.airavata.model.error.InvalidRequestException();
          struct.ire.read(iprot);
          struct.setIreIsSet(true);
        }
        if (incoming.get(2)) {
          struct.ace = new org.apache.airavata.model.error.AiravataClientException();
          struct.ace.read(iprot);
          struct.setAceIsSet(true);
        }
        if (incoming.get(3)) {
          struct.ase = new org.apache.airavata.model.error.AiravataSystemException();
          struct.ase.read(iprot);
          struct.setAseIsSet(true);
        }
        if (incoming.get(4)) {
          struct.ae = new org.apache.airavata.model.error.AuthorizationException();
          struct.ae.read(iprot);
          struct.setAeIsSet(true);
        }
      }
    }

  }

  public static class deleteComputeResource_args implements org.apache.thrift.TBase<deleteComputeResource_args, deleteComputeResource_args._Fields>, java.io.Serializable, Cloneable, Comparable<deleteComputeResource_args>   {
    private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("deleteComputeResource_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 COMPUTE_RESOURCE_ID_FIELD_DESC = new org.apache.thrift.protocol.TField("computeResourceId", org.apache.thrift.protocol.TType.STRING, (short)2);

    private static final Map<Class<? extends IScheme>, SchemeFactory> schemes = new HashMap<Class<? extends IScheme>, SchemeFactory>();
    static {
      schemes.put(StandardScheme.class, new deleteComputeResource_argsStandardSchemeFactory());
      schemes.put(TupleScheme.class, new deleteComputeResource_argsTupleSchemeFactory());
    }

    public org.apache.airavata.model.security.AuthzToken authzToken; // required
    public String computeResourceId; // required

    /** 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"),
      COMPUTE_RESOURCE_ID((short)2, "computeResourceId");

      private static final Map<String, _Fields> byName = new HashMap<String, _Fields>();

      static {
        for (_Fields field : EnumSet.allOf(_Fields.class)) {
          byName.put(field.getFieldName(), field);
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, or null if its not found.
       */
      public static _Fields findByThriftId(int fieldId) {
        switch(fieldId) {
          case 1: // AUTHZ_TOKEN
            return AUTHZ_TOKEN;
          case 2: // COMPUTE_RESOURCE_ID
            return COMPUTE_RESOURCE_ID;
          default:
            return null;
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, throwing an exception
       * if it is not found.
       */
      public static _Fields findByThriftIdOrThrow(int fieldId) {
        _Fields fields = findByThriftId(fieldId);
        if (fields == null) throw new IllegalArgumentException("Field " + fieldId + " doesn't exist!");
        return fields;
      }

      /**
       * Find the _Fields constant that matches name, or null if its not found.
       */
      public static _Fields findByName(String name) {
        return byName.get(name);
      }

      private final short _thriftId;
      private final String _fieldName;

      _Fields(short thriftId, String fieldName) {
        _thriftId = thriftId;
        _fieldName = fieldName;
      }

      public short getThriftFieldId() {
        return _thriftId;
      }

      public String getFieldName() {
        return _fieldName;
      }
    }

    // isset id assignments
    public static final Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
    static {
      Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new EnumMap<_Fields, org.apache.thrift.meta_data.FieldMetaData>(_Fields.class);
      tmpMap.put(_Fields.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.COMPUTE_RESOURCE_ID, new org.apache.thrift.meta_data.FieldMetaData("computeResourceId", org.apache.thrift.TFieldRequirementType.REQUIRED, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING)));
      metaDataMap = Collections.unmodifiableMap(tmpMap);
      org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(deleteComputeResource_args.class, metaDataMap);
    }

    public deleteComputeResource_args() {
    }

    public deleteComputeResource_args(
      org.apache.airavata.model.security.AuthzToken authzToken,
      String computeResourceId)
    {
      this();
      this.authzToken = authzToken;
      this.computeResourceId = computeResourceId;
    }

    /**
     * Performs a deep copy on <i>other</i>.
     */
    public deleteComputeResource_args(deleteComputeResource_args other) {
      if (other.isSetAuthzToken()) {
        this.authzToken = new org.apache.airavata.model.security.AuthzToken(other.authzToken);
      }
      if (other.isSetComputeResourceId()) {
        this.computeResourceId = other.computeResourceId;
      }
    }

    public deleteComputeResource_args deepCopy() {
      return new deleteComputeResource_args(this);
    }

    @Override
    public void clear() {
      this.authzToken = null;
      this.computeResourceId = null;
    }

    public org.apache.airavata.model.security.AuthzToken getAuthzToken() {
      return this.authzToken;
    }

    public deleteComputeResource_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 String getComputeResourceId() {
      return this.computeResourceId;
    }

    public deleteComputeResource_args setComputeResourceId(String computeResourceId) {
      this.computeResourceId = computeResourceId;
      return this;
    }

    public void unsetComputeResourceId() {
      this.computeResourceId = null;
    }

    /** Returns true if field computeResourceId is set (has been assigned a value) and false otherwise */
    public boolean isSetComputeResourceId() {
      return this.computeResourceId != null;
    }

    public void setComputeResourceIdIsSet(boolean value) {
      if (!value) {
        this.computeResourceId = null;
      }
    }

    public void setFieldValue(_Fields field, Object value) {
      switch (field) {
      case AUTHZ_TOKEN:
        if (value == null) {
          unsetAuthzToken();
        } else {
          setAuthzToken((org.apache.airavata.model.security.AuthzToken)value);
        }
        break;

      case COMPUTE_RESOURCE_ID:
        if (value == null) {
          unsetComputeResourceId();
        } else {
          setComputeResourceId((String)value);
        }
        break;

      }
    }

    public Object getFieldValue(_Fields field) {
      switch (field) {
      case AUTHZ_TOKEN:
        return getAuthzToken();

      case COMPUTE_RESOURCE_ID:
        return getComputeResourceId();

      }
      throw new IllegalStateException();
    }

    /** Returns true if field corresponding to fieldID is set (has been assigned a value) and false otherwise */
    public boolean isSet(_Fields field) {
      if (field == null) {
        throw new IllegalArgumentException();
      }

      switch (field) {
      case AUTHZ_TOKEN:
        return isSetAuthzToken();
      case COMPUTE_RESOURCE_ID:
        return isSetComputeResourceId();
      }
      throw new IllegalStateException();
    }

    @Override
    public boolean equals(Object that) {
      if (that == null)
        return false;
      if (that instanceof deleteComputeResource_args)
        return this.equals((deleteComputeResource_args)that);
      return false;
    }

    public boolean equals(deleteComputeResource_args that) {
      if (that == null)
        return false;

      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_computeResourceId = true && this.isSetComputeResourceId();
      boolean that_present_computeResourceId = true && that.isSetComputeResourceId();
      if (this_present_computeResourceId || that_present_computeResourceId) {
        if (!(this_present_computeResourceId && that_present_computeResourceId))
          return false;
        if (!this.computeResourceId.equals(that.computeResourceId))
          return false;
      }

      return true;
    }

    @Override
    public int hashCode() {
      List<Object> list = new ArrayList<Object>();

      boolean present_authzToken = true && (isSetAuthzToken());
      list.add(present_authzToken);
      if (present_authzToken)
        list.add(authzToken);

      boolean present_computeResourceId = true && (isSetComputeResourceId());
      list.add(present_computeResourceId);
      if (present_computeResourceId)
        list.add(computeResourceId);

      return list.hashCode();
    }

    @Override
    public int compareTo(deleteComputeResource_args other) {
      if (!getClass().equals(other.getClass())) {
        return getClass().getName().compareTo(other.getClass().getName());
      }

      int lastComparison = 0;

      lastComparison = 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 = Boolean.valueOf(isSetComputeResourceId()).compareTo(other.isSetComputeResourceId());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetComputeResourceId()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.computeResourceId, other.computeResourceId);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      return 0;
    }

    public _Fields fieldForId(int fieldId) {
      return _Fields.findByThriftId(fieldId);
    }

    public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
      schemes.get(iprot.getScheme()).getScheme().read(iprot, this);
    }

    public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException {
      schemes.get(oprot.getScheme()).getScheme().write(oprot, this);
    }

    @Override
    public String toString() {
      StringBuilder sb = new StringBuilder("deleteComputeResource_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("computeResourceId:");
      if (this.computeResourceId == null) {
        sb.append("null");
      } else {
        sb.append(this.computeResourceId);
      }
      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 (computeResourceId == null) {
        throw new org.apache.thrift.protocol.TProtocolException("Required field 'computeResourceId' 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, 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 deleteComputeResource_argsStandardSchemeFactory implements SchemeFactory {
      public deleteComputeResource_argsStandardScheme getScheme() {
        return new deleteComputeResource_argsStandardScheme();
      }
    }

    private static class deleteComputeResource_argsStandardScheme extends StandardScheme<deleteComputeResource_args> {

      public void read(org.apache.thrift.protocol.TProtocol iprot, deleteComputeResource_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: // COMPUTE_RESOURCE_ID
              if (schemeField.type == org.apache.thrift.protocol.TType.STRING) {
                struct.computeResourceId = iprot.readString();
                struct.setComputeResourceIdIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            default:
              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
          }
          iprot.readFieldEnd();
        }
        iprot.readStructEnd();

        // check for required fields of primitive type, which can't be checked in the validate method
        struct.validate();
      }

      public void write(org.apache.thrift.protocol.TProtocol oprot, deleteComputeResource_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.computeResourceId != null) {
          oprot.writeFieldBegin(COMPUTE_RESOURCE_ID_FIELD_DESC);
          oprot.writeString(struct.computeResourceId);
          oprot.writeFieldEnd();
        }
        oprot.writeFieldStop();
        oprot.writeStructEnd();
      }

    }

    private static class deleteComputeResource_argsTupleSchemeFactory implements SchemeFactory {
      public deleteComputeResource_argsTupleScheme getScheme() {
        return new deleteComputeResource_argsTupleScheme();
      }
    }

    private static class deleteComputeResource_argsTupleScheme extends TupleScheme<deleteComputeResource_args> {

      @Override
      public void write(org.apache.thrift.protocol.TProtocol prot, deleteComputeResource_args struct) throws org.apache.thrift.TException {
        TTupleProtocol oprot = (TTupleProtocol) prot;
        struct.authzToken.write(oprot);
        oprot.writeString(struct.computeResourceId);
      }

      @Override
      public void read(org.apache.thrift.protocol.TProtocol prot, deleteComputeResource_args struct) throws org.apache.thrift.TException {
        TTupleProtocol iprot = (TTupleProtocol) prot;
        struct.authzToken = new org.apache.airavata.model.security.AuthzToken();
        struct.authzToken.read(iprot);
        struct.setAuthzTokenIsSet(true);
        struct.computeResourceId = iprot.readString();
        struct.setComputeResourceIdIsSet(true);
      }
    }

  }

  public static class deleteComputeResource_result implements org.apache.thrift.TBase<deleteComputeResource_result, deleteComputeResource_result._Fields>, java.io.Serializable, Cloneable, Comparable<deleteComputeResource_result>   {
    private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("deleteComputeResource_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 IRE_FIELD_DESC = new org.apache.thrift.protocol.TField("ire", org.apache.thrift.protocol.TType.STRUCT, (short)1);
    private static final org.apache.thrift.protocol.TField ACE_FIELD_DESC = new org.apache.thrift.protocol.TField("ace", org.apache.thrift.protocol.TType.STRUCT, (short)2);
    private static final org.apache.thrift.protocol.TField ASE_FIELD_DESC = new org.apache.thrift.protocol.TField("ase", org.apache.thrift.protocol.TType.STRUCT, (short)3);
    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)4);

    private static final Map<Class<? extends IScheme>, SchemeFactory> schemes = new HashMap<Class<? extends IScheme>, SchemeFactory>();
    static {
      schemes.put(StandardScheme.class, new deleteComputeResource_resultStandardSchemeFactory());
      schemes.put(TupleScheme.class, new deleteComputeResource_resultTupleSchemeFactory());
    }

    public boolean success; // required
    public org.apache.airavata.model.error.InvalidRequestException ire; // required
    public org.apache.airavata.model.error.AiravataClientException ace; // required
    public org.apache.airavata.model.error.AiravataSystemException ase; // 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"),
      IRE((short)1, "ire"),
      ACE((short)2, "ace"),
      ASE((short)3, "ase"),
      AE((short)4, "ae");

      private static final Map<String, _Fields> byName = new HashMap<String, _Fields>();

      static {
        for (_Fields field : EnumSet.allOf(_Fields.class)) {
          byName.put(field.getFieldName(), field);
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, or null if its not found.
       */
      public static _Fields findByThriftId(int fieldId) {
        switch(fieldId) {
          case 0: // SUCCESS
            return SUCCESS;
          case 1: // IRE
            return IRE;
          case 2: // ACE
            return ACE;
          case 3: // ASE
            return ASE;
          case 4: // 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 IllegalArgumentException("Field " + fieldId + " doesn't exist!");
        return fields;
      }

      /**
       * Find the _Fields constant that matches name, or null if its not found.
       */
      public static _Fields findByName(String name) {
        return byName.get(name);
      }

      private final short _thriftId;
      private final String _fieldName;

      _Fields(short thriftId, String fieldName) {
        _thriftId = thriftId;
        _fieldName = fieldName;
      }

      public short getThriftFieldId() {
        return _thriftId;
      }

      public String getFieldName() {
        return _fieldName;
      }
    }

    // isset id assignments
    private static final int __SUCCESS_ISSET_ID = 0;
    private byte __isset_bitfield = 0;
    public static final Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
    static {
      Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new EnumMap<_Fields, org.apache.thrift.meta_data.FieldMetaData>(_Fields.class);
      tmpMap.put(_Fields.SUCCESS, new org.apache.thrift.meta_data.FieldMetaData("success", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.BOOL)));
      tmpMap.put(_Fields.IRE, new org.apache.thrift.meta_data.FieldMetaData("ire", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRUCT)));
      tmpMap.put(_Fields.ACE, new org.apache.thrift.meta_data.FieldMetaData("ace", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRUCT)));
      tmpMap.put(_Fields.ASE, new org.apache.thrift.meta_data.FieldMetaData("ase", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRUCT)));
      tmpMap.put(_Fields.AE, new org.apache.thrift.meta_data.FieldMetaData("ae", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRUCT)));
      metaDataMap = Collections.unmodifiableMap(tmpMap);
      org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(deleteComputeResource_result.class, metaDataMap);
    }

    public deleteComputeResource_result() {
    }

    public deleteComputeResource_result(
      boolean success,
      org.apache.airavata.model.error.InvalidRequestException ire,
      org.apache.airavata.model.error.AiravataClientException ace,
      org.apache.airavata.model.error.AiravataSystemException ase,
      org.apache.airavata.model.error.AuthorizationException ae)
    {
      this();
      this.success = success;
      setSuccessIsSet(true);
      this.ire = ire;
      this.ace = ace;
      this.ase = ase;
      this.ae = ae;
    }

    /**
     * Performs a deep copy on <i>other</i>.
     */
    public deleteComputeResource_result(deleteComputeResource_result other) {
      __isset_bitfield = other.__isset_bitfield;
      this.success = other.success;
      if (other.isSetIre()) {
        this.ire = new org.apache.airavata.model.error.InvalidRequestException(other.ire);
      }
      if (other.isSetAce()) {
        this.ace = new org.apache.airavata.model.error.AiravataClientException(other.ace);
      }
      if (other.isSetAse()) {
        this.ase = new org.apache.airavata.model.error.AiravataSystemException(other.ase);
      }
      if (other.isSetAe()) {
        this.ae = new org.apache.airavata.model.error.AuthorizationException(other.ae);
      }
    }

    public deleteComputeResource_result deepCopy() {
      return new deleteComputeResource_result(this);
    }

    @Override
    public void clear() {
      setSuccessIsSet(false);
      this.success = false;
      this.ire = null;
      this.ace = null;
      this.ase = null;
      this.ae = null;
    }

    public boolean isSuccess() {
      return this.success;
    }

    public deleteComputeResource_result setSuccess(boolean success) {
      this.success = success;
      setSuccessIsSet(true);
      return this;
    }

    public void unsetSuccess() {
      __isset_bitfield = EncodingUtils.clearBit(__isset_bitfield, __SUCCESS_ISSET_ID);
    }

    /** Returns true if field success is set (has been assigned a value) and false otherwise */
    public boolean isSetSuccess() {
      return EncodingUtils.testBit(__isset_bitfield, __SUCCESS_ISSET_ID);
    }

    public void setSuccessIsSet(boolean value) {
      __isset_bitfield = EncodingUtils.setBit(__isset_bitfield, __SUCCESS_ISSET_ID, value);
    }

    public org.apache.airavata.model.error.InvalidRequestException getIre() {
      return this.ire;
    }

    public deleteComputeResource_result setIre(org.apache.airavata.model.error.InvalidRequestException ire) {
      this.ire = ire;
      return this;
    }

    public void unsetIre() {
      this.ire = null;
    }

    /** Returns true if field ire is set (has been assigned a value) and false otherwise */
    public boolean isSetIre() {
      return this.ire != null;
    }

    public void setIreIsSet(boolean value) {
      if (!value) {
        this.ire = null;
      }
    }

    public org.apache.airavata.model.error.AiravataClientException getAce() {
      return this.ace;
    }

    public deleteComputeResource_result setAce(org.apache.airavata.model.error.AiravataClientException ace) {
      this.ace = ace;
      return this;
    }

    public void unsetAce() {
      this.ace = null;
    }

    /** Returns true if field ace is set (has been assigned a value) and false otherwise */
    public boolean isSetAce() {
      return this.ace != null;
    }

    public void setAceIsSet(boolean value) {
      if (!value) {
        this.ace = null;
      }
    }

    public org.apache.airavata.model.error.AiravataSystemException getAse() {
      return this.ase;
    }

    public deleteComputeResource_result setAse(org.apache.airavata.model.error.AiravataSystemException ase) {
      this.ase = ase;
      return this;
    }

    public void unsetAse() {
      this.ase = null;
    }

    /** Returns true if field ase is set (has been assigned a value) and false otherwise */
    public boolean isSetAse() {
      return this.ase != null;
    }

    public void setAseIsSet(boolean value) {
      if (!value) {
        this.ase = null;
      }
    }

    public org.apache.airavata.model.error.AuthorizationException getAe() {
      return this.ae;
    }

    public deleteComputeResource_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, Object value) {
      switch (field) {
      case SUCCESS:
        if (value == null) {
          unsetSuccess();
        } else {
          setSuccess((Boolean)value);
        }
        break;

      case IRE:
        if (value == null) {
          unsetIre();
        } else {
          setIre((org.apache.airavata.model.error.InvalidRequestException)value);
        }
        break;

      case ACE:
        if (value == null) {
          unsetAce();
        } else {
          setAce((org.apache.airavata.model.error.AiravataClientException)value);
        }
        break;

      case ASE:
        if (value == null) {
          unsetAse();
        } else {
          setAse((org.apache.airavata.model.error.AiravataSystemException)value);
        }
        break;

      case AE:
        if (value == null) {
          unsetAe();
        } else {
          setAe((org.apache.airavata.model.error.AuthorizationException)value);
        }
        break;

      }
    }

    public Object getFieldValue(_Fields field) {
      switch (field) {
      case SUCCESS:
        return Boolean.valueOf(isSuccess());

      case IRE:
        return getIre();

      case ACE:
        return getAce();

      case ASE:
        return getAse();

      case AE:
        return getAe();

      }
      throw new IllegalStateException();
    }

    /** Returns true if field corresponding to fieldID is set (has been assigned a value) and false otherwise */
    public boolean isSet(_Fields field) {
      if (field == null) {
        throw new IllegalArgumentException();
      }

      switch (field) {
      case SUCCESS:
        return isSetSuccess();
      case IRE:
        return isSetIre();
      case ACE:
        return isSetAce();
      case ASE:
        return isSetAse();
      case AE:
        return isSetAe();
      }
      throw new IllegalStateException();
    }

    @Override
    public boolean equals(Object that) {
      if (that == null)
        return false;
      if (that instanceof deleteComputeResource_result)
        return this.equals((deleteComputeResource_result)that);
      return false;
    }

    public boolean equals(deleteComputeResource_result that) {
      if (that == null)
        return false;

      boolean this_present_success = true;
      boolean that_present_success = true;
      if (this_present_success || that_present_success) {
        if (!(this_present_success && that_present_success))
          return false;
        if (this.success != that.success)
          return false;
      }

      boolean this_present_ire = true && this.isSetIre();
      boolean that_present_ire = true && that.isSetIre();
      if (this_present_ire || that_present_ire) {
        if (!(this_present_ire && that_present_ire))
          return false;
        if (!this.ire.equals(that.ire))
          return false;
      }

      boolean this_present_ace = true && this.isSetAce();
      boolean that_present_ace = true && that.isSetAce();
      if (this_present_ace || that_present_ace) {
        if (!(this_present_ace && that_present_ace))
          return false;
        if (!this.ace.equals(that.ace))
          return false;
      }

      boolean this_present_ase = true && this.isSetAse();
      boolean that_present_ase = true && that.isSetAse();
      if (this_present_ase || that_present_ase) {
        if (!(this_present_ase && that_present_ase))
          return false;
        if (!this.ase.equals(that.ase))
          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() {
      List<Object> list = new ArrayList<Object>();

      boolean present_success = true;
      list.add(present_success);
      if (present_success)
        list.add(success);

      boolean present_ire = true && (isSetIre());
      list.add(present_ire);
      if (present_ire)
        list.add(ire);

      boolean present_ace = true && (isSetAce());
      list.add(present_ace);
      if (present_ace)
        list.add(ace);

      boolean present_ase = true && (isSetAse());
      list.add(present_ase);
      if (present_ase)
        list.add(ase);

      boolean present_ae = true && (isSetAe());
      list.add(present_ae);
      if (present_ae)
        list.add(ae);

      return list.hashCode();
    }

    @Override
    public int compareTo(deleteComputeResource_result other) {
      if (!getClass().equals(other.getClass())) {
        return getClass().getName().compareTo(other.getClass().getName());
      }

      int lastComparison = 0;

      lastComparison = Boolean.valueOf(isSetSuccess()).compareTo(other.isSetSuccess());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetSuccess()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.success, other.success);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = Boolean.valueOf(isSetIre()).compareTo(other.isSetIre());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetIre()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.ire, other.ire);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = Boolean.valueOf(isSetAce()).compareTo(other.isSetAce());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetAce()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.ace, other.ace);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = Boolean.valueOf(isSetAse()).compareTo(other.isSetAse());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetAse()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.ase, other.ase);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = 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 {
      schemes.get(iprot.getScheme()).getScheme().read(iprot, this);
    }

    public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException {
      schemes.get(oprot.getScheme()).getScheme().write(oprot, this);
      }

    @Override
    public String toString() {
      StringBuilder sb = new StringBuilder("deleteComputeResource_result(");
      boolean first = true;

      sb.append("success:");
      sb.append(this.success);
      first = false;
      if (!first) sb.append(", ");
      sb.append("ire:");
      if (this.ire == null) {
        sb.append("null");
      } else {
        sb.append(this.ire);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("ace:");
      if (this.ace == null) {
        sb.append("null");
      } else {
        sb.append(this.ace);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("ase:");
      if (this.ase == null) {
        sb.append("null");
      } else {
        sb.append(this.ase);
      }
      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, 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 deleteComputeResource_resultStandardSchemeFactory implements SchemeFactory {
      public deleteComputeResource_resultStandardScheme getScheme() {
        return new deleteComputeResource_resultStandardScheme();
      }
    }

    private static class deleteComputeResource_resultStandardScheme extends StandardScheme<deleteComputeResource_result> {

      public void read(org.apache.thrift.protocol.TProtocol iprot, deleteComputeResource_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: // IRE
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.ire = new org.apache.airavata.model.error.InvalidRequestException();
                struct.ire.read(iprot);
                struct.setIreIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 2: // ACE
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.ace = new org.apache.airavata.model.error.AiravataClientException();
                struct.ace.read(iprot);
                struct.setAceIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 3: // ASE
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.ase = new org.apache.airavata.model.error.AiravataSystemException();
                struct.ase.read(iprot);
                struct.setAseIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 4: // 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, deleteComputeResource_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.ire != null) {
          oprot.writeFieldBegin(IRE_FIELD_DESC);
          struct.ire.write(oprot);
          oprot.writeFieldEnd();
        }
        if (struct.ace != null) {
          oprot.writeFieldBegin(ACE_FIELD_DESC);
          struct.ace.write(oprot);
          oprot.writeFieldEnd();
        }
        if (struct.ase != null) {
          oprot.writeFieldBegin(ASE_FIELD_DESC);
          struct.ase.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 deleteComputeResource_resultTupleSchemeFactory implements SchemeFactory {
      public deleteComputeResource_resultTupleScheme getScheme() {
        return new deleteComputeResource_resultTupleScheme();
      }
    }

    private static class deleteComputeResource_resultTupleScheme extends TupleScheme<deleteComputeResource_result> {

      @Override
      public void write(org.apache.thrift.protocol.TProtocol prot, deleteComputeResource_result struct) throws org.apache.thrift.TException {
        TTupleProtocol oprot = (TTupleProtocol) prot;
        BitSet optionals = new BitSet();
        if (struct.isSetSuccess()) {
          optionals.set(0);
        }
        if (struct.isSetIre()) {
          optionals.set(1);
        }
        if (struct.isSetAce()) {
          optionals.set(2);
        }
        if (struct.isSetAse()) {
          optionals.set(3);
        }
        if (struct.isSetAe()) {
          optionals.set(4);
        }
        oprot.writeBitSet(optionals, 5);
        if (struct.isSetSuccess()) {
          oprot.writeBool(struct.success);
        }
        if (struct.isSetIre()) {
          struct.ire.write(oprot);
        }
        if (struct.isSetAce()) {
          struct.ace.write(oprot);
        }
        if (struct.isSetAse()) {
          struct.ase.write(oprot);
        }
        if (struct.isSetAe()) {
          struct.ae.write(oprot);
        }
      }

      @Override
      public void read(org.apache.thrift.protocol.TProtocol prot, deleteComputeResource_result struct) throws org.apache.thrift.TException {
        TTupleProtocol iprot = (TTupleProtocol) prot;
        BitSet incoming = iprot.readBitSet(5);
        if (incoming.get(0)) {
          struct.success = iprot.readBool();
          struct.setSuccessIsSet(true);
        }
        if (incoming.get(1)) {
          struct.ire = new org.apache.airavata.model.error.InvalidRequestException();
          struct.ire.read(iprot);
          struct.setIreIsSet(true);
        }
        if (incoming.get(2)) {
          struct.ace = new org.apache.airavata.model.error.AiravataClientException();
          struct.ace.read(iprot);
          struct.setAceIsSet(true);
        }
        if (incoming.get(3)) {
          struct.ase = new org.apache.airavata.model.error.AiravataSystemException();
          struct.ase.read(iprot);
          struct.setAseIsSet(true);
        }
        if (incoming.get(4)) {
          struct.ae = new org.apache.airavata.model.error.AuthorizationException();
          struct.ae.read(iprot);
          struct.setAeIsSet(true);
        }
      }
    }

  }

  public static class addLocalSubmissionDetails_args implements org.apache.thrift.TBase<addLocalSubmissionDetails_args, addLocalSubmissionDetails_args._Fields>, java.io.Serializable, Cloneable, Comparable<addLocalSubmissionDetails_args>   {
    private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("addLocalSubmissionDetails_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 COMPUTE_RESOURCE_ID_FIELD_DESC = new org.apache.thrift.protocol.TField("computeResourceId", org.apache.thrift.protocol.TType.STRING, (short)2);
    private static final org.apache.thrift.protocol.TField PRIORITY_ORDER_FIELD_DESC = new org.apache.thrift.protocol.TField("priorityOrder", org.apache.thrift.protocol.TType.I32, (short)3);
    private static final org.apache.thrift.protocol.TField LOCAL_SUBMISSION_FIELD_DESC = new org.apache.thrift.protocol.TField("localSubmission", org.apache.thrift.protocol.TType.STRUCT, (short)4);

    private static final Map<Class<? extends IScheme>, SchemeFactory> schemes = new HashMap<Class<? extends IScheme>, SchemeFactory>();
    static {
      schemes.put(StandardScheme.class, new addLocalSubmissionDetails_argsStandardSchemeFactory());
      schemes.put(TupleScheme.class, new addLocalSubmissionDetails_argsTupleSchemeFactory());
    }

    public org.apache.airavata.model.security.AuthzToken authzToken; // required
    public String computeResourceId; // required
    public int priorityOrder; // required
    public org.apache.airavata.model.appcatalog.computeresource.LOCALSubmission localSubmission; // required

    /** 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"),
      COMPUTE_RESOURCE_ID((short)2, "computeResourceId"),
      PRIORITY_ORDER((short)3, "priorityOrder"),
      LOCAL_SUBMISSION((short)4, "localSubmission");

      private static final Map<String, _Fields> byName = new HashMap<String, _Fields>();

      static {
        for (_Fields field : EnumSet.allOf(_Fields.class)) {
          byName.put(field.getFieldName(), field);
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, or null if its not found.
       */
      public static _Fields findByThriftId(int fieldId) {
        switch(fieldId) {
          case 1: // AUTHZ_TOKEN
            return AUTHZ_TOKEN;
          case 2: // COMPUTE_RESOURCE_ID
            return COMPUTE_RESOURCE_ID;
          case 3: // PRIORITY_ORDER
            return PRIORITY_ORDER;
          case 4: // LOCAL_SUBMISSION
            return LOCAL_SUBMISSION;
          default:
            return null;
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, throwing an exception
       * if it is not found.
       */
      public static _Fields findByThriftIdOrThrow(int fieldId) {
        _Fields fields = findByThriftId(fieldId);
        if (fields == null) throw new IllegalArgumentException("Field " + fieldId + " doesn't exist!");
        return fields;
      }

      /**
       * Find the _Fields constant that matches name, or null if its not found.
       */
      public static _Fields findByName(String name) {
        return byName.get(name);
      }

      private final short _thriftId;
      private final String _fieldName;

      _Fields(short thriftId, String fieldName) {
        _thriftId = thriftId;
        _fieldName = fieldName;
      }

      public short getThriftFieldId() {
        return _thriftId;
      }

      public String getFieldName() {
        return _fieldName;
      }
    }

    // isset id assignments
    private static final int __PRIORITYORDER_ISSET_ID = 0;
    private byte __isset_bitfield = 0;
    public static final Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
    static {
      Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new EnumMap<_Fields, org.apache.thrift.meta_data.FieldMetaData>(_Fields.class);
      tmpMap.put(_Fields.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.COMPUTE_RESOURCE_ID, new org.apache.thrift.meta_data.FieldMetaData("computeResourceId", org.apache.thrift.TFieldRequirementType.REQUIRED, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING)));
      tmpMap.put(_Fields.PRIORITY_ORDER, new org.apache.thrift.meta_data.FieldMetaData("priorityOrder", org.apache.thrift.TFieldRequirementType.REQUIRED, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.I32)));
      tmpMap.put(_Fields.LOCAL_SUBMISSION, new org.apache.thrift.meta_data.FieldMetaData("localSubmission", org.apache.thrift.TFieldRequirementType.REQUIRED, 
          new org.apache.thrift.meta_data.StructMetaData(org.apache.thrift.protocol.TType.STRUCT, org.apache.airavata.model.appcatalog.computeresource.LOCALSubmission.class)));
      metaDataMap = Collections.unmodifiableMap(tmpMap);
      org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(addLocalSubmissionDetails_args.class, metaDataMap);
    }

    public addLocalSubmissionDetails_args() {
    }

    public addLocalSubmissionDetails_args(
      org.apache.airavata.model.security.AuthzToken authzToken,
      String computeResourceId,
      int priorityOrder,
      org.apache.airavata.model.appcatalog.computeresource.LOCALSubmission localSubmission)
    {
      this();
      this.authzToken = authzToken;
      this.computeResourceId = computeResourceId;
      this.priorityOrder = priorityOrder;
      setPriorityOrderIsSet(true);
      this.localSubmission = localSubmission;
    }

    /**
     * Performs a deep copy on <i>other</i>.
     */
    public addLocalSubmissionDetails_args(addLocalSubmissionDetails_args other) {
      __isset_bitfield = other.__isset_bitfield;
      if (other.isSetAuthzToken()) {
        this.authzToken = new org.apache.airavata.model.security.AuthzToken(other.authzToken);
      }
      if (other.isSetComputeResourceId()) {
        this.computeResourceId = other.computeResourceId;
      }
      this.priorityOrder = other.priorityOrder;
      if (other.isSetLocalSubmission()) {
        this.localSubmission = new org.apache.airavata.model.appcatalog.computeresource.LOCALSubmission(other.localSubmission);
      }
    }

    public addLocalSubmissionDetails_args deepCopy() {
      return new addLocalSubmissionDetails_args(this);
    }

    @Override
    public void clear() {
      this.authzToken = null;
      this.computeResourceId = null;
      setPriorityOrderIsSet(false);
      this.priorityOrder = 0;
      this.localSubmission = null;
    }

    public org.apache.airavata.model.security.AuthzToken getAuthzToken() {
      return this.authzToken;
    }

    public addLocalSubmissionDetails_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 String getComputeResourceId() {
      return this.computeResourceId;
    }

    public addLocalSubmissionDetails_args setComputeResourceId(String computeResourceId) {
      this.computeResourceId = computeResourceId;
      return this;
    }

    public void unsetComputeResourceId() {
      this.computeResourceId = null;
    }

    /** Returns true if field computeResourceId is set (has been assigned a value) and false otherwise */
    public boolean isSetComputeResourceId() {
      return this.computeResourceId != null;
    }

    public void setComputeResourceIdIsSet(boolean value) {
      if (!value) {
        this.computeResourceId = null;
      }
    }

    public int getPriorityOrder() {
      return this.priorityOrder;
    }

    public addLocalSubmissionDetails_args setPriorityOrder(int priorityOrder) {
      this.priorityOrder = priorityOrder;
      setPriorityOrderIsSet(true);
      return this;
    }

    public void unsetPriorityOrder() {
      __isset_bitfield = EncodingUtils.clearBit(__isset_bitfield, __PRIORITYORDER_ISSET_ID);
    }

    /** Returns true if field priorityOrder is set (has been assigned a value) and false otherwise */
    public boolean isSetPriorityOrder() {
      return EncodingUtils.testBit(__isset_bitfield, __PRIORITYORDER_ISSET_ID);
    }

    public void setPriorityOrderIsSet(boolean value) {
      __isset_bitfield = EncodingUtils.setBit(__isset_bitfield, __PRIORITYORDER_ISSET_ID, value);
    }

    public org.apache.airavata.model.appcatalog.computeresource.LOCALSubmission getLocalSubmission() {
      return this.localSubmission;
    }

    public addLocalSubmissionDetails_args setLocalSubmission(org.apache.airavata.model.appcatalog.computeresource.LOCALSubmission localSubmission) {
      this.localSubmission = localSubmission;
      return this;
    }

    public void unsetLocalSubmission() {
      this.localSubmission = null;
    }

    /** Returns true if field localSubmission is set (has been assigned a value) and false otherwise */
    public boolean isSetLocalSubmission() {
      return this.localSubmission != null;
    }

    public void setLocalSubmissionIsSet(boolean value) {
      if (!value) {
        this.localSubmission = null;
      }
    }

    public void setFieldValue(_Fields field, Object value) {
      switch (field) {
      case AUTHZ_TOKEN:
        if (value == null) {
          unsetAuthzToken();
        } else {
          setAuthzToken((org.apache.airavata.model.security.AuthzToken)value);
        }
        break;

      case COMPUTE_RESOURCE_ID:
        if (value == null) {
          unsetComputeResourceId();
        } else {
          setComputeResourceId((String)value);
        }
        break;

      case PRIORITY_ORDER:
        if (value == null) {
          unsetPriorityOrder();
        } else {
          setPriorityOrder((Integer)value);
        }
        break;

      case LOCAL_SUBMISSION:
        if (value == null) {
          unsetLocalSubmission();
        } else {
          setLocalSubmission((org.apache.airavata.model.appcatalog.computeresource.LOCALSubmission)value);
        }
        break;

      }
    }

    public Object getFieldValue(_Fields field) {
      switch (field) {
      case AUTHZ_TOKEN:
        return getAuthzToken();

      case COMPUTE_RESOURCE_ID:
        return getComputeResourceId();

      case PRIORITY_ORDER:
        return Integer.valueOf(getPriorityOrder());

      case LOCAL_SUBMISSION:
        return getLocalSubmission();

      }
      throw new IllegalStateException();
    }

    /** Returns true if field corresponding to fieldID is set (has been assigned a value) and false otherwise */
    public boolean isSet(_Fields field) {
      if (field == null) {
        throw new IllegalArgumentException();
      }

      switch (field) {
      case AUTHZ_TOKEN:
        return isSetAuthzToken();
      case COMPUTE_RESOURCE_ID:
        return isSetComputeResourceId();
      case PRIORITY_ORDER:
        return isSetPriorityOrder();
      case LOCAL_SUBMISSION:
        return isSetLocalSubmission();
      }
      throw new IllegalStateException();
    }

    @Override
    public boolean equals(Object that) {
      if (that == null)
        return false;
      if (that instanceof addLocalSubmissionDetails_args)
        return this.equals((addLocalSubmissionDetails_args)that);
      return false;
    }

    public boolean equals(addLocalSubmissionDetails_args that) {
      if (that == null)
        return false;

      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_computeResourceId = true && this.isSetComputeResourceId();
      boolean that_present_computeResourceId = true && that.isSetComputeResourceId();
      if (this_present_computeResourceId || that_present_computeResourceId) {
        if (!(this_present_computeResourceId && that_present_computeResourceId))
          return false;
        if (!this.computeResourceId.equals(that.computeResourceId))
          return false;
      }

      boolean this_present_priorityOrder = true;
      boolean that_present_priorityOrder = true;
      if (this_present_priorityOrder || that_present_priorityOrder) {
        if (!(this_present_priorityOrder && that_present_priorityOrder))
          return false;
        if (this.priorityOrder != that.priorityOrder)
          return false;
      }

      boolean this_present_localSubmission = true && this.isSetLocalSubmission();
      boolean that_present_localSubmission = true && that.isSetLocalSubmission();
      if (this_present_localSubmission || that_present_localSubmission) {
        if (!(this_present_localSubmission && that_present_localSubmission))
          return false;
        if (!this.localSubmission.equals(that.localSubmission))
          return false;
      }

      return true;
    }

    @Override
    public int hashCode() {
      List<Object> list = new ArrayList<Object>();

      boolean present_authzToken = true && (isSetAuthzToken());
      list.add(present_authzToken);
      if (present_authzToken)
        list.add(authzToken);

      boolean present_computeResourceId = true && (isSetComputeResourceId());
      list.add(present_computeResourceId);
      if (present_computeResourceId)
        list.add(computeResourceId);

      boolean present_priorityOrder = true;
      list.add(present_priorityOrder);
      if (present_priorityOrder)
        list.add(priorityOrder);

      boolean present_localSubmission = true && (isSetLocalSubmission());
      list.add(present_localSubmission);
      if (present_localSubmission)
        list.add(localSubmission);

      return list.hashCode();
    }

    @Override
    public int compareTo(addLocalSubmissionDetails_args other) {
      if (!getClass().equals(other.getClass())) {
        return getClass().getName().compareTo(other.getClass().getName());
      }

      int lastComparison = 0;

      lastComparison = 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 = Boolean.valueOf(isSetComputeResourceId()).compareTo(other.isSetComputeResourceId());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetComputeResourceId()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.computeResourceId, other.computeResourceId);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = Boolean.valueOf(isSetPriorityOrder()).compareTo(other.isSetPriorityOrder());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetPriorityOrder()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.priorityOrder, other.priorityOrder);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = Boolean.valueOf(isSetLocalSubmission()).compareTo(other.isSetLocalSubmission());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetLocalSubmission()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.localSubmission, other.localSubmission);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      return 0;
    }

    public _Fields fieldForId(int fieldId) {
      return _Fields.findByThriftId(fieldId);
    }

    public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
      schemes.get(iprot.getScheme()).getScheme().read(iprot, this);
    }

    public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException {
      schemes.get(oprot.getScheme()).getScheme().write(oprot, this);
    }

    @Override
    public String toString() {
      StringBuilder sb = new StringBuilder("addLocalSubmissionDetails_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("computeResourceId:");
      if (this.computeResourceId == null) {
        sb.append("null");
      } else {
        sb.append(this.computeResourceId);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("priorityOrder:");
      sb.append(this.priorityOrder);
      first = false;
      if (!first) sb.append(", ");
      sb.append("localSubmission:");
      if (this.localSubmission == null) {
        sb.append("null");
      } else {
        sb.append(this.localSubmission);
      }
      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 (computeResourceId == null) {
        throw new org.apache.thrift.protocol.TProtocolException("Required field 'computeResourceId' was not present! Struct: " + toString());
      }
      // alas, we cannot check 'priorityOrder' because it's a primitive and you chose the non-beans generator.
      if (localSubmission == null) {
        throw new org.apache.thrift.protocol.TProtocolException("Required field 'localSubmission' was not present! Struct: " + toString());
      }
      // check for sub-struct validity
      if (authzToken != null) {
        authzToken.validate();
      }
      if (localSubmission != null) {
        localSubmission.validate();
      }
    }

    private void writeObject(java.io.ObjectOutputStream out) throws java.io.IOException {
      try {
        write(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(out)));
      } catch (org.apache.thrift.TException te) {
        throw new java.io.IOException(te);
      }
    }

    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, ClassNotFoundException {
      try {
        // 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 addLocalSubmissionDetails_argsStandardSchemeFactory implements SchemeFactory {
      public addLocalSubmissionDetails_argsStandardScheme getScheme() {
        return new addLocalSubmissionDetails_argsStandardScheme();
      }
    }

    private static class addLocalSubmissionDetails_argsStandardScheme extends StandardScheme<addLocalSubmissionDetails_args> {

      public void read(org.apache.thrift.protocol.TProtocol iprot, addLocalSubmissionDetails_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: // COMPUTE_RESOURCE_ID
              if (schemeField.type == org.apache.thrift.protocol.TType.STRING) {
                struct.computeResourceId = iprot.readString();
                struct.setComputeResourceIdIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 3: // PRIORITY_ORDER
              if (schemeField.type == org.apache.thrift.protocol.TType.I32) {
                struct.priorityOrder = iprot.readI32();
                struct.setPriorityOrderIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 4: // LOCAL_SUBMISSION
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.localSubmission = new org.apache.airavata.model.appcatalog.computeresource.LOCALSubmission();
                struct.localSubmission.read(iprot);
                struct.setLocalSubmissionIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            default:
              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
          }
          iprot.readFieldEnd();
        }
        iprot.readStructEnd();

        // check for required fields of primitive type, which can't be checked in the validate method
        if (!struct.isSetPriorityOrder()) {
          throw new org.apache.thrift.protocol.TProtocolException("Required field 'priorityOrder' was not found in serialized data! Struct: " + toString());
        }
        struct.validate();
      }

      public void write(org.apache.thrift.protocol.TProtocol oprot, addLocalSubmissionDetails_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.computeResourceId != null) {
          oprot.writeFieldBegin(COMPUTE_RESOURCE_ID_FIELD_DESC);
          oprot.writeString(struct.computeResourceId);
          oprot.writeFieldEnd();
        }
        oprot.writeFieldBegin(PRIORITY_ORDER_FIELD_DESC);
        oprot.writeI32(struct.priorityOrder);
        oprot.writeFieldEnd();
        if (struct.localSubmission != null) {
          oprot.writeFieldBegin(LOCAL_SUBMISSION_FIELD_DESC);
          struct.localSubmission.write(oprot);
          oprot.writeFieldEnd();
        }
        oprot.writeFieldStop();
        oprot.writeStructEnd();
      }

    }

    private static class addLocalSubmissionDetails_argsTupleSchemeFactory implements SchemeFactory {
      public addLocalSubmissionDetails_argsTupleScheme getScheme() {
        return new addLocalSubmissionDetails_argsTupleScheme();
      }
    }

    private static class addLocalSubmissionDetails_argsTupleScheme extends TupleScheme<addLocalSubmissionDetails_args> {

      @Override
      public void write(org.apache.thrift.protocol.TProtocol prot, addLocalSubmissionDetails_args struct) throws org.apache.thrift.TException {
        TTupleProtocol oprot = (TTupleProtocol) prot;
        struct.authzToken.write(oprot);
        oprot.writeString(struct.computeResourceId);
        oprot.writeI32(struct.priorityOrder);
        struct.localSubmission.write(oprot);
      }

      @Override
      public void read(org.apache.thrift.protocol.TProtocol prot, addLocalSubmissionDetails_args struct) throws org.apache.thrift.TException {
        TTupleProtocol iprot = (TTupleProtocol) prot;
        struct.authzToken = new org.apache.airavata.model.security.AuthzToken();
        struct.authzToken.read(iprot);
        struct.setAuthzTokenIsSet(true);
        struct.computeResourceId = iprot.readString();
        struct.setComputeResourceIdIsSet(true);
        struct.priorityOrder = iprot.readI32();
        struct.setPriorityOrderIsSet(true);
        struct.localSubmission = new org.apache.airavata.model.appcatalog.computeresource.LOCALSubmission();
        struct.localSubmission.read(iprot);
        struct.setLocalSubmissionIsSet(true);
      }
    }

  }

  public static class addLocalSubmissionDetails_result implements org.apache.thrift.TBase<addLocalSubmissionDetails_result, addLocalSubmissionDetails_result._Fields>, java.io.Serializable, Cloneable, Comparable<addLocalSubmissionDetails_result>   {
    private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("addLocalSubmissionDetails_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 IRE_FIELD_DESC = new org.apache.thrift.protocol.TField("ire", org.apache.thrift.protocol.TType.STRUCT, (short)1);
    private static final org.apache.thrift.protocol.TField ACE_FIELD_DESC = new org.apache.thrift.protocol.TField("ace", org.apache.thrift.protocol.TType.STRUCT, (short)2);
    private static final org.apache.thrift.protocol.TField ASE_FIELD_DESC = new org.apache.thrift.protocol.TField("ase", org.apache.thrift.protocol.TType.STRUCT, (short)3);
    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)4);

    private static final Map<Class<? extends IScheme>, SchemeFactory> schemes = new HashMap<Class<? extends IScheme>, SchemeFactory>();
    static {
      schemes.put(StandardScheme.class, new addLocalSubmissionDetails_resultStandardSchemeFactory());
      schemes.put(TupleScheme.class, new addLocalSubmissionDetails_resultTupleSchemeFactory());
    }

    public String success; // required
    public org.apache.airavata.model.error.InvalidRequestException ire; // required
    public org.apache.airavata.model.error.AiravataClientException ace; // required
    public org.apache.airavata.model.error.AiravataSystemException ase; // 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"),
      IRE((short)1, "ire"),
      ACE((short)2, "ace"),
      ASE((short)3, "ase"),
      AE((short)4, "ae");

      private static final Map<String, _Fields> byName = new HashMap<String, _Fields>();

      static {
        for (_Fields field : EnumSet.allOf(_Fields.class)) {
          byName.put(field.getFieldName(), field);
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, or null if its not found.
       */
      public static _Fields findByThriftId(int fieldId) {
        switch(fieldId) {
          case 0: // SUCCESS
            return SUCCESS;
          case 1: // IRE
            return IRE;
          case 2: // ACE
            return ACE;
          case 3: // ASE
            return ASE;
          case 4: // 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 IllegalArgumentException("Field " + fieldId + " doesn't exist!");
        return fields;
      }

      /**
       * Find the _Fields constant that matches name, or null if its not found.
       */
      public static _Fields findByName(String name) {
        return byName.get(name);
      }

      private final short _thriftId;
      private final String _fieldName;

      _Fields(short thriftId, String fieldName) {
        _thriftId = thriftId;
        _fieldName = fieldName;
      }

      public short getThriftFieldId() {
        return _thriftId;
      }

      public String getFieldName() {
        return _fieldName;
      }
    }

    // isset id assignments
    public static final Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
    static {
      Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new EnumMap<_Fields, org.apache.thrift.meta_data.FieldMetaData>(_Fields.class);
      tmpMap.put(_Fields.SUCCESS, new org.apache.thrift.meta_data.FieldMetaData("success", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING)));
      tmpMap.put(_Fields.IRE, new org.apache.thrift.meta_data.FieldMetaData("ire", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRUCT)));
      tmpMap.put(_Fields.ACE, new org.apache.thrift.meta_data.FieldMetaData("ace", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRUCT)));
      tmpMap.put(_Fields.ASE, new org.apache.thrift.meta_data.FieldMetaData("ase", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRUCT)));
      tmpMap.put(_Fields.AE, new org.apache.thrift.meta_data.FieldMetaData("ae", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRUCT)));
      metaDataMap = Collections.unmodifiableMap(tmpMap);
      org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(addLocalSubmissionDetails_result.class, metaDataMap);
    }

    public addLocalSubmissionDetails_result() {
    }

    public addLocalSubmissionDetails_result(
      String success,
      org.apache.airavata.model.error.InvalidRequestException ire,
      org.apache.airavata.model.error.AiravataClientException ace,
      org.apache.airavata.model.error.AiravataSystemException ase,
      org.apache.airavata.model.error.AuthorizationException ae)
    {
      this();
      this.success = success;
      this.ire = ire;
      this.ace = ace;
      this.ase = ase;
      this.ae = ae;
    }

    /**
     * Performs a deep copy on <i>other</i>.
     */
    public addLocalSubmissionDetails_result(addLocalSubmissionDetails_result other) {
      if (other.isSetSuccess()) {
        this.success = other.success;
      }
      if (other.isSetIre()) {
        this.ire = new org.apache.airavata.model.error.InvalidRequestException(other.ire);
      }
      if (other.isSetAce()) {
        this.ace = new org.apache.airavata.model.error.AiravataClientException(other.ace);
      }
      if (other.isSetAse()) {
        this.ase = new org.apache.airavata.model.error.AiravataSystemException(other.ase);
      }
      if (other.isSetAe()) {
        this.ae = new org.apache.airavata.model.error.AuthorizationException(other.ae);
      }
    }

    public addLocalSubmissionDetails_result deepCopy() {
      return new addLocalSubmissionDetails_result(this);
    }

    @Override
    public void clear() {
      this.success = null;
      this.ire = null;
      this.ace = null;
      this.ase = null;
      this.ae = null;
    }

    public String getSuccess() {
      return this.success;
    }

    public addLocalSubmissionDetails_result setSuccess(String success) {
      this.success = success;
      return this;
    }

    public void unsetSuccess() {
      this.success = null;
    }

    /** Returns true if field success is set (has been assigned a value) and false otherwise */
    public boolean isSetSuccess() {
      return this.success != null;
    }

    public void setSuccessIsSet(boolean value) {
      if (!value) {
        this.success = null;
      }
    }

    public org.apache.airavata.model.error.InvalidRequestException getIre() {
      return this.ire;
    }

    public addLocalSubmissionDetails_result setIre(org.apache.airavata.model.error.InvalidRequestException ire) {
      this.ire = ire;
      return this;
    }

    public void unsetIre() {
      this.ire = null;
    }

    /** Returns true if field ire is set (has been assigned a value) and false otherwise */
    public boolean isSetIre() {
      return this.ire != null;
    }

    public void setIreIsSet(boolean value) {
      if (!value) {
        this.ire = null;
      }
    }

    public org.apache.airavata.model.error.AiravataClientException getAce() {
      return this.ace;
    }

    public addLocalSubmissionDetails_result setAce(org.apache.airavata.model.error.AiravataClientException ace) {
      this.ace = ace;
      return this;
    }

    public void unsetAce() {
      this.ace = null;
    }

    /** Returns true if field ace is set (has been assigned a value) and false otherwise */
    public boolean isSetAce() {
      return this.ace != null;
    }

    public void setAceIsSet(boolean value) {
      if (!value) {
        this.ace = null;
      }
    }

    public org.apache.airavata.model.error.AiravataSystemException getAse() {
      return this.ase;
    }

    public addLocalSubmissionDetails_result setAse(org.apache.airavata.model.error.AiravataSystemException ase) {
      this.ase = ase;
      return this;
    }

    public void unsetAse() {
      this.ase = null;
    }

    /** Returns true if field ase is set (has been assigned a value) and false otherwise */
    public boolean isSetAse() {
      return this.ase != null;
    }

    public void setAseIsSet(boolean value) {
      if (!value) {
        this.ase = null;
      }
    }

    public org.apache.airavata.model.error.AuthorizationException getAe() {
      return this.ae;
    }

    public addLocalSubmissionDetails_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, Object value) {
      switch (field) {
      case SUCCESS:
        if (value == null) {
          unsetSuccess();
        } else {
          setSuccess((String)value);
        }
        break;

      case IRE:
        if (value == null) {
          unsetIre();
        } else {
          setIre((org.apache.airavata.model.error.InvalidRequestException)value);
        }
        break;

      case ACE:
        if (value == null) {
          unsetAce();
        } else {
          setAce((org.apache.airavata.model.error.AiravataClientException)value);
        }
        break;

      case ASE:
        if (value == null) {
          unsetAse();
        } else {
          setAse((org.apache.airavata.model.error.AiravataSystemException)value);
        }
        break;

      case AE:
        if (value == null) {
          unsetAe();
        } else {
          setAe((org.apache.airavata.model.error.AuthorizationException)value);
        }
        break;

      }
    }

    public Object getFieldValue(_Fields field) {
      switch (field) {
      case SUCCESS:
        return getSuccess();

      case IRE:
        return getIre();

      case ACE:
        return getAce();

      case ASE:
        return getAse();

      case AE:
        return getAe();

      }
      throw new IllegalStateException();
    }

    /** Returns true if field corresponding to fieldID is set (has been assigned a value) and false otherwise */
    public boolean isSet(_Fields field) {
      if (field == null) {
        throw new IllegalArgumentException();
      }

      switch (field) {
      case SUCCESS:
        return isSetSuccess();
      case IRE:
        return isSetIre();
      case ACE:
        return isSetAce();
      case ASE:
        return isSetAse();
      case AE:
        return isSetAe();
      }
      throw new IllegalStateException();
    }

    @Override
    public boolean equals(Object that) {
      if (that == null)
        return false;
      if (that instanceof addLocalSubmissionDetails_result)
        return this.equals((addLocalSubmissionDetails_result)that);
      return false;
    }

    public boolean equals(addLocalSubmissionDetails_result that) {
      if (that == null)
        return false;

      boolean this_present_success = true && this.isSetSuccess();
      boolean that_present_success = true && that.isSetSuccess();
      if (this_present_success || that_present_success) {
        if (!(this_present_success && that_present_success))
          return false;
        if (!this.success.equals(that.success))
          return false;
      }

      boolean this_present_ire = true && this.isSetIre();
      boolean that_present_ire = true && that.isSetIre();
      if (this_present_ire || that_present_ire) {
        if (!(this_present_ire && that_present_ire))
          return false;
        if (!this.ire.equals(that.ire))
          return false;
      }

      boolean this_present_ace = true && this.isSetAce();
      boolean that_present_ace = true && that.isSetAce();
      if (this_present_ace || that_present_ace) {
        if (!(this_present_ace && that_present_ace))
          return false;
        if (!this.ace.equals(that.ace))
          return false;
      }

      boolean this_present_ase = true && this.isSetAse();
      boolean that_present_ase = true && that.isSetAse();
      if (this_present_ase || that_present_ase) {
        if (!(this_present_ase && that_present_ase))
          return false;
        if (!this.ase.equals(that.ase))
          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() {
      List<Object> list = new ArrayList<Object>();

      boolean present_success = true && (isSetSuccess());
      list.add(present_success);
      if (present_success)
        list.add(success);

      boolean present_ire = true && (isSetIre());
      list.add(present_ire);
      if (present_ire)
        list.add(ire);

      boolean present_ace = true && (isSetAce());
      list.add(present_ace);
      if (present_ace)
        list.add(ace);

      boolean present_ase = true && (isSetAse());
      list.add(present_ase);
      if (present_ase)
        list.add(ase);

      boolean present_ae = true && (isSetAe());
      list.add(present_ae);
      if (present_ae)
        list.add(ae);

      return list.hashCode();
    }

    @Override
    public int compareTo(addLocalSubmissionDetails_result other) {
      if (!getClass().equals(other.getClass())) {
        return getClass().getName().compareTo(other.getClass().getName());
      }

      int lastComparison = 0;

      lastComparison = Boolean.valueOf(isSetSuccess()).compareTo(other.isSetSuccess());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetSuccess()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.success, other.success);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = Boolean.valueOf(isSetIre()).compareTo(other.isSetIre());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetIre()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.ire, other.ire);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = Boolean.valueOf(isSetAce()).compareTo(other.isSetAce());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetAce()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.ace, other.ace);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = Boolean.valueOf(isSetAse()).compareTo(other.isSetAse());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetAse()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.ase, other.ase);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = 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 {
      schemes.get(iprot.getScheme()).getScheme().read(iprot, this);
    }

    public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException {
      schemes.get(oprot.getScheme()).getScheme().write(oprot, this);
      }

    @Override
    public String toString() {
      StringBuilder sb = new StringBuilder("addLocalSubmissionDetails_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("ire:");
      if (this.ire == null) {
        sb.append("null");
      } else {
        sb.append(this.ire);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("ace:");
      if (this.ace == null) {
        sb.append("null");
      } else {
        sb.append(this.ace);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("ase:");
      if (this.ase == null) {
        sb.append("null");
      } else {
        sb.append(this.ase);
      }
      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, 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 addLocalSubmissionDetails_resultStandardSchemeFactory implements SchemeFactory {
      public addLocalSubmissionDetails_resultStandardScheme getScheme() {
        return new addLocalSubmissionDetails_resultStandardScheme();
      }
    }

    private static class addLocalSubmissionDetails_resultStandardScheme extends StandardScheme<addLocalSubmissionDetails_result> {

      public void read(org.apache.thrift.protocol.TProtocol iprot, addLocalSubmissionDetails_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: // IRE
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.ire = new org.apache.airavata.model.error.InvalidRequestException();
                struct.ire.read(iprot);
                struct.setIreIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 2: // ACE
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.ace = new org.apache.airavata.model.error.AiravataClientException();
                struct.ace.read(iprot);
                struct.setAceIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 3: // ASE
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.ase = new org.apache.airavata.model.error.AiravataSystemException();
                struct.ase.read(iprot);
                struct.setAseIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 4: // 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, addLocalSubmissionDetails_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.ire != null) {
          oprot.writeFieldBegin(IRE_FIELD_DESC);
          struct.ire.write(oprot);
          oprot.writeFieldEnd();
        }
        if (struct.ace != null) {
          oprot.writeFieldBegin(ACE_FIELD_DESC);
          struct.ace.write(oprot);
          oprot.writeFieldEnd();
        }
        if (struct.ase != null) {
          oprot.writeFieldBegin(ASE_FIELD_DESC);
          struct.ase.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 addLocalSubmissionDetails_resultTupleSchemeFactory implements SchemeFactory {
      public addLocalSubmissionDetails_resultTupleScheme getScheme() {
        return new addLocalSubmissionDetails_resultTupleScheme();
      }
    }

    private static class addLocalSubmissionDetails_resultTupleScheme extends TupleScheme<addLocalSubmissionDetails_result> {

      @Override
      public void write(org.apache.thrift.protocol.TProtocol prot, addLocalSubmissionDetails_result struct) throws org.apache.thrift.TException {
        TTupleProtocol oprot = (TTupleProtocol) prot;
        BitSet optionals = new BitSet();
        if (struct.isSetSuccess()) {
          optionals.set(0);
        }
        if (struct.isSetIre()) {
          optionals.set(1);
        }
        if (struct.isSetAce()) {
          optionals.set(2);
        }
        if (struct.isSetAse()) {
          optionals.set(3);
        }
        if (struct.isSetAe()) {
          optionals.set(4);
        }
        oprot.writeBitSet(optionals, 5);
        if (struct.isSetSuccess()) {
          oprot.writeString(struct.success);
        }
        if (struct.isSetIre()) {
          struct.ire.write(oprot);
        }
        if (struct.isSetAce()) {
          struct.ace.write(oprot);
        }
        if (struct.isSetAse()) {
          struct.ase.write(oprot);
        }
        if (struct.isSetAe()) {
          struct.ae.write(oprot);
        }
      }

      @Override
      public void read(org.apache.thrift.protocol.TProtocol prot, addLocalSubmissionDetails_result struct) throws org.apache.thrift.TException {
        TTupleProtocol iprot = (TTupleProtocol) prot;
        BitSet incoming = iprot.readBitSet(5);
        if (incoming.get(0)) {
          struct.success = iprot.readString();
          struct.setSuccessIsSet(true);
        }
        if (incoming.get(1)) {
          struct.ire = new org.apache.airavata.model.error.InvalidRequestException();
          struct.ire.read(iprot);
          struct.setIreIsSet(true);
        }
        if (incoming.get(2)) {
          struct.ace = new org.apache.airavata.model.error.AiravataClientException();
          struct.ace.read(iprot);
          struct.setAceIsSet(true);
        }
        if (incoming.get(3)) {
          struct.ase = new org.apache.airavata.model.error.AiravataSystemException();
          struct.ase.read(iprot);
          struct.setAseIsSet(true);
        }
        if (incoming.get(4)) {
          struct.ae = new org.apache.airavata.model.error.AuthorizationException();
          struct.ae.read(iprot);
          struct.setAeIsSet(true);
        }
      }
    }

  }

  public static class updateLocalSubmissionDetails_args implements org.apache.thrift.TBase<updateLocalSubmissionDetails_args, updateLocalSubmissionDetails_args._Fields>, java.io.Serializable, Cloneable, Comparable<updateLocalSubmissionDetails_args>   {
    private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("updateLocalSubmissionDetails_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 JOB_SUBMISSION_INTERFACE_ID_FIELD_DESC = new org.apache.thrift.protocol.TField("jobSubmissionInterfaceId", org.apache.thrift.protocol.TType.STRING, (short)2);
    private static final org.apache.thrift.protocol.TField LOCAL_SUBMISSION_FIELD_DESC = new org.apache.thrift.protocol.TField("localSubmission", org.apache.thrift.protocol.TType.STRUCT, (short)3);

    private static final Map<Class<? extends IScheme>, SchemeFactory> schemes = new HashMap<Class<? extends IScheme>, SchemeFactory>();
    static {
      schemes.put(StandardScheme.class, new updateLocalSubmissionDetails_argsStandardSchemeFactory());
      schemes.put(TupleScheme.class, new updateLocalSubmissionDetails_argsTupleSchemeFactory());
    }

    public org.apache.airavata.model.security.AuthzToken authzToken; // required
    public String jobSubmissionInterfaceId; // required
    public org.apache.airavata.model.appcatalog.computeresource.LOCALSubmission localSubmission; // required

    /** 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"),
      JOB_SUBMISSION_INTERFACE_ID((short)2, "jobSubmissionInterfaceId"),
      LOCAL_SUBMISSION((short)3, "localSubmission");

      private static final Map<String, _Fields> byName = new HashMap<String, _Fields>();

      static {
        for (_Fields field : EnumSet.allOf(_Fields.class)) {
          byName.put(field.getFieldName(), field);
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, or null if its not found.
       */
      public static _Fields findByThriftId(int fieldId) {
        switch(fieldId) {
          case 1: // AUTHZ_TOKEN
            return AUTHZ_TOKEN;
          case 2: // JOB_SUBMISSION_INTERFACE_ID
            return JOB_SUBMISSION_INTERFACE_ID;
          case 3: // LOCAL_SUBMISSION
            return LOCAL_SUBMISSION;
          default:
            return null;
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, throwing an exception
       * if it is not found.
       */
      public static _Fields findByThriftIdOrThrow(int fieldId) {
        _Fields fields = findByThriftId(fieldId);
        if (fields == null) throw new IllegalArgumentException("Field " + fieldId + " doesn't exist!");
        return fields;
      }

      /**
       * Find the _Fields constant that matches name, or null if its not found.
       */
      public static _Fields findByName(String name) {
        return byName.get(name);
      }

      private final short _thriftId;
      private final String _fieldName;

      _Fields(short thriftId, String fieldName) {
        _thriftId = thriftId;
        _fieldName = fieldName;
      }

      public short getThriftFieldId() {
        return _thriftId;
      }

      public String getFieldName() {
        return _fieldName;
      }
    }

    // isset id assignments
    public static final Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
    static {
      Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new EnumMap<_Fields, org.apache.thrift.meta_data.FieldMetaData>(_Fields.class);
      tmpMap.put(_Fields.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.JOB_SUBMISSION_INTERFACE_ID, new org.apache.thrift.meta_data.FieldMetaData("jobSubmissionInterfaceId", org.apache.thrift.TFieldRequirementType.REQUIRED, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING)));
      tmpMap.put(_Fields.LOCAL_SUBMISSION, new org.apache.thrift.meta_data.FieldMetaData("localSubmission", org.apache.thrift.TFieldRequirementType.REQUIRED, 
          new org.apache.thrift.meta_data.StructMetaData(org.apache.thrift.protocol.TType.STRUCT, org.apache.airavata.model.appcatalog.computeresource.LOCALSubmission.class)));
      metaDataMap = Collections.unmodifiableMap(tmpMap);
      org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(updateLocalSubmissionDetails_args.class, metaDataMap);
    }

    public updateLocalSubmissionDetails_args() {
    }

    public updateLocalSubmissionDetails_args(
      org.apache.airavata.model.security.AuthzToken authzToken,
      String jobSubmissionInterfaceId,
      org.apache.airavata.model.appcatalog.computeresource.LOCALSubmission localSubmission)
    {
      this();
      this.authzToken = authzToken;
      this.jobSubmissionInterfaceId = jobSubmissionInterfaceId;
      this.localSubmission = localSubmission;
    }

    /**
     * Performs a deep copy on <i>other</i>.
     */
    public updateLocalSubmissionDetails_args(updateLocalSubmissionDetails_args other) {
      if (other.isSetAuthzToken()) {
        this.authzToken = new org.apache.airavata.model.security.AuthzToken(other.authzToken);
      }
      if (other.isSetJobSubmissionInterfaceId()) {
        this.jobSubmissionInterfaceId = other.jobSubmissionInterfaceId;
      }
      if (other.isSetLocalSubmission()) {
        this.localSubmission = new org.apache.airavata.model.appcatalog.computeresource.LOCALSubmission(other.localSubmission);
      }
    }

    public updateLocalSubmissionDetails_args deepCopy() {
      return new updateLocalSubmissionDetails_args(this);
    }

    @Override
    public void clear() {
      this.authzToken = null;
      this.jobSubmissionInterfaceId = null;
      this.localSubmission = null;
    }

    public org.apache.airavata.model.security.AuthzToken getAuthzToken() {
      return this.authzToken;
    }

    public updateLocalSubmissionDetails_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 String getJobSubmissionInterfaceId() {
      return this.jobSubmissionInterfaceId;
    }

    public updateLocalSubmissionDetails_args setJobSubmissionInterfaceId(String jobSubmissionInterfaceId) {
      this.jobSubmissionInterfaceId = jobSubmissionInterfaceId;
      return this;
    }

    public void unsetJobSubmissionInterfaceId() {
      this.jobSubmissionInterfaceId = null;
    }

    /** Returns true if field jobSubmissionInterfaceId is set (has been assigned a value) and false otherwise */
    public boolean isSetJobSubmissionInterfaceId() {
      return this.jobSubmissionInterfaceId != null;
    }

    public void setJobSubmissionInterfaceIdIsSet(boolean value) {
      if (!value) {
        this.jobSubmissionInterfaceId = null;
      }
    }

    public org.apache.airavata.model.appcatalog.computeresource.LOCALSubmission getLocalSubmission() {
      return this.localSubmission;
    }

    public updateLocalSubmissionDetails_args setLocalSubmission(org.apache.airavata.model.appcatalog.computeresource.LOCALSubmission localSubmission) {
      this.localSubmission = localSubmission;
      return this;
    }

    public void unsetLocalSubmission() {
      this.localSubmission = null;
    }

    /** Returns true if field localSubmission is set (has been assigned a value) and false otherwise */
    public boolean isSetLocalSubmission() {
      return this.localSubmission != null;
    }

    public void setLocalSubmissionIsSet(boolean value) {
      if (!value) {
        this.localSubmission = null;
      }
    }

    public void setFieldValue(_Fields field, Object value) {
      switch (field) {
      case AUTHZ_TOKEN:
        if (value == null) {
          unsetAuthzToken();
        } else {
          setAuthzToken((org.apache.airavata.model.security.AuthzToken)value);
        }
        break;

      case JOB_SUBMISSION_INTERFACE_ID:
        if (value == null) {
          unsetJobSubmissionInterfaceId();
        } else {
          setJobSubmissionInterfaceId((String)value);
        }
        break;

      case LOCAL_SUBMISSION:
        if (value == null) {
          unsetLocalSubmission();
        } else {
          setLocalSubmission((org.apache.airavata.model.appcatalog.computeresource.LOCALSubmission)value);
        }
        break;

      }
    }

    public Object getFieldValue(_Fields field) {
      switch (field) {
      case AUTHZ_TOKEN:
        return getAuthzToken();

      case JOB_SUBMISSION_INTERFACE_ID:
        return getJobSubmissionInterfaceId();

      case LOCAL_SUBMISSION:
        return getLocalSubmission();

      }
      throw new IllegalStateException();
    }

    /** Returns true if field corresponding to fieldID is set (has been assigned a value) and false otherwise */
    public boolean isSet(_Fields field) {
      if (field == null) {
        throw new IllegalArgumentException();
      }

      switch (field) {
      case AUTHZ_TOKEN:
        return isSetAuthzToken();
      case JOB_SUBMISSION_INTERFACE_ID:
        return isSetJobSubmissionInterfaceId();
      case LOCAL_SUBMISSION:
        return isSetLocalSubmission();
      }
      throw new IllegalStateException();
    }

    @Override
    public boolean equals(Object that) {
      if (that == null)
        return false;
      if (that instanceof updateLocalSubmissionDetails_args)
        return this.equals((updateLocalSubmissionDetails_args)that);
      return false;
    }

    public boolean equals(updateLocalSubmissionDetails_args that) {
      if (that == null)
        return false;

      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_jobSubmissionInterfaceId = true && this.isSetJobSubmissionInterfaceId();
      boolean that_present_jobSubmissionInterfaceId = true && that.isSetJobSubmissionInterfaceId();
      if (this_present_jobSubmissionInterfaceId || that_present_jobSubmissionInterfaceId) {
        if (!(this_present_jobSubmissionInterfaceId && that_present_jobSubmissionInterfaceId))
          return false;
        if (!this.jobSubmissionInterfaceId.equals(that.jobSubmissionInterfaceId))
          return false;
      }

      boolean this_present_localSubmission = true && this.isSetLocalSubmission();
      boolean that_present_localSubmission = true && that.isSetLocalSubmission();
      if (this_present_localSubmission || that_present_localSubmission) {
        if (!(this_present_localSubmission && that_present_localSubmission))
          return false;
        if (!this.localSubmission.equals(that.localSubmission))
          return false;
      }

      return true;
    }

    @Override
    public int hashCode() {
      List<Object> list = new ArrayList<Object>();

      boolean present_authzToken = true && (isSetAuthzToken());
      list.add(present_authzToken);
      if (present_authzToken)
        list.add(authzToken);

      boolean present_jobSubmissionInterfaceId = true && (isSetJobSubmissionInterfaceId());
      list.add(present_jobSubmissionInterfaceId);
      if (present_jobSubmissionInterfaceId)
        list.add(jobSubmissionInterfaceId);

      boolean present_localSubmission = true && (isSetLocalSubmission());
      list.add(present_localSubmission);
      if (present_localSubmission)
        list.add(localSubmission);

      return list.hashCode();
    }

    @Override
    public int compareTo(updateLocalSubmissionDetails_args other) {
      if (!getClass().equals(other.getClass())) {
        return getClass().getName().compareTo(other.getClass().getName());
      }

      int lastComparison = 0;

      lastComparison = 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 = Boolean.valueOf(isSetJobSubmissionInterfaceId()).compareTo(other.isSetJobSubmissionInterfaceId());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetJobSubmissionInterfaceId()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.jobSubmissionInterfaceId, other.jobSubmissionInterfaceId);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = Boolean.valueOf(isSetLocalSubmission()).compareTo(other.isSetLocalSubmission());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetLocalSubmission()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.localSubmission, other.localSubmission);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      return 0;
    }

    public _Fields fieldForId(int fieldId) {
      return _Fields.findByThriftId(fieldId);
    }

    public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
      schemes.get(iprot.getScheme()).getScheme().read(iprot, this);
    }

    public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException {
      schemes.get(oprot.getScheme()).getScheme().write(oprot, this);
    }

    @Override
    public String toString() {
      StringBuilder sb = new StringBuilder("updateLocalSubmissionDetails_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("jobSubmissionInterfaceId:");
      if (this.jobSubmissionInterfaceId == null) {
        sb.append("null");
      } else {
        sb.append(this.jobSubmissionInterfaceId);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("localSubmission:");
      if (this.localSubmission == null) {
        sb.append("null");
      } else {
        sb.append(this.localSubmission);
      }
      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 (jobSubmissionInterfaceId == null) {
        throw new org.apache.thrift.protocol.TProtocolException("Required field 'jobSubmissionInterfaceId' was not present! Struct: " + toString());
      }
      if (localSubmission == null) {
        throw new org.apache.thrift.protocol.TProtocolException("Required field 'localSubmission' was not present! Struct: " + toString());
      }
      // check for sub-struct validity
      if (authzToken != null) {
        authzToken.validate();
      }
      if (localSubmission != null) {
        localSubmission.validate();
      }
    }

    private void writeObject(java.io.ObjectOutputStream out) throws java.io.IOException {
      try {
        write(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(out)));
      } catch (org.apache.thrift.TException te) {
        throw new java.io.IOException(te);
      }
    }

    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, ClassNotFoundException {
      try {
        read(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(in)));
      } catch (org.apache.thrift.TException te) {
        throw new java.io.IOException(te);
      }
    }

    private static class updateLocalSubmissionDetails_argsStandardSchemeFactory implements SchemeFactory {
      public updateLocalSubmissionDetails_argsStandardScheme getScheme() {
        return new updateLocalSubmissionDetails_argsStandardScheme();
      }
    }

    private static class updateLocalSubmissionDetails_argsStandardScheme extends StandardScheme<updateLocalSubmissionDetails_args> {

      public void read(org.apache.thrift.protocol.TProtocol iprot, updateLocalSubmissionDetails_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: // JOB_SUBMISSION_INTERFACE_ID
              if (schemeField.type == org.apache.thrift.protocol.TType.STRING) {
                struct.jobSubmissionInterfaceId = iprot.readString();
                struct.setJobSubmissionInterfaceIdIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 3: // LOCAL_SUBMISSION
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.localSubmission = new org.apache.airavata.model.appcatalog.computeresource.LOCALSubmission();
                struct.localSubmission.read(iprot);
                struct.setLocalSubmissionIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            default:
              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
          }
          iprot.readFieldEnd();
        }
        iprot.readStructEnd();

        // check for required fields of primitive type, which can't be checked in the validate method
        struct.validate();
      }

      public void write(org.apache.thrift.protocol.TProtocol oprot, updateLocalSubmissionDetails_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.jobSubmissionInterfaceId != null) {
          oprot.writeFieldBegin(JOB_SUBMISSION_INTERFACE_ID_FIELD_DESC);
          oprot.writeString(struct.jobSubmissionInterfaceId);
          oprot.writeFieldEnd();
        }
        if (struct.localSubmission != null) {
          oprot.writeFieldBegin(LOCAL_SUBMISSION_FIELD_DESC);
          struct.localSubmission.write(oprot);
          oprot.writeFieldEnd();
        }
        oprot.writeFieldStop();
        oprot.writeStructEnd();
      }

    }

    private static class updateLocalSubmissionDetails_argsTupleSchemeFactory implements SchemeFactory {
      public updateLocalSubmissionDetails_argsTupleScheme getScheme() {
        return new updateLocalSubmissionDetails_argsTupleScheme();
      }
    }

    private static class updateLocalSubmissionDetails_argsTupleScheme extends TupleScheme<updateLocalSubmissionDetails_args> {

      @Override
      public void write(org.apache.thrift.protocol.TProtocol prot, updateLocalSubmissionDetails_args struct) throws org.apache.thrift.TException {
        TTupleProtocol oprot = (TTupleProtocol) prot;
        struct.authzToken.write(oprot);
        oprot.writeString(struct.jobSubmissionInterfaceId);
        struct.localSubmission.write(oprot);
      }

      @Override
      public void read(org.apache.thrift.protocol.TProtocol prot, updateLocalSubmissionDetails_args struct) throws org.apache.thrift.TException {
        TTupleProtocol iprot = (TTupleProtocol) prot;
        struct.authzToken = new org.apache.airavata.model.security.AuthzToken();
        struct.authzToken.read(iprot);
        struct.setAuthzTokenIsSet(true);
        struct.jobSubmissionInterfaceId = iprot.readString();
        struct.setJobSubmissionInterfaceIdIsSet(true);
        struct.localSubmission = new org.apache.airavata.model.appcatalog.computeresource.LOCALSubmission();
        struct.localSubmission.read(iprot);
        struct.setLocalSubmissionIsSet(true);
      }
    }

  }

  public static class updateLocalSubmissionDetails_result implements org.apache.thrift.TBase<updateLocalSubmissionDetails_result, updateLocalSubmissionDetails_result._Fields>, java.io.Serializable, Cloneable, Comparable<updateLocalSubmissionDetails_result>   {
    private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("updateLocalSubmissionDetails_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 IRE_FIELD_DESC = new org.apache.thrift.protocol.TField("ire", org.apache.thrift.protocol.TType.STRUCT, (short)1);
    private static final org.apache.thrift.protocol.TField ACE_FIELD_DESC = new org.apache.thrift.protocol.TField("ace", org.apache.thrift.protocol.TType.STRUCT, (short)2);
    private static final org.apache.thrift.protocol.TField ASE_FIELD_DESC = new org.apache.thrift.protocol.TField("ase", org.apache.thrift.protocol.TType.STRUCT, (short)3);
    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)4);

    private static final Map<Class<? extends IScheme>, SchemeFactory> schemes = new HashMap<Class<? extends IScheme>, SchemeFactory>();
    static {
      schemes.put(StandardScheme.class, new updateLocalSubmissionDetails_resultStandardSchemeFactory());
      schemes.put(TupleScheme.class, new updateLocalSubmissionDetails_resultTupleSchemeFactory());
    }

    public boolean success; // required
    public org.apache.airavata.model.error.InvalidRequestException ire; // required
    public org.apache.airavata.model.error.AiravataClientException ace; // required
    public org.apache.airavata.model.error.AiravataSystemException ase; // 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"),
      IRE((short)1, "ire"),
      ACE((short)2, "ace"),
      ASE((short)3, "ase"),
      AE((short)4, "ae");

      private static final Map<String, _Fields> byName = new HashMap<String, _Fields>();

      static {
        for (_Fields field : EnumSet.allOf(_Fields.class)) {
          byName.put(field.getFieldName(), field);
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, or null if its not found.
       */
      public static _Fields findByThriftId(int fieldId) {
        switch(fieldId) {
          case 0: // SUCCESS
            return SUCCESS;
          case 1: // IRE
            return IRE;
          case 2: // ACE
            return ACE;
          case 3: // ASE
            return ASE;
          case 4: // 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 IllegalArgumentException("Field " + fieldId + " doesn't exist!");
        return fields;
      }

      /**
       * Find the _Fields constant that matches name, or null if its not found.
       */
      public static _Fields findByName(String name) {
        return byName.get(name);
      }

      private final short _thriftId;
      private final String _fieldName;

      _Fields(short thriftId, String fieldName) {
        _thriftId = thriftId;
        _fieldName = fieldName;
      }

      public short getThriftFieldId() {
        return _thriftId;
      }

      public String getFieldName() {
        return _fieldName;
      }
    }

    // isset id assignments
    private static final int __SUCCESS_ISSET_ID = 0;
    private byte __isset_bitfield = 0;
    public static final Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
    static {
      Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new EnumMap<_Fields, org.apache.thrift.meta_data.FieldMetaData>(_Fields.class);
      tmpMap.put(_Fields.SUCCESS, new org.apache.thrift.meta_data.FieldMetaData("success", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.BOOL)));
      tmpMap.put(_Fields.IRE, new org.apache.thrift.meta_data.FieldMetaData("ire", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRUCT)));
      tmpMap.put(_Fields.ACE, new org.apache.thrift.meta_data.FieldMetaData("ace", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRUCT)));
      tmpMap.put(_Fields.ASE, new org.apache.thrift.meta_data.FieldMetaData("ase", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRUCT)));
      tmpMap.put(_Fields.AE, new org.apache.thrift.meta_data.FieldMetaData("ae", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRUCT)));
      metaDataMap = Collections.unmodifiableMap(tmpMap);
      org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(updateLocalSubmissionDetails_result.class, metaDataMap);
    }

    public updateLocalSubmissionDetails_result() {
    }

    public updateLocalSubmissionDetails_result(
      boolean success,
      org.apache.airavata.model.error.InvalidRequestException ire,
      org.apache.airavata.model.error.AiravataClientException ace,
      org.apache.airavata.model.error.AiravataSystemException ase,
      org.apache.airavata.model.error.AuthorizationException ae)
    {
      this();
      this.success = success;
      setSuccessIsSet(true);
      this.ire = ire;
      this.ace = ace;
      this.ase = ase;
      this.ae = ae;
    }

    /**
     * Performs a deep copy on <i>other</i>.
     */
    public updateLocalSubmissionDetails_result(updateLocalSubmissionDetails_result other) {
      __isset_bitfield = other.__isset_bitfield;
      this.success = other.success;
      if (other.isSetIre()) {
        this.ire = new org.apache.airavata.model.error.InvalidRequestException(other.ire);
      }
      if (other.isSetAce()) {
        this.ace = new org.apache.airavata.model.error.AiravataClientException(other.ace);
      }
      if (other.isSetAse()) {
        this.ase = new org.apache.airavata.model.error.AiravataSystemException(other.ase);
      }
      if (other.isSetAe()) {
        this.ae = new org.apache.airavata.model.error.AuthorizationException(other.ae);
      }
    }

    public updateLocalSubmissionDetails_result deepCopy() {
      return new updateLocalSubmissionDetails_result(this);
    }

    @Override
    public void clear() {
      setSuccessIsSet(false);
      this.success = false;
      this.ire = null;
      this.ace = null;
      this.ase = null;
      this.ae = null;
    }

    public boolean isSuccess() {
      return this.success;
    }

    public updateLocalSubmissionDetails_result setSuccess(boolean success) {
      this.success = success;
      setSuccessIsSet(true);
      return this;
    }

    public void unsetSuccess() {
      __isset_bitfield = EncodingUtils.clearBit(__isset_bitfield, __SUCCESS_ISSET_ID);
    }

    /** Returns true if field success is set (has been assigned a value) and false otherwise */
    public boolean isSetSuccess() {
      return EncodingUtils.testBit(__isset_bitfield, __SUCCESS_ISSET_ID);
    }

    public void setSuccessIsSet(boolean value) {
      __isset_bitfield = EncodingUtils.setBit(__isset_bitfield, __SUCCESS_ISSET_ID, value);
    }

    public org.apache.airavata.model.error.InvalidRequestException getIre() {
      return this.ire;
    }

    public updateLocalSubmissionDetails_result setIre(org.apache.airavata.model.error.InvalidRequestException ire) {
      this.ire = ire;
      return this;
    }

    public void unsetIre() {
      this.ire = null;
    }

    /** Returns true if field ire is set (has been assigned a value) and false otherwise */
    public boolean isSetIre() {
      return this.ire != null;
    }

    public void setIreIsSet(boolean value) {
      if (!value) {
        this.ire = null;
      }
    }

    public org.apache.airavata.model.error.AiravataClientException getAce() {
      return this.ace;
    }

    public updateLocalSubmissionDetails_result setAce(org.apache.airavata.model.error.AiravataClientException ace) {
      this.ace = ace;
      return this;
    }

    public void unsetAce() {
      this.ace = null;
    }

    /** Returns true if field ace is set (has been assigned a value) and false otherwise */
    public boolean isSetAce() {
      return this.ace != null;
    }

    public void setAceIsSet(boolean value) {
      if (!value) {
        this.ace = null;
      }
    }

    public org.apache.airavata.model.error.AiravataSystemException getAse() {
      return this.ase;
    }

    public updateLocalSubmissionDetails_result setAse(org.apache.airavata.model.error.AiravataSystemException ase) {
      this.ase = ase;
      return this;
    }

    public void unsetAse() {
      this.ase = null;
    }

    /** Returns true if field ase is set (has been assigned a value) and false otherwise */
    public boolean isSetAse() {
      return this.ase != null;
    }

    public void setAseIsSet(boolean value) {
      if (!value) {
        this.ase = null;
      }
    }

    public org.apache.airavata.model.error.AuthorizationException getAe() {
      return this.ae;
    }

    public updateLocalSubmissionDetails_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, Object value) {
      switch (field) {
      case SUCCESS:
        if (value == null) {
          unsetSuccess();
        } else {
          setSuccess((Boolean)value);
        }
        break;

      case IRE:
        if (value == null) {
          unsetIre();
        } else {
          setIre((org.apache.airavata.model.error.InvalidRequestException)value);
        }
        break;

      case ACE:
        if (value == null) {
          unsetAce();
        } else {
          setAce((org.apache.airavata.model.error.AiravataClientException)value);
        }
        break;

      case ASE:
        if (value == null) {
          unsetAse();
        } else {
          setAse((org.apache.airavata.model.error.AiravataSystemException)value);
        }
        break;

      case AE:
        if (value == null) {
          unsetAe();
        } else {
          setAe((org.apache.airavata.model.error.AuthorizationException)value);
        }
        break;

      }
    }

    public Object getFieldValue(_Fields field) {
      switch (field) {
      case SUCCESS:
        return Boolean.valueOf(isSuccess());

      case IRE:
        return getIre();

      case ACE:
        return getAce();

      case ASE:
        return getAse();

      case AE:
        return getAe();

      }
      throw new IllegalStateException();
    }

    /** Returns true if field corresponding to fieldID is set (has been assigned a value) and false otherwise */
    public boolean isSet(_Fields field) {
      if (field == null) {
        throw new IllegalArgumentException();
      }

      switch (field) {
      case SUCCESS:
        return isSetSuccess();
      case IRE:
        return isSetIre();
      case ACE:
        return isSetAce();
      case ASE:
        return isSetAse();
      case AE:
        return isSetAe();
      }
      throw new IllegalStateException();
    }

    @Override
    public boolean equals(Object that) {
      if (that == null)
        return false;
      if (that instanceof updateLocalSubmissionDetails_result)
        return this.equals((updateLocalSubmissionDetails_result)that);
      return false;
    }

    public boolean equals(updateLocalSubmissionDetails_result that) {
      if (that == null)
        return false;

      boolean this_present_success = true;
      boolean that_present_success = true;
      if (this_present_success || that_present_success) {
        if (!(this_present_success && that_present_success))
          return false;
        if (this.success != that.success)
          return false;
      }

      boolean this_present_ire = true && this.isSetIre();
      boolean that_present_ire = true && that.isSetIre();
      if (this_present_ire || that_present_ire) {
        if (!(this_present_ire && that_present_ire))
          return false;
        if (!this.ire.equals(that.ire))
          return false;
      }

      boolean this_present_ace = true && this.isSetAce();
      boolean that_present_ace = true && that.isSetAce();
      if (this_present_ace || that_present_ace) {
        if (!(this_present_ace && that_present_ace))
          return false;
        if (!this.ace.equals(that.ace))
          return false;
      }

      boolean this_present_ase = true && this.isSetAse();
      boolean that_present_ase = true && that.isSetAse();
      if (this_present_ase || that_present_ase) {
        if (!(this_present_ase && that_present_ase))
          return false;
        if (!this.ase.equals(that.ase))
          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() {
      List<Object> list = new ArrayList<Object>();

      boolean present_success = true;
      list.add(present_success);
      if (present_success)
        list.add(success);

      boolean present_ire = true && (isSetIre());
      list.add(present_ire);
      if (present_ire)
        list.add(ire);

      boolean present_ace = true && (isSetAce());
      list.add(present_ace);
      if (present_ace)
        list.add(ace);

      boolean present_ase = true && (isSetAse());
      list.add(present_ase);
      if (present_ase)
        list.add(ase);

      boolean present_ae = true && (isSetAe());
      list.add(present_ae);
      if (present_ae)
        list.add(ae);

      return list.hashCode();
    }

    @Override
    public int compareTo(updateLocalSubmissionDetails_result other) {
      if (!getClass().equals(other.getClass())) {
        return getClass().getName().compareTo(other.getClass().getName());
      }

      int lastComparison = 0;

      lastComparison = Boolean.valueOf(isSetSuccess()).compareTo(other.isSetSuccess());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetSuccess()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.success, other.success);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = Boolean.valueOf(isSetIre()).compareTo(other.isSetIre());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetIre()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.ire, other.ire);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = Boolean.valueOf(isSetAce()).compareTo(other.isSetAce());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetAce()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.ace, other.ace);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = Boolean.valueOf(isSetAse()).compareTo(other.isSetAse());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetAse()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.ase, other.ase);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = 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 {
      schemes.get(iprot.getScheme()).getScheme().read(iprot, this);
    }

    public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException {
      schemes.get(oprot.getScheme()).getScheme().write(oprot, this);
      }

    @Override
    public String toString() {
      StringBuilder sb = new StringBuilder("updateLocalSubmissionDetails_result(");
      boolean first = true;

      sb.append("success:");
      sb.append(this.success);
      first = false;
      if (!first) sb.append(", ");
      sb.append("ire:");
      if (this.ire == null) {
        sb.append("null");
      } else {
        sb.append(this.ire);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("ace:");
      if (this.ace == null) {
        sb.append("null");
      } else {
        sb.append(this.ace);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("ase:");
      if (this.ase == null) {
        sb.append("null");
      } else {
        sb.append(this.ase);
      }
      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, 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 updateLocalSubmissionDetails_resultStandardSchemeFactory implements SchemeFactory {
      public updateLocalSubmissionDetails_resultStandardScheme getScheme() {
        return new updateLocalSubmissionDetails_resultStandardScheme();
      }
    }

    private static class updateLocalSubmissionDetails_resultStandardScheme extends StandardScheme<updateLocalSubmissionDetails_result> {

      public void read(org.apache.thrift.protocol.TProtocol iprot, updateLocalSubmissionDetails_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: // IRE
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.ire = new org.apache.airavata.model.error.InvalidRequestException();
                struct.ire.read(iprot);
                struct.setIreIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 2: // ACE
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.ace = new org.apache.airavata.model.error.AiravataClientException();
                struct.ace.read(iprot);
                struct.setAceIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 3: // ASE
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.ase = new org.apache.airavata.model.error.AiravataSystemException();
                struct.ase.read(iprot);
                struct.setAseIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 4: // 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, updateLocalSubmissionDetails_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.ire != null) {
          oprot.writeFieldBegin(IRE_FIELD_DESC);
          struct.ire.write(oprot);
          oprot.writeFieldEnd();
        }
        if (struct.ace != null) {
          oprot.writeFieldBegin(ACE_FIELD_DESC);
          struct.ace.write(oprot);
          oprot.writeFieldEnd();
        }
        if (struct.ase != null) {
          oprot.writeFieldBegin(ASE_FIELD_DESC);
          struct.ase.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 updateLocalSubmissionDetails_resultTupleSchemeFactory implements SchemeFactory {
      public updateLocalSubmissionDetails_resultTupleScheme getScheme() {
        return new updateLocalSubmissionDetails_resultTupleScheme();
      }
    }

    private static class updateLocalSubmissionDetails_resultTupleScheme extends TupleScheme<updateLocalSubmissionDetails_result> {

      @Override
      public void write(org.apache.thrift.protocol.TProtocol prot, updateLocalSubmissionDetails_result struct) throws org.apache.thrift.TException {
        TTupleProtocol oprot = (TTupleProtocol) prot;
        BitSet optionals = new BitSet();
        if (struct.isSetSuccess()) {
          optionals.set(0);
        }
        if (struct.isSetIre()) {
          optionals.set(1);
        }
        if (struct.isSetAce()) {
          optionals.set(2);
        }
        if (struct.isSetAse()) {
          optionals.set(3);
        }
        if (struct.isSetAe()) {
          optionals.set(4);
        }
        oprot.writeBitSet(optionals, 5);
        if (struct.isSetSuccess()) {
          oprot.writeBool(struct.success);
        }
        if (struct.isSetIre()) {
          struct.ire.write(oprot);
        }
        if (struct.isSetAce()) {
          struct.ace.write(oprot);
        }
        if (struct.isSetAse()) {
          struct.ase.write(oprot);
        }
        if (struct.isSetAe()) {
          struct.ae.write(oprot);
        }
      }

      @Override
      public void read(org.apache.thrift.protocol.TProtocol prot, updateLocalSubmissionDetails_result struct) throws org.apache.thrift.TException {
        TTupleProtocol iprot = (TTupleProtocol) prot;
        BitSet incoming = iprot.readBitSet(5);
        if (incoming.get(0)) {
          struct.success = iprot.readBool();
          struct.setSuccessIsSet(true);
        }
        if (incoming.get(1)) {
          struct.ire = new org.apache.airavata.model.error.InvalidRequestException();
          struct.ire.read(iprot);
          struct.setIreIsSet(true);
        }
        if (incoming.get(2)) {
          struct.ace = new org.apache.airavata.model.error.AiravataClientException();
          struct.ace.read(iprot);
          struct.setAceIsSet(true);
        }
        if (incoming.get(3)) {
          struct.ase = new org.apache.airavata.model.error.AiravataSystemException();
          struct.ase.read(iprot);
          struct.setAseIsSet(true);
        }
        if (incoming.get(4)) {
          struct.ae = new org.apache.airavata.model.error.AuthorizationException();
          struct.ae.read(iprot);
          struct.setAeIsSet(true);
        }
      }
    }

  }

  public static class getLocalJobSubmission_args implements org.apache.thrift.TBase<getLocalJobSubmission_args, getLocalJobSubmission_args._Fields>, java.io.Serializable, Cloneable, Comparable<getLocalJobSubmission_args>   {
    private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("getLocalJobSubmission_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 JOB_SUBMISSION_ID_FIELD_DESC = new org.apache.thrift.protocol.TField("jobSubmissionId", org.apache.thrift.protocol.TType.STRING, (short)2);

    private static final Map<Class<? extends IScheme>, SchemeFactory> schemes = new HashMap<Class<? extends IScheme>, SchemeFactory>();
    static {
      schemes.put(StandardScheme.class, new getLocalJobSubmission_argsStandardSchemeFactory());
      schemes.put(TupleScheme.class, new getLocalJobSubmission_argsTupleSchemeFactory());
    }

    public org.apache.airavata.model.security.AuthzToken authzToken; // required
    public String jobSubmissionId; // required

    /** 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"),
      JOB_SUBMISSION_ID((short)2, "jobSubmissionId");

      private static final Map<String, _Fields> byName = new HashMap<String, _Fields>();

      static {
        for (_Fields field : EnumSet.allOf(_Fields.class)) {
          byName.put(field.getFieldName(), field);
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, or null if its not found.
       */
      public static _Fields findByThriftId(int fieldId) {
        switch(fieldId) {
          case 1: // AUTHZ_TOKEN
            return AUTHZ_TOKEN;
          case 2: // JOB_SUBMISSION_ID
            return JOB_SUBMISSION_ID;
          default:
            return null;
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, throwing an exception
       * if it is not found.
       */
      public static _Fields findByThriftIdOrThrow(int fieldId) {
        _Fields fields = findByThriftId(fieldId);
        if (fields == null) throw new IllegalArgumentException("Field " + fieldId + " doesn't exist!");
        return fields;
      }

      /**
       * Find the _Fields constant that matches name, or null if its not found.
       */
      public static _Fields findByName(String name) {
        return byName.get(name);
      }

      private final short _thriftId;
      private final String _fieldName;

      _Fields(short thriftId, String fieldName) {
        _thriftId = thriftId;
        _fieldName = fieldName;
      }

      public short getThriftFieldId() {
        return _thriftId;
      }

      public String getFieldName() {
        return _fieldName;
      }
    }

    // isset id assignments
    public static final Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
    static {
      Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new EnumMap<_Fields, org.apache.thrift.meta_data.FieldMetaData>(_Fields.class);
      tmpMap.put(_Fields.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.JOB_SUBMISSION_ID, new org.apache.thrift.meta_data.FieldMetaData("jobSubmissionId", org.apache.thrift.TFieldRequirementType.REQUIRED, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING)));
      metaDataMap = Collections.unmodifiableMap(tmpMap);
      org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(getLocalJobSubmission_args.class, metaDataMap);
    }

    public getLocalJobSubmission_args() {
    }

    public getLocalJobSubmission_args(
      org.apache.airavata.model.security.AuthzToken authzToken,
      String jobSubmissionId)
    {
      this();
      this.authzToken = authzToken;
      this.jobSubmissionId = jobSubmissionId;
    }

    /**
     * Performs a deep copy on <i>other</i>.
     */
    public getLocalJobSubmission_args(getLocalJobSubmission_args other) {
      if (other.isSetAuthzToken()) {
        this.authzToken = new org.apache.airavata.model.security.AuthzToken(other.authzToken);
      }
      if (other.isSetJobSubmissionId()) {
        this.jobSubmissionId = other.jobSubmissionId;
      }
    }

    public getLocalJobSubmission_args deepCopy() {
      return new getLocalJobSubmission_args(this);
    }

    @Override
    public void clear() {
      this.authzToken = null;
      this.jobSubmissionId = null;
    }

    public org.apache.airavata.model.security.AuthzToken getAuthzToken() {
      return this.authzToken;
    }

    public getLocalJobSubmission_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 String getJobSubmissionId() {
      return this.jobSubmissionId;
    }

    public getLocalJobSubmission_args setJobSubmissionId(String jobSubmissionId) {
      this.jobSubmissionId = jobSubmissionId;
      return this;
    }

    public void unsetJobSubmissionId() {
      this.jobSubmissionId = null;
    }

    /** Returns true if field jobSubmissionId is set (has been assigned a value) and false otherwise */
    public boolean isSetJobSubmissionId() {
      return this.jobSubmissionId != null;
    }

    public void setJobSubmissionIdIsSet(boolean value) {
      if (!value) {
        this.jobSubmissionId = null;
      }
    }

    public void setFieldValue(_Fields field, Object value) {
      switch (field) {
      case AUTHZ_TOKEN:
        if (value == null) {
          unsetAuthzToken();
        } else {
          setAuthzToken((org.apache.airavata.model.security.AuthzToken)value);
        }
        break;

      case JOB_SUBMISSION_ID:
        if (value == null) {
          unsetJobSubmissionId();
        } else {
          setJobSubmissionId((String)value);
        }
        break;

      }
    }

    public Object getFieldValue(_Fields field) {
      switch (field) {
      case AUTHZ_TOKEN:
        return getAuthzToken();

      case JOB_SUBMISSION_ID:
        return getJobSubmissionId();

      }
      throw new IllegalStateException();
    }

    /** Returns true if field corresponding to fieldID is set (has been assigned a value) and false otherwise */
    public boolean isSet(_Fields field) {
      if (field == null) {
        throw new IllegalArgumentException();
      }

      switch (field) {
      case AUTHZ_TOKEN:
        return isSetAuthzToken();
      case JOB_SUBMISSION_ID:
        return isSetJobSubmissionId();
      }
      throw new IllegalStateException();
    }

    @Override
    public boolean equals(Object that) {
      if (that == null)
        return false;
      if (that instanceof getLocalJobSubmission_args)
        return this.equals((getLocalJobSubmission_args)that);
      return false;
    }

    public boolean equals(getLocalJobSubmission_args that) {
      if (that == null)
        return false;

      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_jobSubmissionId = true && this.isSetJobSubmissionId();
      boolean that_present_jobSubmissionId = true && that.isSetJobSubmissionId();
      if (this_present_jobSubmissionId || that_present_jobSubmissionId) {
        if (!(this_present_jobSubmissionId && that_present_jobSubmissionId))
          return false;
        if (!this.jobSubmissionId.equals(that.jobSubmissionId))
          return false;
      }

      return true;
    }

    @Override
    public int hashCode() {
      List<Object> list = new ArrayList<Object>();

      boolean present_authzToken = true && (isSetAuthzToken());
      list.add(present_authzToken);
      if (present_authzToken)
        list.add(authzToken);

      boolean present_jobSubmissionId = true && (isSetJobSubmissionId());
      list.add(present_jobSubmissionId);
      if (present_jobSubmissionId)
        list.add(jobSubmissionId);

      return list.hashCode();
    }

    @Override
    public int compareTo(getLocalJobSubmission_args other) {
      if (!getClass().equals(other.getClass())) {
        return getClass().getName().compareTo(other.getClass().getName());
      }

      int lastComparison = 0;

      lastComparison = 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 = Boolean.valueOf(isSetJobSubmissionId()).compareTo(other.isSetJobSubmissionId());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetJobSubmissionId()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.jobSubmissionId, other.jobSubmissionId);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      return 0;
    }

    public _Fields fieldForId(int fieldId) {
      return _Fields.findByThriftId(fieldId);
    }

    public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
      schemes.get(iprot.getScheme()).getScheme().read(iprot, this);
    }

    public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException {
      schemes.get(oprot.getScheme()).getScheme().write(oprot, this);
    }

    @Override
    public String toString() {
      StringBuilder sb = new StringBuilder("getLocalJobSubmission_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("jobSubmissionId:");
      if (this.jobSubmissionId == null) {
        sb.append("null");
      } else {
        sb.append(this.jobSubmissionId);
      }
      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 (jobSubmissionId == null) {
        throw new org.apache.thrift.protocol.TProtocolException("Required field 'jobSubmissionId' 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, 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 getLocalJobSubmission_argsStandardSchemeFactory implements SchemeFactory {
      public getLocalJobSubmission_argsStandardScheme getScheme() {
        return new getLocalJobSubmission_argsStandardScheme();
      }
    }

    private static class getLocalJobSubmission_argsStandardScheme extends StandardScheme<getLocalJobSubmission_args> {

      public void read(org.apache.thrift.protocol.TProtocol iprot, getLocalJobSubmission_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: // JOB_SUBMISSION_ID
              if (schemeField.type == org.apache.thrift.protocol.TType.STRING) {
                struct.jobSubmissionId = iprot.readString();
                struct.setJobSubmissionIdIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            default:
              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
          }
          iprot.readFieldEnd();
        }
        iprot.readStructEnd();

        // check for required fields of primitive type, which can't be checked in the validate method
        struct.validate();
      }

      public void write(org.apache.thrift.protocol.TProtocol oprot, getLocalJobSubmission_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.jobSubmissionId != null) {
          oprot.writeFieldBegin(JOB_SUBMISSION_ID_FIELD_DESC);
          oprot.writeString(struct.jobSubmissionId);
          oprot.writeFieldEnd();
        }
        oprot.writeFieldStop();
        oprot.writeStructEnd();
      }

    }

    private static class getLocalJobSubmission_argsTupleSchemeFactory implements SchemeFactory {
      public getLocalJobSubmission_argsTupleScheme getScheme() {
        return new getLocalJobSubmission_argsTupleScheme();
      }
    }

    private static class getLocalJobSubmission_argsTupleScheme extends TupleScheme<getLocalJobSubmission_args> {

      @Override
      public void write(org.apache.thrift.protocol.TProtocol prot, getLocalJobSubmission_args struct) throws org.apache.thrift.TException {
        TTupleProtocol oprot = (TTupleProtocol) prot;
        struct.authzToken.write(oprot);
        oprot.writeString(struct.jobSubmissionId);
      }

      @Override
      public void read(org.apache.thrift.protocol.TProtocol prot, getLocalJobSubmission_args struct) throws org.apache.thrift.TException {
        TTupleProtocol iprot = (TTupleProtocol) prot;
        struct.authzToken = new org.apache.airavata.model.security.AuthzToken();
        struct.authzToken.read(iprot);
        struct.setAuthzTokenIsSet(true);
        struct.jobSubmissionId = iprot.readString();
        struct.setJobSubmissionIdIsSet(true);
      }
    }

  }

  public static class getLocalJobSubmission_result implements org.apache.thrift.TBase<getLocalJobSubmission_result, getLocalJobSubmission_result._Fields>, java.io.Serializable, Cloneable, Comparable<getLocalJobSubmission_result>   {
    private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("getLocalJobSubmission_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 IRE_FIELD_DESC = new org.apache.thrift.protocol.TField("ire", org.apache.thrift.protocol.TType.STRUCT, (short)1);
    private static final org.apache.thrift.protocol.TField ACE_FIELD_DESC = new org.apache.thrift.protocol.TField("ace", org.apache.thrift.protocol.TType.STRUCT, (short)2);
    private static final org.apache.thrift.protocol.TField ASE_FIELD_DESC = new org.apache.thrift.protocol.TField("ase", org.apache.thrift.protocol.TType.STRUCT, (short)3);
    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)4);

    private static final Map<Class<? extends IScheme>, SchemeFactory> schemes = new HashMap<Class<? extends IScheme>, SchemeFactory>();
    static {
      schemes.put(StandardScheme.class, new getLocalJobSubmission_resultStandardSchemeFactory());
      schemes.put(TupleScheme.class, new getLocalJobSubmission_resultTupleSchemeFactory());
    }

    public org.apache.airavata.model.appcatalog.computeresource.LOCALSubmission success; // required
    public org.apache.airavata.model.error.InvalidRequestException ire; // required
    public org.apache.airavata.model.error.AiravataClientException ace; // required
    public org.apache.airavata.model.error.AiravataSystemException ase; // 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"),
      IRE((short)1, "ire"),
      ACE((short)2, "ace"),
      ASE((short)3, "ase"),
      AE((short)4, "ae");

      private static final Map<String, _Fields> byName = new HashMap<String, _Fields>();

      static {
        for (_Fields field : EnumSet.allOf(_Fields.class)) {
          byName.put(field.getFieldName(), field);
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, or null if its not found.
       */
      public static _Fields findByThriftId(int fieldId) {
        switch(fieldId) {
          case 0: // SUCCESS
            return SUCCESS;
          case 1: // IRE
            return IRE;
          case 2: // ACE
            return ACE;
          case 3: // ASE
            return ASE;
          case 4: // 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 IllegalArgumentException("Field " + fieldId + " doesn't exist!");
        return fields;
      }

      /**
       * Find the _Fields constant that matches name, or null if its not found.
       */
      public static _Fields findByName(String name) {
        return byName.get(name);
      }

      private final short _thriftId;
      private final String _fieldName;

      _Fields(short thriftId, String fieldName) {
        _thriftId = thriftId;
        _fieldName = fieldName;
      }

      public short getThriftFieldId() {
        return _thriftId;
      }

      public String getFieldName() {
        return _fieldName;
      }
    }

    // isset id assignments
    public static final Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
    static {
      Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new EnumMap<_Fields, org.apache.thrift.meta_data.FieldMetaData>(_Fields.class);
      tmpMap.put(_Fields.SUCCESS, new org.apache.thrift.meta_data.FieldMetaData("success", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.StructMetaData(org.apache.thrift.protocol.TType.STRUCT, org.apache.airavata.model.appcatalog.computeresource.LOCALSubmission.class)));
      tmpMap.put(_Fields.IRE, new org.apache.thrift.meta_data.FieldMetaData("ire", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRUCT)));
      tmpMap.put(_Fields.ACE, new org.apache.thrift.meta_data.FieldMetaData("ace", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRUCT)));
      tmpMap.put(_Fields.ASE, new org.apache.thrift.meta_data.FieldMetaData("ase", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRUCT)));
      tmpMap.put(_Fields.AE, new org.apache.thrift.meta_data.FieldMetaData("ae", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRUCT)));
      metaDataMap = Collections.unmodifiableMap(tmpMap);
      org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(getLocalJobSubmission_result.class, metaDataMap);
    }

    public getLocalJobSubmission_result() {
    }

    public getLocalJobSubmission_result(
      org.apache.airavata.model.appcatalog.computeresource.LOCALSubmission success,
      org.apache.airavata.model.error.InvalidRequestException ire,
      org.apache.airavata.model.error.AiravataClientException ace,
      org.apache.airavata.model.error.AiravataSystemException ase,
      org.apache.airavata.model.error.AuthorizationException ae)
    {
      this();
      this.success = success;
      this.ire = ire;
      this.ace = ace;
      this.ase = ase;
      this.ae = ae;
    }

    /**
     * Performs a deep copy on <i>other</i>.
     */
    public getLocalJobSubmission_result(getLocalJobSubmission_result other) {
      if (other.isSetSuccess()) {
        this.success = new org.apache.airavata.model.appcatalog.computeresource.LOCALSubmission(other.success);
      }
      if (other.isSetIre()) {
        this.ire = new org.apache.airavata.model.error.InvalidRequestException(other.ire);
      }
      if (other.isSetAce()) {
        this.ace = new org.apache.airavata.model.error.AiravataClientException(other.ace);
      }
      if (other.isSetAse()) {
        this.ase = new org.apache.airavata.model.error.AiravataSystemException(other.ase);
      }
      if (other.isSetAe()) {
        this.ae = new org.apache.airavata.model.error.AuthorizationException(other.ae);
      }
    }

    public getLocalJobSubmission_result deepCopy() {
      return new getLocalJobSubmission_result(this);
    }

    @Override
    public void clear() {
      this.success = null;
      this.ire = null;
      this.ace = null;
      this.ase = null;
      this.ae = null;
    }

    public org.apache.airavata.model.appcatalog.computeresource.LOCALSubmission getSuccess() {
      return this.success;
    }

    public getLocalJobSubmission_result setSuccess(org.apache.airavata.model.appcatalog.computeresource.LOCALSubmission 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.model.error.InvalidRequestException getIre() {
      return this.ire;
    }

    public getLocalJobSubmission_result setIre(org.apache.airavata.model.error.InvalidRequestException ire) {
      this.ire = ire;
      return this;
    }

    public void unsetIre() {
      this.ire = null;
    }

    /** Returns true if field ire is set (has been assigned a value) and false otherwise */
    public boolean isSetIre() {
      return this.ire != null;
    }

    public void setIreIsSet(boolean value) {
      if (!value) {
        this.ire = null;
      }
    }

    public org.apache.airavata.model.error.AiravataClientException getAce() {
      return this.ace;
    }

    public getLocalJobSubmission_result setAce(org.apache.airavata.model.error.AiravataClientException ace) {
      this.ace = ace;
      return this;
    }

    public void unsetAce() {
      this.ace = null;
    }

    /** Returns true if field ace is set (has been assigned a value) and false otherwise */
    public boolean isSetAce() {
      return this.ace != null;
    }

    public void setAceIsSet(boolean value) {
      if (!value) {
        this.ace = null;
      }
    }

    public org.apache.airavata.model.error.AiravataSystemException getAse() {
      return this.ase;
    }

    public getLocalJobSubmission_result setAse(org.apache.airavata.model.error.AiravataSystemException ase) {
      this.ase = ase;
      return this;
    }

    public void unsetAse() {
      this.ase = null;
    }

    /** Returns true if field ase is set (has been assigned a value) and false otherwise */
    public boolean isSetAse() {
      return this.ase != null;
    }

    public void setAseIsSet(boolean value) {
      if (!value) {
        this.ase = null;
      }
    }

    public org.apache.airavata.model.error.AuthorizationException getAe() {
      return this.ae;
    }

    public getLocalJobSubmission_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, Object value) {
      switch (field) {
      case SUCCESS:
        if (value == null) {
          unsetSuccess();
        } else {
          setSuccess((org.apache.airavata.model.appcatalog.computeresource.LOCALSubmission)value);
        }
        break;

      case IRE:
        if (value == null) {
          unsetIre();
        } else {
          setIre((org.apache.airavata.model.error.InvalidRequestException)value);
        }
        break;

      case ACE:
        if (value == null) {
          unsetAce();
        } else {
          setAce((org.apache.airavata.model.error.AiravataClientException)value);
        }
        break;

      case ASE:
        if (value == null) {
          unsetAse();
        } else {
          setAse((org.apache.airavata.model.error.AiravataSystemException)value);
        }
        break;

      case AE:
        if (value == null) {
          unsetAe();
        } else {
          setAe((org.apache.airavata.model.error.AuthorizationException)value);
        }
        break;

      }
    }

    public Object getFieldValue(_Fields field) {
      switch (field) {
      case SUCCESS:
        return getSuccess();

      case IRE:
        return getIre();

      case ACE:
        return getAce();

      case ASE:
        return getAse();

      case AE:
        return getAe();

      }
      throw new IllegalStateException();
    }

    /** Returns true if field corresponding to fieldID is set (has been assigned a value) and false otherwise */
    public boolean isSet(_Fields field) {
      if (field == null) {
        throw new IllegalArgumentException();
      }

      switch (field) {
      case SUCCESS:
        return isSetSuccess();
      case IRE:
        return isSetIre();
      case ACE:
        return isSetAce();
      case ASE:
        return isSetAse();
      case AE:
        return isSetAe();
      }
      throw new IllegalStateException();
    }

    @Override
    public boolean equals(Object that) {
      if (that == null)
        return false;
      if (that instanceof getLocalJobSubmission_result)
        return this.equals((getLocalJobSubmission_result)that);
      return false;
    }

    public boolean equals(getLocalJobSubmission_result that) {
      if (that == null)
        return false;

      boolean this_present_success = true && this.isSetSuccess();
      boolean that_present_success = true && that.isSetSuccess();
      if (this_present_success || that_present_success) {
        if (!(this_present_success && that_present_success))
          return false;
        if (!this.success.equals(that.success))
          return false;
      }

      boolean this_present_ire = true && this.isSetIre();
      boolean that_present_ire = true && that.isSetIre();
      if (this_present_ire || that_present_ire) {
        if (!(this_present_ire && that_present_ire))
          return false;
        if (!this.ire.equals(that.ire))
          return false;
      }

      boolean this_present_ace = true && this.isSetAce();
      boolean that_present_ace = true && that.isSetAce();
      if (this_present_ace || that_present_ace) {
        if (!(this_present_ace && that_present_ace))
          return false;
        if (!this.ace.equals(that.ace))
          return false;
      }

      boolean this_present_ase = true && this.isSetAse();
      boolean that_present_ase = true && that.isSetAse();
      if (this_present_ase || that_present_ase) {
        if (!(this_present_ase && that_present_ase))
          return false;
        if (!this.ase.equals(that.ase))
          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() {
      List<Object> list = new ArrayList<Object>();

      boolean present_success = true && (isSetSuccess());
      list.add(present_success);
      if (present_success)
        list.add(success);

      boolean present_ire = true && (isSetIre());
      list.add(present_ire);
      if (present_ire)
        list.add(ire);

      boolean present_ace = true && (isSetAce());
      list.add(present_ace);
      if (present_ace)
        list.add(ace);

      boolean present_ase = true && (isSetAse());
      list.add(present_ase);
      if (present_ase)
        list.add(ase);

      boolean present_ae = true && (isSetAe());
      list.add(present_ae);
      if (present_ae)
        list.add(ae);

      return list.hashCode();
    }

    @Override
    public int compareTo(getLocalJobSubmission_result other) {
      if (!getClass().equals(other.getClass())) {
        return getClass().getName().compareTo(other.getClass().getName());
      }

      int lastComparison = 0;

      lastComparison = Boolean.valueOf(isSetSuccess()).compareTo(other.isSetSuccess());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetSuccess()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.success, other.success);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = Boolean.valueOf(isSetIre()).compareTo(other.isSetIre());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetIre()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.ire, other.ire);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = Boolean.valueOf(isSetAce()).compareTo(other.isSetAce());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetAce()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.ace, other.ace);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = Boolean.valueOf(isSetAse()).compareTo(other.isSetAse());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetAse()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.ase, other.ase);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = 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 {
      schemes.get(iprot.getScheme()).getScheme().read(iprot, this);
    }

    public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException {
      schemes.get(oprot.getScheme()).getScheme().write(oprot, this);
      }

    @Override
    public String toString() {
      StringBuilder sb = new StringBuilder("getLocalJobSubmission_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("ire:");
      if (this.ire == null) {
        sb.append("null");
      } else {
        sb.append(this.ire);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("ace:");
      if (this.ace == null) {
        sb.append("null");
      } else {
        sb.append(this.ace);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("ase:");
      if (this.ase == null) {
        sb.append("null");
      } else {
        sb.append(this.ase);
      }
      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, 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 getLocalJobSubmission_resultStandardSchemeFactory implements SchemeFactory {
      public getLocalJobSubmission_resultStandardScheme getScheme() {
        return new getLocalJobSubmission_resultStandardScheme();
      }
    }

    private static class getLocalJobSubmission_resultStandardScheme extends StandardScheme<getLocalJobSubmission_result> {

      public void read(org.apache.thrift.protocol.TProtocol iprot, getLocalJobSubmission_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.appcatalog.computeresource.LOCALSubmission();
                struct.success.read(iprot);
                struct.setSuccessIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 1: // IRE
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.ire = new org.apache.airavata.model.error.InvalidRequestException();
                struct.ire.read(iprot);
                struct.setIreIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 2: // ACE
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.ace = new org.apache.airavata.model.error.AiravataClientException();
                struct.ace.read(iprot);
                struct.setAceIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 3: // ASE
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.ase = new org.apache.airavata.model.error.AiravataSystemException();
                struct.ase.read(iprot);
                struct.setAseIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 4: // 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, getLocalJobSubmission_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.ire != null) {
          oprot.writeFieldBegin(IRE_FIELD_DESC);
          struct.ire.write(oprot);
          oprot.writeFieldEnd();
        }
        if (struct.ace != null) {
          oprot.writeFieldBegin(ACE_FIELD_DESC);
          struct.ace.write(oprot);
          oprot.writeFieldEnd();
        }
        if (struct.ase != null) {
          oprot.writeFieldBegin(ASE_FIELD_DESC);
          struct.ase.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 getLocalJobSubmission_resultTupleSchemeFactory implements SchemeFactory {
      public getLocalJobSubmission_resultTupleScheme getScheme() {
        return new getLocalJobSubmission_resultTupleScheme();
      }
    }

    private static class getLocalJobSubmission_resultTupleScheme extends TupleScheme<getLocalJobSubmission_result> {

      @Override
      public void write(org.apache.thrift.protocol.TProtocol prot, getLocalJobSubmission_result struct) throws org.apache.thrift.TException {
        TTupleProtocol oprot = (TTupleProtocol) prot;
        BitSet optionals = new BitSet();
        if (struct.isSetSuccess()) {
          optionals.set(0);
        }
        if (struct.isSetIre()) {
          optionals.set(1);
        }
        if (struct.isSetAce()) {
          optionals.set(2);
        }
        if (struct.isSetAse()) {
          optionals.set(3);
        }
        if (struct.isSetAe()) {
          optionals.set(4);
        }
        oprot.writeBitSet(optionals, 5);
        if (struct.isSetSuccess()) {
          struct.success.write(oprot);
        }
        if (struct.isSetIre()) {
          struct.ire.write(oprot);
        }
        if (struct.isSetAce()) {
          struct.ace.write(oprot);
        }
        if (struct.isSetAse()) {
          struct.ase.write(oprot);
        }
        if (struct.isSetAe()) {
          struct.ae.write(oprot);
        }
      }

      @Override
      public void read(org.apache.thrift.protocol.TProtocol prot, getLocalJobSubmission_result struct) throws org.apache.thrift.TException {
        TTupleProtocol iprot = (TTupleProtocol) prot;
        BitSet incoming = iprot.readBitSet(5);
        if (incoming.get(0)) {
          struct.success = new org.apache.airavata.model.appcatalog.computeresource.LOCALSubmission();
          struct.success.read(iprot);
          struct.setSuccessIsSet(true);
        }
        if (incoming.get(1)) {
          struct.ire = new org.apache.airavata.model.error.InvalidRequestException();
          struct.ire.read(iprot);
          struct.setIreIsSet(true);
        }
        if (incoming.get(2)) {
          struct.ace = new org.apache.airavata.model.error.AiravataClientException();
          struct.ace.read(iprot);
          struct.setAceIsSet(true);
        }
        if (incoming.get(3)) {
          struct.ase = new org.apache.airavata.model.error.AiravataSystemException();
          struct.ase.read(iprot);
          struct.setAseIsSet(true);
        }
        if (incoming.get(4)) {
          struct.ae = new org.apache.airavata.model.error.AuthorizationException();
          struct.ae.read(iprot);
          struct.setAeIsSet(true);
        }
      }
    }

  }

  public static class addSSHJobSubmissionDetails_args implements org.apache.thrift.TBase<addSSHJobSubmissionDetails_args, addSSHJobSubmissionDetails_args._Fields>, java.io.Serializable, Cloneable, Comparable<addSSHJobSubmissionDetails_args>   {
    private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("addSSHJobSubmissionDetails_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 COMPUTE_RESOURCE_ID_FIELD_DESC = new org.apache.thrift.protocol.TField("computeResourceId", org.apache.thrift.protocol.TType.STRING, (short)2);
    private static final org.apache.thrift.protocol.TField PRIORITY_ORDER_FIELD_DESC = new org.apache.thrift.protocol.TField("priorityOrder", org.apache.thrift.protocol.TType.I32, (short)3);
    private static final org.apache.thrift.protocol.TField SSH_JOB_SUBMISSION_FIELD_DESC = new org.apache.thrift.protocol.TField("sshJobSubmission", org.apache.thrift.protocol.TType.STRUCT, (short)4);

    private static final Map<Class<? extends IScheme>, SchemeFactory> schemes = new HashMap<Class<? extends IScheme>, SchemeFactory>();
    static {
      schemes.put(StandardScheme.class, new addSSHJobSubmissionDetails_argsStandardSchemeFactory());
      schemes.put(TupleScheme.class, new addSSHJobSubmissionDetails_argsTupleSchemeFactory());
    }

    public org.apache.airavata.model.security.AuthzToken authzToken; // required
    public String computeResourceId; // required
    public int priorityOrder; // required
    public org.apache.airavata.model.appcatalog.computeresource.SSHJobSubmission sshJobSubmission; // required

    /** 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"),
      COMPUTE_RESOURCE_ID((short)2, "computeResourceId"),
      PRIORITY_ORDER((short)3, "priorityOrder"),
      SSH_JOB_SUBMISSION((short)4, "sshJobSubmission");

      private static final Map<String, _Fields> byName = new HashMap<String, _Fields>();

      static {
        for (_Fields field : EnumSet.allOf(_Fields.class)) {
          byName.put(field.getFieldName(), field);
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, or null if its not found.
       */
      public static _Fields findByThriftId(int fieldId) {
        switch(fieldId) {
          case 1: // AUTHZ_TOKEN
            return AUTHZ_TOKEN;
          case 2: // COMPUTE_RESOURCE_ID
            return COMPUTE_RESOURCE_ID;
          case 3: // PRIORITY_ORDER
            return PRIORITY_ORDER;
          case 4: // SSH_JOB_SUBMISSION
            return SSH_JOB_SUBMISSION;
          default:
            return null;
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, throwing an exception
       * if it is not found.
       */
      public static _Fields findByThriftIdOrThrow(int fieldId) {
        _Fields fields = findByThriftId(fieldId);
        if (fields == null) throw new IllegalArgumentException("Field " + fieldId + " doesn't exist!");
        return fields;
      }

      /**
       * Find the _Fields constant that matches name, or null if its not found.
       */
      public static _Fields findByName(String name) {
        return byName.get(name);
      }

      private final short _thriftId;
      private final String _fieldName;

      _Fields(short thriftId, String fieldName) {
        _thriftId = thriftId;
        _fieldName = fieldName;
      }

      public short getThriftFieldId() {
        return _thriftId;
      }

      public String getFieldName() {
        return _fieldName;
      }
    }

    // isset id assignments
    private static final int __PRIORITYORDER_ISSET_ID = 0;
    private byte __isset_bitfield = 0;
    public static final Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
    static {
      Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new EnumMap<_Fields, org.apache.thrift.meta_data.FieldMetaData>(_Fields.class);
      tmpMap.put(_Fields.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.COMPUTE_RESOURCE_ID, new org.apache.thrift.meta_data.FieldMetaData("computeResourceId", org.apache.thrift.TFieldRequirementType.REQUIRED, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING)));
      tmpMap.put(_Fields.PRIORITY_ORDER, new org.apache.thrift.meta_data.FieldMetaData("priorityOrder", org.apache.thrift.TFieldRequirementType.REQUIRED, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.I32)));
      tmpMap.put(_Fields.SSH_JOB_SUBMISSION, new org.apache.thrift.meta_data.FieldMetaData("sshJobSubmission", org.apache.thrift.TFieldRequirementType.REQUIRED, 
          new org.apache.thrift.meta_data.StructMetaData(org.apache.thrift.protocol.TType.STRUCT, org.apache.airavata.model.appcatalog.computeresource.SSHJobSubmission.class)));
      metaDataMap = Collections.unmodifiableMap(tmpMap);
      org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(addSSHJobSubmissionDetails_args.class, metaDataMap);
    }

    public addSSHJobSubmissionDetails_args() {
    }

    public addSSHJobSubmissionDetails_args(
      org.apache.airavata.model.security.AuthzToken authzToken,
      String computeResourceId,
      int priorityOrder,
      org.apache.airavata.model.appcatalog.computeresource.SSHJobSubmission sshJobSubmission)
    {
      this();
      this.authzToken = authzToken;
      this.computeResourceId = computeResourceId;
      this.priorityOrder = priorityOrder;
      setPriorityOrderIsSet(true);
      this.sshJobSubmission = sshJobSubmission;
    }

    /**
     * Performs a deep copy on <i>other</i>.
     */
    public addSSHJobSubmissionDetails_args(addSSHJobSubmissionDetails_args other) {
      __isset_bitfield = other.__isset_bitfield;
      if (other.isSetAuthzToken()) {
        this.authzToken = new org.apache.airavata.model.security.AuthzToken(other.authzToken);
      }
      if (other.isSetComputeResourceId()) {
        this.computeResourceId = other.computeResourceId;
      }
      this.priorityOrder = other.priorityOrder;
      if (other.isSetSshJobSubmission()) {
        this.sshJobSubmission = new org.apache.airavata.model.appcatalog.computeresource.SSHJobSubmission(other.sshJobSubmission);
      }
    }

    public addSSHJobSubmissionDetails_args deepCopy() {
      return new addSSHJobSubmissionDetails_args(this);
    }

    @Override
    public void clear() {
      this.authzToken = null;
      this.computeResourceId = null;
      setPriorityOrderIsSet(false);
      this.priorityOrder = 0;
      this.sshJobSubmission = null;
    }

    public org.apache.airavata.model.security.AuthzToken getAuthzToken() {
      return this.authzToken;
    }

    public addSSHJobSubmissionDetails_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 String getComputeResourceId() {
      return this.computeResourceId;
    }

    public addSSHJobSubmissionDetails_args setComputeResourceId(String computeResourceId) {
      this.computeResourceId = computeResourceId;
      return this;
    }

    public void unsetComputeResourceId() {
      this.computeResourceId = null;
    }

    /** Returns true if field computeResourceId is set (has been assigned a value) and false otherwise */
    public boolean isSetComputeResourceId() {
      return this.computeResourceId != null;
    }

    public void setComputeResourceIdIsSet(boolean value) {
      if (!value) {
        this.computeResourceId = null;
      }
    }

    public int getPriorityOrder() {
      return this.priorityOrder;
    }

    public addSSHJobSubmissionDetails_args setPriorityOrder(int priorityOrder) {
      this.priorityOrder = priorityOrder;
      setPriorityOrderIsSet(true);
      return this;
    }

    public void unsetPriorityOrder() {
      __isset_bitfield = EncodingUtils.clearBit(__isset_bitfield, __PRIORITYORDER_ISSET_ID);
    }

    /** Returns true if field priorityOrder is set (has been assigned a value) and false otherwise */
    public boolean isSetPriorityOrder() {
      return EncodingUtils.testBit(__isset_bitfield, __PRIORITYORDER_ISSET_ID);
    }

    public void setPriorityOrderIsSet(boolean value) {
      __isset_bitfield = EncodingUtils.setBit(__isset_bitfield, __PRIORITYORDER_ISSET_ID, value);
    }

    public org.apache.airavata.model.appcatalog.computeresource.SSHJobSubmission getSshJobSubmission() {
      return this.sshJobSubmission;
    }

    public addSSHJobSubmissionDetails_args setSshJobSubmission(org.apache.airavata.model.appcatalog.computeresource.SSHJobSubmission sshJobSubmission) {
      this.sshJobSubmission = sshJobSubmission;
      return this;
    }

    public void unsetSshJobSubmission() {
      this.sshJobSubmission = null;
    }

    /** Returns true if field sshJobSubmission is set (has been assigned a value) and false otherwise */
    public boolean isSetSshJobSubmission() {
      return this.sshJobSubmission != null;
    }

    public void setSshJobSubmissionIsSet(boolean value) {
      if (!value) {
        this.sshJobSubmission = null;
      }
    }

    public void setFieldValue(_Fields field, Object value) {
      switch (field) {
      case AUTHZ_TOKEN:
        if (value == null) {
          unsetAuthzToken();
        } else {
          setAuthzToken((org.apache.airavata.model.security.AuthzToken)value);
        }
        break;

      case COMPUTE_RESOURCE_ID:
        if (value == null) {
          unsetComputeResourceId();
        } else {
          setComputeResourceId((String)value);
        }
        break;

      case PRIORITY_ORDER:
        if (value == null) {
          unsetPriorityOrder();
        } else {
          setPriorityOrder((Integer)value);
        }
        break;

      case SSH_JOB_SUBMISSION:
        if (value == null) {
          unsetSshJobSubmission();
        } else {
          setSshJobSubmission((org.apache.airavata.model.appcatalog.computeresource.SSHJobSubmission)value);
        }
        break;

      }
    }

    public Object getFieldValue(_Fields field) {
      switch (field) {
      case AUTHZ_TOKEN:
        return getAuthzToken();

      case COMPUTE_RESOURCE_ID:
        return getComputeResourceId();

      case PRIORITY_ORDER:
        return Integer.valueOf(getPriorityOrder());

      case SSH_JOB_SUBMISSION:
        return getSshJobSubmission();

      }
      throw new IllegalStateException();
    }

    /** Returns true if field corresponding to fieldID is set (has been assigned a value) and false otherwise */
    public boolean isSet(_Fields field) {
      if (field == null) {
        throw new IllegalArgumentException();
      }

      switch (field) {
      case AUTHZ_TOKEN:
        return isSetAuthzToken();
      case COMPUTE_RESOURCE_ID:
        return isSetComputeResourceId();
      case PRIORITY_ORDER:
        return isSetPriorityOrder();
      case SSH_JOB_SUBMISSION:
        return isSetSshJobSubmission();
      }
      throw new IllegalStateException();
    }

    @Override
    public boolean equals(Object that) {
      if (that == null)
        return false;
      if (that instanceof addSSHJobSubmissionDetails_args)
        return this.equals((addSSHJobSubmissionDetails_args)that);
      return false;
    }

    public boolean equals(addSSHJobSubmissionDetails_args that) {
      if (that == null)
        return false;

      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_computeResourceId = true && this.isSetComputeResourceId();
      boolean that_present_computeResourceId = true && that.isSetComputeResourceId();
      if (this_present_computeResourceId || that_present_computeResourceId) {
        if (!(this_present_computeResourceId && that_present_computeResourceId))
          return false;
        if (!this.computeResourceId.equals(that.computeResourceId))
          return false;
      }

      boolean this_present_priorityOrder = true;
      boolean that_present_priorityOrder = true;
      if (this_present_priorityOrder || that_present_priorityOrder) {
        if (!(this_present_priorityOrder && that_present_priorityOrder))
          return false;
        if (this.priorityOrder != that.priorityOrder)
          return false;
      }

      boolean this_present_sshJobSubmission = true && this.isSetSshJobSubmission();
      boolean that_present_sshJobSubmission = true && that.isSetSshJobSubmission();
      if (this_present_sshJobSubmission || that_present_sshJobSubmission) {
        if (!(this_present_sshJobSubmission && that_present_sshJobSubmission))
          return false;
        if (!this.sshJobSubmission.equals(that.sshJobSubmission))
          return false;
      }

      return true;
    }

    @Override
    public int hashCode() {
      List<Object> list = new ArrayList<Object>();

      boolean present_authzToken = true && (isSetAuthzToken());
      list.add(present_authzToken);
      if (present_authzToken)
        list.add(authzToken);

      boolean present_computeResourceId = true && (isSetComputeResourceId());
      list.add(present_computeResourceId);
      if (present_computeResourceId)
        list.add(computeResourceId);

      boolean present_priorityOrder = true;
      list.add(present_priorityOrder);
      if (present_priorityOrder)
        list.add(priorityOrder);

      boolean present_sshJobSubmission = true && (isSetSshJobSubmission());
      list.add(present_sshJobSubmission);
      if (present_sshJobSubmission)
        list.add(sshJobSubmission);

      return list.hashCode();
    }

    @Override
    public int compareTo(addSSHJobSubmissionDetails_args other) {
      if (!getClass().equals(other.getClass())) {
        return getClass().getName().compareTo(other.getClass().getName());
      }

      int lastComparison = 0;

      lastComparison = 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 = Boolean.valueOf(isSetComputeResourceId()).compareTo(other.isSetComputeResourceId());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetComputeResourceId()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.computeResourceId, other.computeResourceId);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = Boolean.valueOf(isSetPriorityOrder()).compareTo(other.isSetPriorityOrder());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetPriorityOrder()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.priorityOrder, other.priorityOrder);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = Boolean.valueOf(isSetSshJobSubmission()).compareTo(other.isSetSshJobSubmission());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetSshJobSubmission()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.sshJobSubmission, other.sshJobSubmission);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      return 0;
    }

    public _Fields fieldForId(int fieldId) {
      return _Fields.findByThriftId(fieldId);
    }

    public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
      schemes.get(iprot.getScheme()).getScheme().read(iprot, this);
    }

    public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException {
      schemes.get(oprot.getScheme()).getScheme().write(oprot, this);
    }

    @Override
    public String toString() {
      StringBuilder sb = new StringBuilder("addSSHJobSubmissionDetails_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("computeResourceId:");
      if (this.computeResourceId == null) {
        sb.append("null");
      } else {
        sb.append(this.computeResourceId);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("priorityOrder:");
      sb.append(this.priorityOrder);
      first = false;
      if (!first) sb.append(", ");
      sb.append("sshJobSubmission:");
      if (this.sshJobSubmission == null) {
        sb.append("null");
      } else {
        sb.append(this.sshJobSubmission);
      }
      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 (computeResourceId == null) {
        throw new org.apache.thrift.protocol.TProtocolException("Required field 'computeResourceId' was not present! Struct: " + toString());
      }
      // alas, we cannot check 'priorityOrder' because it's a primitive and you chose the non-beans generator.
      if (sshJobSubmission == null) {
        throw new org.apache.thrift.protocol.TProtocolException("Required field 'sshJobSubmission' was not present! Struct: " + toString());
      }
      // check for sub-struct validity
      if (authzToken != null) {
        authzToken.validate();
      }
      if (sshJobSubmission != null) {
        sshJobSubmission.validate();
      }
    }

    private void writeObject(java.io.ObjectOutputStream out) throws java.io.IOException {
      try {
        write(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(out)));
      } catch (org.apache.thrift.TException te) {
        throw new java.io.IOException(te);
      }
    }

    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, ClassNotFoundException {
      try {
        // 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 addSSHJobSubmissionDetails_argsStandardSchemeFactory implements SchemeFactory {
      public addSSHJobSubmissionDetails_argsStandardScheme getScheme() {
        return new addSSHJobSubmissionDetails_argsStandardScheme();
      }
    }

    private static class addSSHJobSubmissionDetails_argsStandardScheme extends StandardScheme<addSSHJobSubmissionDetails_args> {

      public void read(org.apache.thrift.protocol.TProtocol iprot, addSSHJobSubmissionDetails_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: // COMPUTE_RESOURCE_ID
              if (schemeField.type == org.apache.thrift.protocol.TType.STRING) {
                struct.computeResourceId = iprot.readString();
                struct.setComputeResourceIdIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 3: // PRIORITY_ORDER
              if (schemeField.type == org.apache.thrift.protocol.TType.I32) {
                struct.priorityOrder = iprot.readI32();
                struct.setPriorityOrderIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 4: // SSH_JOB_SUBMISSION
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.sshJobSubmission = new org.apache.airavata.model.appcatalog.computeresource.SSHJobSubmission();
                struct.sshJobSubmission.read(iprot);
                struct.setSshJobSubmissionIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            default:
              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
          }
          iprot.readFieldEnd();
        }
        iprot.readStructEnd();

        // check for required fields of primitive type, which can't be checked in the validate method
        if (!struct.isSetPriorityOrder()) {
          throw new org.apache.thrift.protocol.TProtocolException("Required field 'priorityOrder' was not found in serialized data! Struct: " + toString());
        }
        struct.validate();
      }

      public void write(org.apache.thrift.protocol.TProtocol oprot, addSSHJobSubmissionDetails_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.computeResourceId != null) {
          oprot.writeFieldBegin(COMPUTE_RESOURCE_ID_FIELD_DESC);
          oprot.writeString(struct.computeResourceId);
          oprot.writeFieldEnd();
        }
        oprot.writeFieldBegin(PRIORITY_ORDER_FIELD_DESC);
        oprot.writeI32(struct.priorityOrder);
        oprot.writeFieldEnd();
        if (struct.sshJobSubmission != null) {
          oprot.writeFieldBegin(SSH_JOB_SUBMISSION_FIELD_DESC);
          struct.sshJobSubmission.write(oprot);
          oprot.writeFieldEnd();
        }
        oprot.writeFieldStop();
        oprot.writeStructEnd();
      }

    }

    private static class addSSHJobSubmissionDetails_argsTupleSchemeFactory implements SchemeFactory {
      public addSSHJobSubmissionDetails_argsTupleScheme getScheme() {
        return new addSSHJobSubmissionDetails_argsTupleScheme();
      }
    }

    private static class addSSHJobSubmissionDetails_argsTupleScheme extends TupleScheme<addSSHJobSubmissionDetails_args> {

      @Override
      public void write(org.apache.thrift.protocol.TProtocol prot, addSSHJobSubmissionDetails_args struct) throws org.apache.thrift.TException {
        TTupleProtocol oprot = (TTupleProtocol) prot;
        struct.authzToken.write(oprot);
        oprot.writeString(struct.computeResourceId);
        oprot.writeI32(struct.priorityOrder);
        struct.sshJobSubmission.write(oprot);
      }

      @Override
      public void read(org.apache.thrift.protocol.TProtocol prot, addSSHJobSubmissionDetails_args struct) throws org.apache.thrift.TException {
        TTupleProtocol iprot = (TTupleProtocol) prot;
        struct.authzToken = new org.apache.airavata.model.security.AuthzToken();
        struct.authzToken.read(iprot);
        struct.setAuthzTokenIsSet(true);
        struct.computeResourceId = iprot.readString();
        struct.setComputeResourceIdIsSet(true);
        struct.priorityOrder = iprot.readI32();
        struct.setPriorityOrderIsSet(true);
        struct.sshJobSubmission = new org.apache.airavata.model.appcatalog.computeresource.SSHJobSubmission();
        struct.sshJobSubmission.read(iprot);
        struct.setSshJobSubmissionIsSet(true);
      }
    }

  }

  public static class addSSHJobSubmissionDetails_result implements org.apache.thrift.TBase<addSSHJobSubmissionDetails_result, addSSHJobSubmissionDetails_result._Fields>, java.io.Serializable, Cloneable, Comparable<addSSHJobSubmissionDetails_result>   {
    private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("addSSHJobSubmissionDetails_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 IRE_FIELD_DESC = new org.apache.thrift.protocol.TField("ire", org.apache.thrift.protocol.TType.STRUCT, (short)1);
    private static final org.apache.thrift.protocol.TField ACE_FIELD_DESC = new org.apache.thrift.protocol.TField("ace", org.apache.thrift.protocol.TType.STRUCT, (short)2);
    private static final org.apache.thrift.protocol.TField ASE_FIELD_DESC = new org.apache.thrift.protocol.TField("ase", org.apache.thrift.protocol.TType.STRUCT, (short)3);
    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)4);

    private static final Map<Class<? extends IScheme>, SchemeFactory> schemes = new HashMap<Class<? extends IScheme>, SchemeFactory>();
    static {
      schemes.put(StandardScheme.class, new addSSHJobSubmissionDetails_resultStandardSchemeFactory());
      schemes.put(TupleScheme.class, new addSSHJobSubmissionDetails_resultTupleSchemeFactory());
    }

    public String success; // required
    public org.apache.airavata.model.error.InvalidRequestException ire; // required
    public org.apache.airavata.model.error.AiravataClientException ace; // required
    public org.apache.airavata.model.error.AiravataSystemException ase; // 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"),
      IRE((short)1, "ire"),
      ACE((short)2, "ace"),
      ASE((short)3, "ase"),
      AE((short)4, "ae");

      private static final Map<String, _Fields> byName = new HashMap<String, _Fields>();

      static {
        for (_Fields field : EnumSet.allOf(_Fields.class)) {
          byName.put(field.getFieldName(), field);
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, or null if its not found.
       */
      public static _Fields findByThriftId(int fieldId) {
        switch(fieldId) {
          case 0: // SUCCESS
            return SUCCESS;
          case 1: // IRE
            return IRE;
          case 2: // ACE
            return ACE;
          case 3: // ASE
            return ASE;
          case 4: // 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 IllegalArgumentException("Field " + fieldId + " doesn't exist!");
        return fields;
      }

      /**
       * Find the _Fields constant that matches name, or null if its not found.
       */
      public static _Fields findByName(String name) {
        return byName.get(name);
      }

      private final short _thriftId;
      private final String _fieldName;

      _Fields(short thriftId, String fieldName) {
        _thriftId = thriftId;
        _fieldName = fieldName;
      }

      public short getThriftFieldId() {
        return _thriftId;
      }

      public String getFieldName() {
        return _fieldName;
      }
    }

    // isset id assignments
    public static final Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
    static {
      Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new EnumMap<_Fields, org.apache.thrift.meta_data.FieldMetaData>(_Fields.class);
      tmpMap.put(_Fields.SUCCESS, new org.apache.thrift.meta_data.FieldMetaData("success", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING)));
      tmpMap.put(_Fields.IRE, new org.apache.thrift.meta_data.FieldMetaData("ire", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRUCT)));
      tmpMap.put(_Fields.ACE, new org.apache.thrift.meta_data.FieldMetaData("ace", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRUCT)));
      tmpMap.put(_Fields.ASE, new org.apache.thrift.meta_data.FieldMetaData("ase", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRUCT)));
      tmpMap.put(_Fields.AE, new org.apache.thrift.meta_data.FieldMetaData("ae", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRUCT)));
      metaDataMap = Collections.unmodifiableMap(tmpMap);
      org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(addSSHJobSubmissionDetails_result.class, metaDataMap);
    }

    public addSSHJobSubmissionDetails_result() {
    }

    public addSSHJobSubmissionDetails_result(
      String success,
      org.apache.airavata.model.error.InvalidRequestException ire,
      org.apache.airavata.model.error.AiravataClientException ace,
      org.apache.airavata.model.error.AiravataSystemException ase,
      org.apache.airavata.model.error.AuthorizationException ae)
    {
      this();
      this.success = success;
      this.ire = ire;
      this.ace = ace;
      this.ase = ase;
      this.ae = ae;
    }

    /**
     * Performs a deep copy on <i>other</i>.
     */
    public addSSHJobSubmissionDetails_result(addSSHJobSubmissionDetails_result other) {
      if (other.isSetSuccess()) {
        this.success = other.success;
      }
      if (other.isSetIre()) {
        this.ire = new org.apache.airavata.model.error.InvalidRequestException(other.ire);
      }
      if (other.isSetAce()) {
        this.ace = new org.apache.airavata.model.error.AiravataClientException(other.ace);
      }
      if (other.isSetAse()) {
        this.ase = new org.apache.airavata.model.error.AiravataSystemException(other.ase);
      }
      if (other.isSetAe()) {
        this.ae = new org.apache.airavata.model.error.AuthorizationException(other.ae);
      }
    }

    public addSSHJobSubmissionDetails_result deepCopy() {
      return new addSSHJobSubmissionDetails_result(this);
    }

    @Override
    public void clear() {
      this.success = null;
      this.ire = null;
      this.ace = null;
      this.ase = null;
      this.ae = null;
    }

    public String getSuccess() {
      return this.success;
    }

    public addSSHJobSubmissionDetails_result setSuccess(String success) {
      this.success = success;
      return this;
    }

    public void unsetSuccess() {
      this.success = null;
    }

    /** Returns true if field success is set (has been assigned a value) and false otherwise */
    public boolean isSetSuccess() {
      return this.success != null;
    }

    public void setSuccessIsSet(boolean value) {
      if (!value) {
        this.success = null;
      }
    }

    public org.apache.airavata.model.error.InvalidRequestException getIre() {
      return this.ire;
    }

    public addSSHJobSubmissionDetails_result setIre(org.apache.airavata.model.error.InvalidRequestException ire) {
      this.ire = ire;
      return this;
    }

    public void unsetIre() {
      this.ire = null;
    }

    /** Returns true if field ire is set (has been assigned a value) and false otherwise */
    public boolean isSetIre() {
      return this.ire != null;
    }

    public void setIreIsSet(boolean value) {
      if (!value) {
        this.ire = null;
      }
    }

    public org.apache.airavata.model.error.AiravataClientException getAce() {
      return this.ace;
    }

    public addSSHJobSubmissionDetails_result setAce(org.apache.airavata.model.error.AiravataClientException ace) {
      this.ace = ace;
      return this;
    }

    public void unsetAce() {
      this.ace = null;
    }

    /** Returns true if field ace is set (has been assigned a value) and false otherwise */
    public boolean isSetAce() {
      return this.ace != null;
    }

    public void setAceIsSet(boolean value) {
      if (!value) {
        this.ace = null;
      }
    }

    public org.apache.airavata.model.error.AiravataSystemException getAse() {
      return this.ase;
    }

    public addSSHJobSubmissionDetails_result setAse(org.apache.airavata.model.error.AiravataSystemException ase) {
      this.ase = ase;
      return this;
    }

    public void unsetAse() {
      this.ase = null;
    }

    /** Returns true if field ase is set (has been assigned a value) and false otherwise */
    public boolean isSetAse() {
      return this.ase != null;
    }

    public void setAseIsSet(boolean value) {
      if (!value) {
        this.ase = null;
      }
    }

    public org.apache.airavata.model.error.AuthorizationException getAe() {
      return this.ae;
    }

    public addSSHJobSubmissionDetails_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, Object value) {
      switch (field) {
      case SUCCESS:
        if (value == null) {
          unsetSuccess();
        } else {
          setSuccess((String)value);
        }
        break;

      case IRE:
        if (value == null) {
          unsetIre();
        } else {
          setIre((org.apache.airavata.model.error.InvalidRequestException)value);
        }
        break;

      case ACE:
        if (value == null) {
          unsetAce();
        } else {
          setAce((org.apache.airavata.model.error.AiravataClientException)value);
        }
        break;

      case ASE:
        if (value == null) {
          unsetAse();
        } else {
          setAse((org.apache.airavata.model.error.AiravataSystemException)value);
        }
        break;

      case AE:
        if (value == null) {
          unsetAe();
        } else {
          setAe((org.apache.airavata.model.error.AuthorizationException)value);
        }
        break;

      }
    }

    public Object getFieldValue(_Fields field) {
      switch (field) {
      case SUCCESS:
        return getSuccess();

      case IRE:
        return getIre();

      case ACE:
        return getAce();

      case ASE:
        return getAse();

      case AE:
        return getAe();

      }
      throw new IllegalStateException();
    }

    /** Returns true if field corresponding to fieldID is set (has been assigned a value) and false otherwise */
    public boolean isSet(_Fields field) {
      if (field == null) {
        throw new IllegalArgumentException();
      }

      switch (field) {
      case SUCCESS:
        return isSetSuccess();
      case IRE:
        return isSetIre();
      case ACE:
        return isSetAce();
      case ASE:
        return isSetAse();
      case AE:
        return isSetAe();
      }
      throw new IllegalStateException();
    }

    @Override
    public boolean equals(Object that) {
      if (that == null)
        return false;
      if (that instanceof addSSHJobSubmissionDetails_result)
        return this.equals((addSSHJobSubmissionDetails_result)that);
      return false;
    }

    public boolean equals(addSSHJobSubmissionDetails_result that) {
      if (that == null)
        return false;

      boolean this_present_success = true && this.isSetSuccess();
      boolean that_present_success = true && that.isSetSuccess();
      if (this_present_success || that_present_success) {
        if (!(this_present_success && that_present_success))
          return false;
        if (!this.success.equals(that.success))
          return false;
      }

      boolean this_present_ire = true && this.isSetIre();
      boolean that_present_ire = true && that.isSetIre();
      if (this_present_ire || that_present_ire) {
        if (!(this_present_ire && that_present_ire))
          return false;
        if (!this.ire.equals(that.ire))
          return false;
      }

      boolean this_present_ace = true && this.isSetAce();
      boolean that_present_ace = true && that.isSetAce();
      if (this_present_ace || that_present_ace) {
        if (!(this_present_ace && that_present_ace))
          return false;
        if (!this.ace.equals(that.ace))
          return false;
      }

      boolean this_present_ase = true && this.isSetAse();
      boolean that_present_ase = true && that.isSetAse();
      if (this_present_ase || that_present_ase) {
        if (!(this_present_ase && that_present_ase))
          return false;
        if (!this.ase.equals(that.ase))
          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() {
      List<Object> list = new ArrayList<Object>();

      boolean present_success = true && (isSetSuccess());
      list.add(present_success);
      if (present_success)
        list.add(success);

      boolean present_ire = true && (isSetIre());
      list.add(present_ire);
      if (present_ire)
        list.add(ire);

      boolean present_ace = true && (isSetAce());
      list.add(present_ace);
      if (present_ace)
        list.add(ace);

      boolean present_ase = true && (isSetAse());
      list.add(present_ase);
      if (present_ase)
        list.add(ase);

      boolean present_ae = true && (isSetAe());
      list.add(present_ae);
      if (present_ae)
        list.add(ae);

      return list.hashCode();
    }

    @Override
    public int compareTo(addSSHJobSubmissionDetails_result other) {
      if (!getClass().equals(other.getClass())) {
        return getClass().getName().compareTo(other.getClass().getName());
      }

      int lastComparison = 0;

      lastComparison = Boolean.valueOf(isSetSuccess()).compareTo(other.isSetSuccess());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetSuccess()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.success, other.success);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = Boolean.valueOf(isSetIre()).compareTo(other.isSetIre());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetIre()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.ire, other.ire);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = Boolean.valueOf(isSetAce()).compareTo(other.isSetAce());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetAce()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.ace, other.ace);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = Boolean.valueOf(isSetAse()).compareTo(other.isSetAse());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetAse()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.ase, other.ase);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = 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 {
      schemes.get(iprot.getScheme()).getScheme().read(iprot, this);
    }

    public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException {
      schemes.get(oprot.getScheme()).getScheme().write(oprot, this);
      }

    @Override
    public String toString() {
      StringBuilder sb = new StringBuilder("addSSHJobSubmissionDetails_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("ire:");
      if (this.ire == null) {
        sb.append("null");
      } else {
        sb.append(this.ire);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("ace:");
      if (this.ace == null) {
        sb.append("null");
      } else {
        sb.append(this.ace);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("ase:");
      if (this.ase == null) {
        sb.append("null");
      } else {
        sb.append(this.ase);
      }
      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, 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 addSSHJobSubmissionDetails_resultStandardSchemeFactory implements SchemeFactory {
      public addSSHJobSubmissionDetails_resultStandardScheme getScheme() {
        return new addSSHJobSubmissionDetails_resultStandardScheme();
      }
    }

    private static class addSSHJobSubmissionDetails_resultStandardScheme extends StandardScheme<addSSHJobSubmissionDetails_result> {

      public void read(org.apache.thrift.protocol.TProtocol iprot, addSSHJobSubmissionDetails_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: // IRE
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.ire = new org.apache.airavata.model.error.InvalidRequestException();
                struct.ire.read(iprot);
                struct.setIreIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 2: // ACE
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.ace = new org.apache.airavata.model.error.AiravataClientException();
                struct.ace.read(iprot);
                struct.setAceIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 3: // ASE
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.ase = new org.apache.airavata.model.error.AiravataSystemException();
                struct.ase.read(iprot);
                struct.setAseIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 4: // 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, addSSHJobSubmissionDetails_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.ire != null) {
          oprot.writeFieldBegin(IRE_FIELD_DESC);
          struct.ire.write(oprot);
          oprot.writeFieldEnd();
        }
        if (struct.ace != null) {
          oprot.writeFieldBegin(ACE_FIELD_DESC);
          struct.ace.write(oprot);
          oprot.writeFieldEnd();
        }
        if (struct.ase != null) {
          oprot.writeFieldBegin(ASE_FIELD_DESC);
          struct.ase.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 addSSHJobSubmissionDetails_resultTupleSchemeFactory implements SchemeFactory {
      public addSSHJobSubmissionDetails_resultTupleScheme getScheme() {
        return new addSSHJobSubmissionDetails_resultTupleScheme();
      }
    }

    private static class addSSHJobSubmissionDetails_resultTupleScheme extends TupleScheme<addSSHJobSubmissionDetails_result> {

      @Override
      public void write(org.apache.thrift.protocol.TProtocol prot, addSSHJobSubmissionDetails_result struct) throws org.apache.thrift.TException {
        TTupleProtocol oprot = (TTupleProtocol) prot;
        BitSet optionals = new BitSet();
        if (struct.isSetSuccess()) {
          optionals.set(0);
        }
        if (struct.isSetIre()) {
          optionals.set(1);
        }
        if (struct.isSetAce()) {
          optionals.set(2);
        }
        if (struct.isSetAse()) {
          optionals.set(3);
        }
        if (struct.isSetAe()) {
          optionals.set(4);
        }
        oprot.writeBitSet(optionals, 5);
        if (struct.isSetSuccess()) {
          oprot.writeString(struct.success);
        }
        if (struct.isSetIre()) {
          struct.ire.write(oprot);
        }
        if (struct.isSetAce()) {
          struct.ace.write(oprot);
        }
        if (struct.isSetAse()) {
          struct.ase.write(oprot);
        }
        if (struct.isSetAe()) {
          struct.ae.write(oprot);
        }
      }

      @Override
      public void read(org.apache.thrift.protocol.TProtocol prot, addSSHJobSubmissionDetails_result struct) throws org.apache.thrift.TException {
        TTupleProtocol iprot = (TTupleProtocol) prot;
        BitSet incoming = iprot.readBitSet(5);
        if (incoming.get(0)) {
          struct.success = iprot.readString();
          struct.setSuccessIsSet(true);
        }
        if (incoming.get(1)) {
          struct.ire = new org.apache.airavata.model.error.InvalidRequestException();
          struct.ire.read(iprot);
          struct.setIreIsSet(true);
        }
        if (incoming.get(2)) {
          struct.ace = new org.apache.airavata.model.error.AiravataClientException();
          struct.ace.read(iprot);
          struct.setAceIsSet(true);
        }
        if (incoming.get(3)) {
          struct.ase = new org.apache.airavata.model.error.AiravataSystemException();
          struct.ase.read(iprot);
          struct.setAseIsSet(true);
        }
        if (incoming.get(4)) {
          struct.ae = new org.apache.airavata.model.error.AuthorizationException();
          struct.ae.read(iprot);
          struct.setAeIsSet(true);
        }
      }
    }

  }

  public static class addSSHForkJobSubmissionDetails_args implements org.apache.thrift.TBase<addSSHForkJobSubmissionDetails_args, addSSHForkJobSubmissionDetails_args._Fields>, java.io.Serializable, Cloneable, Comparable<addSSHForkJobSubmissionDetails_args>   {
    private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("addSSHForkJobSubmissionDetails_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 COMPUTE_RESOURCE_ID_FIELD_DESC = new org.apache.thrift.protocol.TField("computeResourceId", org.apache.thrift.protocol.TType.STRING, (short)2);
    private static final org.apache.thrift.protocol.TField PRIORITY_ORDER_FIELD_DESC = new org.apache.thrift.protocol.TField("priorityOrder", org.apache.thrift.protocol.TType.I32, (short)3);
    private static final org.apache.thrift.protocol.TField SSH_JOB_SUBMISSION_FIELD_DESC = new org.apache.thrift.protocol.TField("sshJobSubmission", org.apache.thrift.protocol.TType.STRUCT, (short)4);

    private static final Map<Class<? extends IScheme>, SchemeFactory> schemes = new HashMap<Class<? extends IScheme>, SchemeFactory>();
    static {
      schemes.put(StandardScheme.class, new addSSHForkJobSubmissionDetails_argsStandardSchemeFactory());
      schemes.put(TupleScheme.class, new addSSHForkJobSubmissionDetails_argsTupleSchemeFactory());
    }

    public org.apache.airavata.model.security.AuthzToken authzToken; // required
    public String computeResourceId; // required
    public int priorityOrder; // required
    public org.apache.airavata.model.appcatalog.computeresource.SSHJobSubmission sshJobSubmission; // required

    /** 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"),
      COMPUTE_RESOURCE_ID((short)2, "computeResourceId"),
      PRIORITY_ORDER((short)3, "priorityOrder"),
      SSH_JOB_SUBMISSION((short)4, "sshJobSubmission");

      private static final Map<String, _Fields> byName = new HashMap<String, _Fields>();

      static {
        for (_Fields field : EnumSet.allOf(_Fields.class)) {
          byName.put(field.getFieldName(), field);
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, or null if its not found.
       */
      public static _Fields findByThriftId(int fieldId) {
        switch(fieldId) {
          case 1: // AUTHZ_TOKEN
            return AUTHZ_TOKEN;
          case 2: // COMPUTE_RESOURCE_ID
            return COMPUTE_RESOURCE_ID;
          case 3: // PRIORITY_ORDER
            return PRIORITY_ORDER;
          case 4: // SSH_JOB_SUBMISSION
            return SSH_JOB_SUBMISSION;
          default:
            return null;
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, throwing an exception
       * if it is not found.
       */
      public static _Fields findByThriftIdOrThrow(int fieldId) {
        _Fields fields = findByThriftId(fieldId);
        if (fields == null) throw new IllegalArgumentException("Field " + fieldId + " doesn't exist!");
        return fields;
      }

      /**
       * Find the _Fields constant that matches name, or null if its not found.
       */
      public static _Fields findByName(String name) {
        return byName.get(name);
      }

      private final short _thriftId;
      private final String _fieldName;

      _Fields(short thriftId, String fieldName) {
        _thriftId = thriftId;
        _fieldName = fieldName;
      }

      public short getThriftFieldId() {
        return _thriftId;
      }

      public String getFieldName() {
        return _fieldName;
      }
    }

    // isset id assignments
    private static final int __PRIORITYORDER_ISSET_ID = 0;
    private byte __isset_bitfield = 0;
    public static final Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
    static {
      Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new EnumMap<_Fields, org.apache.thrift.meta_data.FieldMetaData>(_Fields.class);
      tmpMap.put(_Fields.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.COMPUTE_RESOURCE_ID, new org.apache.thrift.meta_data.FieldMetaData("computeResourceId", org.apache.thrift.TFieldRequirementType.REQUIRED, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING)));
      tmpMap.put(_Fields.PRIORITY_ORDER, new org.apache.thrift.meta_data.FieldMetaData("priorityOrder", org.apache.thrift.TFieldRequirementType.REQUIRED, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.I32)));
      tmpMap.put(_Fields.SSH_JOB_SUBMISSION, new org.apache.thrift.meta_data.FieldMetaData("sshJobSubmission", org.apache.thrift.TFieldRequirementType.REQUIRED, 
          new org.apache.thrift.meta_data.StructMetaData(org.apache.thrift.protocol.TType.STRUCT, org.apache.airavata.model.appcatalog.computeresource.SSHJobSubmission.class)));
      metaDataMap = Collections.unmodifiableMap(tmpMap);
      org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(addSSHForkJobSubmissionDetails_args.class, metaDataMap);
    }

    public addSSHForkJobSubmissionDetails_args() {
    }

    public addSSHForkJobSubmissionDetails_args(
      org.apache.airavata.model.security.AuthzToken authzToken,
      String computeResourceId,
      int priorityOrder,
      org.apache.airavata.model.appcatalog.computeresource.SSHJobSubmission sshJobSubmission)
    {
      this();
      this.authzToken = authzToken;
      this.computeResourceId = computeResourceId;
      this.priorityOrder = priorityOrder;
      setPriorityOrderIsSet(true);
      this.sshJobSubmission = sshJobSubmission;
    }

    /**
     * Performs a deep copy on <i>other</i>.
     */
    public addSSHForkJobSubmissionDetails_args(addSSHForkJobSubmissionDetails_args other) {
      __isset_bitfield = other.__isset_bitfield;
      if (other.isSetAuthzToken()) {
        this.authzToken = new org.apache.airavata.model.security.AuthzToken(other.authzToken);
      }
      if (other.isSetComputeResourceId()) {
        this.computeResourceId = other.computeResourceId;
      }
      this.priorityOrder = other.priorityOrder;
      if (other.isSetSshJobSubmission()) {
        this.sshJobSubmission = new org.apache.airavata.model.appcatalog.computeresource.SSHJobSubmission(other.sshJobSubmission);
      }
    }

    public addSSHForkJobSubmissionDetails_args deepCopy() {
      return new addSSHForkJobSubmissionDetails_args(this);
    }

    @Override
    public void clear() {
      this.authzToken = null;
      this.computeResourceId = null;
      setPriorityOrderIsSet(false);
      this.priorityOrder = 0;
      this.sshJobSubmission = null;
    }

    public org.apache.airavata.model.security.AuthzToken getAuthzToken() {
      return this.authzToken;
    }

    public addSSHForkJobSubmissionDetails_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 String getComputeResourceId() {
      return this.computeResourceId;
    }

    public addSSHForkJobSubmissionDetails_args setComputeResourceId(String computeResourceId) {
      this.computeResourceId = computeResourceId;
      return this;
    }

    public void unsetComputeResourceId() {
      this.computeResourceId = null;
    }

    /** Returns true if field computeResourceId is set (has been assigned a value) and false otherwise */
    public boolean isSetComputeResourceId() {
      return this.computeResourceId != null;
    }

    public void setComputeResourceIdIsSet(boolean value) {
      if (!value) {
        this.computeResourceId = null;
      }
    }

    public int getPriorityOrder() {
      return this.priorityOrder;
    }

    public addSSHForkJobSubmissionDetails_args setPriorityOrder(int priorityOrder) {
      this.priorityOrder = priorityOrder;
      setPriorityOrderIsSet(true);
      return this;
    }

    public void unsetPriorityOrder() {
      __isset_bitfield = EncodingUtils.clearBit(__isset_bitfield, __PRIORITYORDER_ISSET_ID);
    }

    /** Returns true if field priorityOrder is set (has been assigned a value) and false otherwise */
    public boolean isSetPriorityOrder() {
      return EncodingUtils.testBit(__isset_bitfield, __PRIORITYORDER_ISSET_ID);
    }

    public void setPriorityOrderIsSet(boolean value) {
      __isset_bitfield = EncodingUtils.setBit(__isset_bitfield, __PRIORITYORDER_ISSET_ID, value);
    }

    public org.apache.airavata.model.appcatalog.computeresource.SSHJobSubmission getSshJobSubmission() {
      return this.sshJobSubmission;
    }

    public addSSHForkJobSubmissionDetails_args setSshJobSubmission(org.apache.airavata.model.appcatalog.computeresource.SSHJobSubmission sshJobSubmission) {
      this.sshJobSubmission = sshJobSubmission;
      return this;
    }

    public void unsetSshJobSubmission() {
      this.sshJobSubmission = null;
    }

    /** Returns true if field sshJobSubmission is set (has been assigned a value) and false otherwise */
    public boolean isSetSshJobSubmission() {
      return this.sshJobSubmission != null;
    }

    public void setSshJobSubmissionIsSet(boolean value) {
      if (!value) {
        this.sshJobSubmission = null;
      }
    }

    public void setFieldValue(_Fields field, Object value) {
      switch (field) {
      case AUTHZ_TOKEN:
        if (value == null) {
          unsetAuthzToken();
        } else {
          setAuthzToken((org.apache.airavata.model.security.AuthzToken)value);
        }
        break;

      case COMPUTE_RESOURCE_ID:
        if (value == null) {
          unsetComputeResourceId();
        } else {
          setComputeResourceId((String)value);
        }
        break;

      case PRIORITY_ORDER:
        if (value == null) {
          unsetPriorityOrder();
        } else {
          setPriorityOrder((Integer)value);
        }
        break;

      case SSH_JOB_SUBMISSION:
        if (value == null) {
          unsetSshJobSubmission();
        } else {
          setSshJobSubmission((org.apache.airavata.model.appcatalog.computeresource.SSHJobSubmission)value);
        }
        break;

      }
    }

    public Object getFieldValue(_Fields field) {
      switch (field) {
      case AUTHZ_TOKEN:
        return getAuthzToken();

      case COMPUTE_RESOURCE_ID:
        return getComputeResourceId();

      case PRIORITY_ORDER:
        return Integer.valueOf(getPriorityOrder());

      case SSH_JOB_SUBMISSION:
        return getSshJobSubmission();

      }
      throw new IllegalStateException();
    }

    /** Returns true if field corresponding to fieldID is set (has been assigned a value) and false otherwise */
    public boolean isSet(_Fields field) {
      if (field == null) {
        throw new IllegalArgumentException();
      }

      switch (field) {
      case AUTHZ_TOKEN:
        return isSetAuthzToken();
      case COMPUTE_RESOURCE_ID:
        return isSetComputeResourceId();
      case PRIORITY_ORDER:
        return isSetPriorityOrder();
      case SSH_JOB_SUBMISSION:
        return isSetSshJobSubmission();
      }
      throw new IllegalStateException();
    }

    @Override
    public boolean equals(Object that) {
      if (that == null)
        return false;
      if (that instanceof addSSHForkJobSubmissionDetails_args)
        return this.equals((addSSHForkJobSubmissionDetails_args)that);
      return false;
    }

    public boolean equals(addSSHForkJobSubmissionDetails_args that) {
      if (that == null)
        return false;

      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_computeResourceId = true && this.isSetComputeResourceId();
      boolean that_present_computeResourceId = true && that.isSetComputeResourceId();
      if (this_present_computeResourceId || that_present_computeResourceId) {
        if (!(this_present_computeResourceId && that_present_computeResourceId))
          return false;
        if (!this.computeResourceId.equals(that.computeResourceId))
          return false;
      }

      boolean this_present_priorityOrder = true;
      boolean that_present_priorityOrder = true;
      if (this_present_priorityOrder || that_present_priorityOrder) {
        if (!(this_present_priorityOrder && that_present_priorityOrder))
          return false;
        if (this.priorityOrder != that.priorityOrder)
          return false;
      }

      boolean this_present_sshJobSubmission = true && this.isSetSshJobSubmission();
      boolean that_present_sshJobSubmission = true && that.isSetSshJobSubmission();
      if (this_present_sshJobSubmission || that_present_sshJobSubmission) {
        if (!(this_present_sshJobSubmission && that_present_sshJobSubmission))
          return false;
        if (!this.sshJobSubmission.equals(that.sshJobSubmission))
          return false;
      }

      return true;
    }

    @Override
    public int hashCode() {
      List<Object> list = new ArrayList<Object>();

      boolean present_authzToken = true && (isSetAuthzToken());
      list.add(present_authzToken);
      if (present_authzToken)
        list.add(authzToken);

      boolean present_computeResourceId = true && (isSetComputeResourceId());
      list.add(present_computeResourceId);
      if (present_computeResourceId)
        list.add(computeResourceId);

      boolean present_priorityOrder = true;
      list.add(present_priorityOrder);
      if (present_priorityOrder)
        list.add(priorityOrder);

      boolean present_sshJobSubmission = true && (isSetSshJobSubmission());
      list.add(present_sshJobSubmission);
      if (present_sshJobSubmission)
        list.add(sshJobSubmission);

      return list.hashCode();
    }

    @Override
    public int compareTo(addSSHForkJobSubmissionDetails_args other) {
      if (!getClass().equals(other.getClass())) {
        return getClass().getName().compareTo(other.getClass().getName());
      }

      int lastComparison = 0;

      lastComparison = 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 = Boolean.valueOf(isSetComputeResourceId()).compareTo(other.isSetComputeResourceId());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetComputeResourceId()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.computeResourceId, other.computeResourceId);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = Boolean.valueOf(isSetPriorityOrder()).compareTo(other.isSetPriorityOrder());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetPriorityOrder()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.priorityOrder, other.priorityOrder);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = Boolean.valueOf(isSetSshJobSubmission()).compareTo(other.isSetSshJobSubmission());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetSshJobSubmission()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.sshJobSubmission, other.sshJobSubmission);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      return 0;
    }

    public _Fields fieldForId(int fieldId) {
      return _Fields.findByThriftId(fieldId);
    }

    public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
      schemes.get(iprot.getScheme()).getScheme().read(iprot, this);
    }

    public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException {
      schemes.get(oprot.getScheme()).getScheme().write(oprot, this);
    }

    @Override
    public String toString() {
      StringBuilder sb = new StringBuilder("addSSHForkJobSubmissionDetails_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("computeResourceId:");
      if (this.computeResourceId == null) {
        sb.append("null");
      } else {
        sb.append(this.computeResourceId);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("priorityOrder:");
      sb.append(this.priorityOrder);
      first = false;
      if (!first) sb.append(", ");
      sb.append("sshJobSubmission:");
      if (this.sshJobSubmission == null) {
        sb.append("null");
      } else {
        sb.append(this.sshJobSubmission);
      }
      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 (computeResourceId == null) {
        throw new org.apache.thrift.protocol.TProtocolException("Required field 'computeResourceId' was not present! Struct: " + toString());
      }
      // alas, we cannot check 'priorityOrder' because it's a primitive and you chose the non-beans generator.
      if (sshJobSubmission == null) {
        throw new org.apache.thrift.protocol.TProtocolException("Required field 'sshJobSubmission' was not present! Struct: " + toString());
      }
      // check for sub-struct validity
      if (authzToken != null) {
        authzToken.validate();
      }
      if (sshJobSubmission != null) {
        sshJobSubmission.validate();
      }
    }

    private void writeObject(java.io.ObjectOutputStream out) throws java.io.IOException {
      try {
        write(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(out)));
      } catch (org.apache.thrift.TException te) {
        throw new java.io.IOException(te);
      }
    }

    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, ClassNotFoundException {
      try {
        // 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 addSSHForkJobSubmissionDetails_argsStandardSchemeFactory implements SchemeFactory {
      public addSSHForkJobSubmissionDetails_argsStandardScheme getScheme() {
        return new addSSHForkJobSubmissionDetails_argsStandardScheme();
      }
    }

    private static class addSSHForkJobSubmissionDetails_argsStandardScheme extends StandardScheme<addSSHForkJobSubmissionDetails_args> {

      public void read(org.apache.thrift.protocol.TProtocol iprot, addSSHForkJobSubmissionDetails_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: // COMPUTE_RESOURCE_ID
              if (schemeField.type == org.apache.thrift.protocol.TType.STRING) {
                struct.computeResourceId = iprot.readString();
                struct.setComputeResourceIdIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 3: // PRIORITY_ORDER
              if (schemeField.type == org.apache.thrift.protocol.TType.I32) {
                struct.priorityOrder = iprot.readI32();
                struct.setPriorityOrderIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 4: // SSH_JOB_SUBMISSION
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.sshJobSubmission = new org.apache.airavata.model.appcatalog.computeresource.SSHJobSubmission();
                struct.sshJobSubmission.read(iprot);
                struct.setSshJobSubmissionIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            default:
              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
          }
          iprot.readFieldEnd();
        }
        iprot.readStructEnd();

        // check for required fields of primitive type, which can't be checked in the validate method
        if (!struct.isSetPriorityOrder()) {
          throw new org.apache.thrift.protocol.TProtocolException("Required field 'priorityOrder' was not found in serialized data! Struct: " + toString());
        }
        struct.validate();
      }

      public void write(org.apache.thrift.protocol.TProtocol oprot, addSSHForkJobSubmissionDetails_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.computeResourceId != null) {
          oprot.writeFieldBegin(COMPUTE_RESOURCE_ID_FIELD_DESC);
          oprot.writeString(struct.computeResourceId);
          oprot.writeFieldEnd();
        }
        oprot.writeFieldBegin(PRIORITY_ORDER_FIELD_DESC);
        oprot.writeI32(struct.priorityOrder);
        oprot.writeFieldEnd();
        if (struct.sshJobSubmission != null) {
          oprot.writeFieldBegin(SSH_JOB_SUBMISSION_FIELD_DESC);
          struct.sshJobSubmission.write(oprot);
          oprot.writeFieldEnd();
        }
        oprot.writeFieldStop();
        oprot.writeStructEnd();
      }

    }

    private static class addSSHForkJobSubmissionDetails_argsTupleSchemeFactory implements SchemeFactory {
      public addSSHForkJobSubmissionDetails_argsTupleScheme getScheme() {
        return new addSSHForkJobSubmissionDetails_argsTupleScheme();
      }
    }

    private static class addSSHForkJobSubmissionDetails_argsTupleScheme extends TupleScheme<addSSHForkJobSubmissionDetails_args> {

      @Override
      public void write(org.apache.thrift.protocol.TProtocol prot, addSSHForkJobSubmissionDetails_args struct) throws org.apache.thrift.TException {
        TTupleProtocol oprot = (TTupleProtocol) prot;
        struct.authzToken.write(oprot);
        oprot.writeString(struct.computeResourceId);
        oprot.writeI32(struct.priorityOrder);
        struct.sshJobSubmission.write(oprot);
      }

      @Override
      public void read(org.apache.thrift.protocol.TProtocol prot, addSSHForkJobSubmissionDetails_args struct) throws org.apache.thrift.TException {
        TTupleProtocol iprot = (TTupleProtocol) prot;
        struct.authzToken = new org.apache.airavata.model.security.AuthzToken();
        struct.authzToken.read(iprot);
        struct.setAuthzTokenIsSet(true);
        struct.computeResourceId = iprot.readString();
        struct.setComputeResourceIdIsSet(true);
        struct.priorityOrder = iprot.readI32();
        struct.setPriorityOrderIsSet(true);
        struct.sshJobSubmission = new org.apache.airavata.model.appcatalog.computeresource.SSHJobSubmission();
        struct.sshJobSubmission.read(iprot);
        struct.setSshJobSubmissionIsSet(true);
      }
    }

  }

  public static class addSSHForkJobSubmissionDetails_result implements org.apache.thrift.TBase<addSSHForkJobSubmissionDetails_result, addSSHForkJobSubmissionDetails_result._Fields>, java.io.Serializable, Cloneable, Comparable<addSSHForkJobSubmissionDetails_result>   {
    private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("addSSHForkJobSubmissionDetails_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 IRE_FIELD_DESC = new org.apache.thrift.protocol.TField("ire", org.apache.thrift.protocol.TType.STRUCT, (short)1);
    private static final org.apache.thrift.protocol.TField ACE_FIELD_DESC = new org.apache.thrift.protocol.TField("ace", org.apache.thrift.protocol.TType.STRUCT, (short)2);
    private static final org.apache.thrift.protocol.TField ASE_FIELD_DESC = new org.apache.thrift.protocol.TField("ase", org.apache.thrift.protocol.TType.STRUCT, (short)3);
    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)4);

    private static final Map<Class<? extends IScheme>, SchemeFactory> schemes = new HashMap<Class<? extends IScheme>, SchemeFactory>();
    static {
      schemes.put(StandardScheme.class, new addSSHForkJobSubmissionDetails_resultStandardSchemeFactory());
      schemes.put(TupleScheme.class, new addSSHForkJobSubmissionDetails_resultTupleSchemeFactory());
    }

    public String success; // required
    public org.apache.airavata.model.error.InvalidRequestException ire; // required
    public org.apache.airavata.model.error.AiravataClientException ace; // required
    public org.apache.airavata.model.error.AiravataSystemException ase; // 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"),
      IRE((short)1, "ire"),
      ACE((short)2, "ace"),
      ASE((short)3, "ase"),
      AE((short)4, "ae");

      private static final Map<String, _Fields> byName = new HashMap<String, _Fields>();

      static {
        for (_Fields field : EnumSet.allOf(_Fields.class)) {
          byName.put(field.getFieldName(), field);
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, or null if its not found.
       */
      public static _Fields findByThriftId(int fieldId) {
        switch(fieldId) {
          case 0: // SUCCESS
            return SUCCESS;
          case 1: // IRE
            return IRE;
          case 2: // ACE
            return ACE;
          case 3: // ASE
            return ASE;
          case 4: // 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 IllegalArgumentException("Field " + fieldId + " doesn't exist!");
        return fields;
      }

      /**
       * Find the _Fields constant that matches name, or null if its not found.
       */
      public static _Fields findByName(String name) {
        return byName.get(name);
      }

      private final short _thriftId;
      private final String _fieldName;

      _Fields(short thriftId, String fieldName) {
        _thriftId = thriftId;
        _fieldName = fieldName;
      }

      public short getThriftFieldId() {
        return _thriftId;
      }

      public String getFieldName() {
        return _fieldName;
      }
    }

    // isset id assignments
    public static final Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
    static {
      Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new EnumMap<_Fields, org.apache.thrift.meta_data.FieldMetaData>(_Fields.class);
      tmpMap.put(_Fields.SUCCESS, new org.apache.thrift.meta_data.FieldMetaData("success", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING)));
      tmpMap.put(_Fields.IRE, new org.apache.thrift.meta_data.FieldMetaData("ire", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRUCT)));
      tmpMap.put(_Fields.ACE, new org.apache.thrift.meta_data.FieldMetaData("ace", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRUCT)));
      tmpMap.put(_Fields.ASE, new org.apache.thrift.meta_data.FieldMetaData("ase", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRUCT)));
      tmpMap.put(_Fields.AE, new org.apache.thrift.meta_data.FieldMetaData("ae", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRUCT)));
      metaDataMap = Collections.unmodifiableMap(tmpMap);
      org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(addSSHForkJobSubmissionDetails_result.class, metaDataMap);
    }

    public addSSHForkJobSubmissionDetails_result() {
    }

    public addSSHForkJobSubmissionDetails_result(
      String success,
      org.apache.airavata.model.error.InvalidRequestException ire,
      org.apache.airavata.model.error.AiravataClientException ace,
      org.apache.airavata.model.error.AiravataSystemException ase,
      org.apache.airavata.model.error.AuthorizationException ae)
    {
      this();
      this.success = success;
      this.ire = ire;
      this.ace = ace;
      this.ase = ase;
      this.ae = ae;
    }

    /**
     * Performs a deep copy on <i>other</i>.
     */
    public addSSHForkJobSubmissionDetails_result(addSSHForkJobSubmissionDetails_result other) {
      if (other.isSetSuccess()) {
        this.success = other.success;
      }
      if (other.isSetIre()) {
        this.ire = new org.apache.airavata.model.error.InvalidRequestException(other.ire);
      }
      if (other.isSetAce()) {
        this.ace = new org.apache.airavata.model.error.AiravataClientException(other.ace);
      }
      if (other.isSetAse()) {
        this.ase = new org.apache.airavata.model.error.AiravataSystemException(other.ase);
      }
      if (other.isSetAe()) {
        this.ae = new org.apache.airavata.model.error.AuthorizationException(other.ae);
      }
    }

    public addSSHForkJobSubmissionDetails_result deepCopy() {
      return new addSSHForkJobSubmissionDetails_result(this);
    }

    @Override
    public void clear() {
      this.success = null;
      this.ire = null;
      this.ace = null;
      this.ase = null;
      this.ae = null;
    }

    public String getSuccess() {
      return this.success;
    }

    public addSSHForkJobSubmissionDetails_result setSuccess(String success) {
      this.success = success;
      return this;
    }

    public void unsetSuccess() {
      this.success = null;
    }

    /** Returns true if field success is set (has been assigned a value) and false otherwise */
    public boolean isSetSuccess() {
      return this.success != null;
    }

    public void setSuccessIsSet(boolean value) {
      if (!value) {
        this.success = null;
      }
    }

    public org.apache.airavata.model.error.InvalidRequestException getIre() {
      return this.ire;
    }

    public addSSHForkJobSubmissionDetails_result setIre(org.apache.airavata.model.error.InvalidRequestException ire) {
      this.ire = ire;
      return this;
    }

    public void unsetIre() {
      this.ire = null;
    }

    /** Returns true if field ire is set (has been assigned a value) and false otherwise */
    public boolean isSetIre() {
      return this.ire != null;
    }

    public void setIreIsSet(boolean value) {
      if (!value) {
        this.ire = null;
      }
    }

    public org.apache.airavata.model.error.AiravataClientException getAce() {
      return this.ace;
    }

    public addSSHForkJobSubmissionDetails_result setAce(org.apache.airavata.model.error.AiravataClientException ace) {
      this.ace = ace;
      return this;
    }

    public void unsetAce() {
      this.ace = null;
    }

    /** Returns true if field ace is set (has been assigned a value) and false otherwise */
    public boolean isSetAce() {
      return this.ace != null;
    }

    public void setAceIsSet(boolean value) {
      if (!value) {
        this.ace = null;
      }
    }

    public org.apache.airavata.model.error.AiravataSystemException getAse() {
      return this.ase;
    }

    public addSSHForkJobSubmissionDetails_result setAse(org.apache.airavata.model.error.AiravataSystemException ase) {
      this.ase = ase;
      return this;
    }

    public void unsetAse() {
      this.ase = null;
    }

    /** Returns true if field ase is set (has been assigned a value) and false otherwise */
    public boolean isSetAse() {
      return this.ase != null;
    }

    public void setAseIsSet(boolean value) {
      if (!value) {
        this.ase = null;
      }
    }

    public org.apache.airavata.model.error.AuthorizationException getAe() {
      return this.ae;
    }

    public addSSHForkJobSubmissionDetails_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, Object value) {
      switch (field) {
      case SUCCESS:
        if (value == null) {
          unsetSuccess();
        } else {
          setSuccess((String)value);
        }
        break;

      case IRE:
        if (value == null) {
          unsetIre();
        } else {
          setIre((org.apache.airavata.model.error.InvalidRequestException)value);
        }
        break;

      case ACE:
        if (value == null) {
          unsetAce();
        } else {
          setAce((org.apache.airavata.model.error.AiravataClientException)value);
        }
        break;

      case ASE:
        if (value == null) {
          unsetAse();
        } else {
          setAse((org.apache.airavata.model.error.AiravataSystemException)value);
        }
        break;

      case AE:
        if (value == null) {
          unsetAe();
        } else {
          setAe((org.apache.airavata.model.error.AuthorizationException)value);
        }
        break;

      }
    }

    public Object getFieldValue(_Fields field) {
      switch (field) {
      case SUCCESS:
        return getSuccess();

      case IRE:
        return getIre();

      case ACE:
        return getAce();

      case ASE:
        return getAse();

      case AE:
        return getAe();

      }
      throw new IllegalStateException();
    }

    /** Returns true if field corresponding to fieldID is set (has been assigned a value) and false otherwise */
    public boolean isSet(_Fields field) {
      if (field == null) {
        throw new IllegalArgumentException();
      }

      switch (field) {
      case SUCCESS:
        return isSetSuccess();
      case IRE:
        return isSetIre();
      case ACE:
        return isSetAce();
      case ASE:
        return isSetAse();
      case AE:
        return isSetAe();
      }
      throw new IllegalStateException();
    }

    @Override
    public boolean equals(Object that) {
      if (that == null)
        return false;
      if (that instanceof addSSHForkJobSubmissionDetails_result)
        return this.equals((addSSHForkJobSubmissionDetails_result)that);
      return false;
    }

    public boolean equals(addSSHForkJobSubmissionDetails_result that) {
      if (that == null)
        return false;

      boolean this_present_success = true && this.isSetSuccess();
      boolean that_present_success = true && that.isSetSuccess();
      if (this_present_success || that_present_success) {
        if (!(this_present_success && that_present_success))
          return false;
        if (!this.success.equals(that.success))
          return false;
      }

      boolean this_present_ire = true && this.isSetIre();
      boolean that_present_ire = true && that.isSetIre();
      if (this_present_ire || that_present_ire) {
        if (!(this_present_ire && that_present_ire))
          return false;
        if (!this.ire.equals(that.ire))
          return false;
      }

      boolean this_present_ace = true && this.isSetAce();
      boolean that_present_ace = true && that.isSetAce();
      if (this_present_ace || that_present_ace) {
        if (!(this_present_ace && that_present_ace))
          return false;
        if (!this.ace.equals(that.ace))
          return false;
      }

      boolean this_present_ase = true && this.isSetAse();
      boolean that_present_ase = true && that.isSetAse();
      if (this_present_ase || that_present_ase) {
        if (!(this_present_ase && that_present_ase))
          return false;
        if (!this.ase.equals(that.ase))
          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() {
      List<Object> list = new ArrayList<Object>();

      boolean present_success = true && (isSetSuccess());
      list.add(present_success);
      if (present_success)
        list.add(success);

      boolean present_ire = true && (isSetIre());
      list.add(present_ire);
      if (present_ire)
        list.add(ire);

      boolean present_ace = true && (isSetAce());
      list.add(present_ace);
      if (present_ace)
        list.add(ace);

      boolean present_ase = true && (isSetAse());
      list.add(present_ase);
      if (present_ase)
        list.add(ase);

      boolean present_ae = true && (isSetAe());
      list.add(present_ae);
      if (present_ae)
        list.add(ae);

      return list.hashCode();
    }

    @Override
    public int compareTo(addSSHForkJobSubmissionDetails_result other) {
      if (!getClass().equals(other.getClass())) {
        return getClass().getName().compareTo(other.getClass().getName());
      }

      int lastComparison = 0;

      lastComparison = Boolean.valueOf(isSetSuccess()).compareTo(other.isSetSuccess());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetSuccess()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.success, other.success);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = Boolean.valueOf(isSetIre()).compareTo(other.isSetIre());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetIre()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.ire, other.ire);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = Boolean.valueOf(isSetAce()).compareTo(other.isSetAce());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetAce()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.ace, other.ace);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = Boolean.valueOf(isSetAse()).compareTo(other.isSetAse());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetAse()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.ase, other.ase);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = 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 {
      schemes.get(iprot.getScheme()).getScheme().read(iprot, this);
    }

    public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException {
      schemes.get(oprot.getScheme()).getScheme().write(oprot, this);
      }

    @Override
    public String toString() {
      StringBuilder sb = new StringBuilder("addSSHForkJobSubmissionDetails_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("ire:");
      if (this.ire == null) {
        sb.append("null");
      } else {
        sb.append(this.ire);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("ace:");
      if (this.ace == null) {
        sb.append("null");
      } else {
        sb.append(this.ace);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("ase:");
      if (this.ase == null) {
        sb.append("null");
      } else {
        sb.append(this.ase);
      }
      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, 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 addSSHForkJobSubmissionDetails_resultStandardSchemeFactory implements SchemeFactory {
      public addSSHForkJobSubmissionDetails_resultStandardScheme getScheme() {
        return new addSSHForkJobSubmissionDetails_resultStandardScheme();
      }
    }

    private static class addSSHForkJobSubmissionDetails_resultStandardScheme extends StandardScheme<addSSHForkJobSubmissionDetails_result> {

      public void read(org.apache.thrift.protocol.TProtocol iprot, addSSHForkJobSubmissionDetails_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: // IRE
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.ire = new org.apache.airavata.model.error.InvalidRequestException();
                struct.ire.read(iprot);
                struct.setIreIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 2: // ACE
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.ace = new org.apache.airavata.model.error.AiravataClientException();
                struct.ace.read(iprot);
                struct.setAceIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 3: // ASE
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.ase = new org.apache.airavata.model.error.AiravataSystemException();
                struct.ase.read(iprot);
                struct.setAseIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 4: // 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, addSSHForkJobSubmissionDetails_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.ire != null) {
          oprot.writeFieldBegin(IRE_FIELD_DESC);
          struct.ire.write(oprot);
          oprot.writeFieldEnd();
        }
        if (struct.ace != null) {
          oprot.writeFieldBegin(ACE_FIELD_DESC);
          struct.ace.write(oprot);
          oprot.writeFieldEnd();
        }
        if (struct.ase != null) {
          oprot.writeFieldBegin(ASE_FIELD_DESC);
          struct.ase.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 addSSHForkJobSubmissionDetails_resultTupleSchemeFactory implements SchemeFactory {
      public addSSHForkJobSubmissionDetails_resultTupleScheme getScheme() {
        return new addSSHForkJobSubmissionDetails_resultTupleScheme();
      }
    }

    private static class addSSHForkJobSubmissionDetails_resultTupleScheme extends TupleScheme<addSSHForkJobSubmissionDetails_result> {

      @Override
      public void write(org.apache.thrift.protocol.TProtocol prot, addSSHForkJobSubmissionDetails_result struct) throws org.apache.thrift.TException {
        TTupleProtocol oprot = (TTupleProtocol) prot;
        BitSet optionals = new BitSet();
        if (struct.isSetSuccess()) {
          optionals.set(0);
        }
        if (struct.isSetIre()) {
          optionals.set(1);
        }
        if (struct.isSetAce()) {
          optionals.set(2);
        }
        if (struct.isSetAse()) {
          optionals.set(3);
        }
        if (struct.isSetAe()) {
          optionals.set(4);
        }
        oprot.writeBitSet(optionals, 5);
        if (struct.isSetSuccess()) {
          oprot.writeString(struct.success);
        }
        if (struct.isSetIre()) {
          struct.ire.write(oprot);
        }
        if (struct.isSetAce()) {
          struct.ace.write(oprot);
        }
        if (struct.isSetAse()) {
          struct.ase.write(oprot);
        }
        if (struct.isSetAe()) {
          struct.ae.write(oprot);
        }
      }

      @Override
      public void read(org.apache.thrift.protocol.TProtocol prot, addSSHForkJobSubmissionDetails_result struct) throws org.apache.thrift.TException {
        TTupleProtocol iprot = (TTupleProtocol) prot;
        BitSet incoming = iprot.readBitSet(5);
        if (incoming.get(0)) {
          struct.success = iprot.readString();
          struct.setSuccessIsSet(true);
        }
        if (incoming.get(1)) {
          struct.ire = new org.apache.airavata.model.error.InvalidRequestException();
          struct.ire.read(iprot);
          struct.setIreIsSet(true);
        }
        if (incoming.get(2)) {
          struct.ace = new org.apache.airavata.model.error.AiravataClientException();
          struct.ace.read(iprot);
          struct.setAceIsSet(true);
        }
        if (incoming.get(3)) {
          struct.ase = new org.apache.airavata.model.error.AiravataSystemException();
          struct.ase.read(iprot);
          struct.setAseIsSet(true);
        }
        if (incoming.get(4)) {
          struct.ae = new org.apache.airavata.model.error.AuthorizationException();
          struct.ae.read(iprot);
          struct.setAeIsSet(true);
        }
      }
    }

  }

  public static class getSSHJobSubmission_args implements org.apache.thrift.TBase<getSSHJobSubmission_args, getSSHJobSubmission_args._Fields>, java.io.Serializable, Cloneable, Comparable<getSSHJobSubmission_args>   {
    private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("getSSHJobSubmission_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 JOB_SUBMISSION_ID_FIELD_DESC = new org.apache.thrift.protocol.TField("jobSubmissionId", org.apache.thrift.protocol.TType.STRING, (short)2);

    private static final Map<Class<? extends IScheme>, SchemeFactory> schemes = new HashMap<Class<? extends IScheme>, SchemeFactory>();
    static {
      schemes.put(StandardScheme.class, new getSSHJobSubmission_argsStandardSchemeFactory());
      schemes.put(TupleScheme.class, new getSSHJobSubmission_argsTupleSchemeFactory());
    }

    public org.apache.airavata.model.security.AuthzToken authzToken; // required
    public String jobSubmissionId; // required

    /** 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"),
      JOB_SUBMISSION_ID((short)2, "jobSubmissionId");

      private static final Map<String, _Fields> byName = new HashMap<String, _Fields>();

      static {
        for (_Fields field : EnumSet.allOf(_Fields.class)) {
          byName.put(field.getFieldName(), field);
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, or null if its not found.
       */
      public static _Fields findByThriftId(int fieldId) {
        switch(fieldId) {
          case 1: // AUTHZ_TOKEN
            return AUTHZ_TOKEN;
          case 2: // JOB_SUBMISSION_ID
            return JOB_SUBMISSION_ID;
          default:
            return null;
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, throwing an exception
       * if it is not found.
       */
      public static _Fields findByThriftIdOrThrow(int fieldId) {
        _Fields fields = findByThriftId(fieldId);
        if (fields == null) throw new IllegalArgumentException("Field " + fieldId + " doesn't exist!");
        return fields;
      }

      /**
       * Find the _Fields constant that matches name, or null if its not found.
       */
      public static _Fields findByName(String name) {
        return byName.get(name);
      }

      private final short _thriftId;
      private final String _fieldName;

      _Fields(short thriftId, String fieldName) {
        _thriftId = thriftId;
        _fieldName = fieldName;
      }

      public short getThriftFieldId() {
        return _thriftId;
      }

      public String getFieldName() {
        return _fieldName;
      }
    }

    // isset id assignments
    public static final Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
    static {
      Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new EnumMap<_Fields, org.apache.thrift.meta_data.FieldMetaData>(_Fields.class);
      tmpMap.put(_Fields.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.JOB_SUBMISSION_ID, new org.apache.thrift.meta_data.FieldMetaData("jobSubmissionId", org.apache.thrift.TFieldRequirementType.REQUIRED, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING)));
      metaDataMap = Collections.unmodifiableMap(tmpMap);
      org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(getSSHJobSubmission_args.class, metaDataMap);
    }

    public getSSHJobSubmission_args() {
    }

    public getSSHJobSubmission_args(
      org.apache.airavata.model.security.AuthzToken authzToken,
      String jobSubmissionId)
    {
      this();
      this.authzToken = authzToken;
      this.jobSubmissionId = jobSubmissionId;
    }

    /**
     * Performs a deep copy on <i>other</i>.
     */
    public getSSHJobSubmission_args(getSSHJobSubmission_args other) {
      if (other.isSetAuthzToken()) {
        this.authzToken = new org.apache.airavata.model.security.AuthzToken(other.authzToken);
      }
      if (other.isSetJobSubmissionId()) {
        this.jobSubmissionId = other.jobSubmissionId;
      }
    }

    public getSSHJobSubmission_args deepCopy() {
      return new getSSHJobSubmission_args(this);
    }

    @Override
    public void clear() {
      this.authzToken = null;
      this.jobSubmissionId = null;
    }

    public org.apache.airavata.model.security.AuthzToken getAuthzToken() {
      return this.authzToken;
    }

    public getSSHJobSubmission_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 String getJobSubmissionId() {
      return this.jobSubmissionId;
    }

    public getSSHJobSubmission_args setJobSubmissionId(String jobSubmissionId) {
      this.jobSubmissionId = jobSubmissionId;
      return this;
    }

    public void unsetJobSubmissionId() {
      this.jobSubmissionId = null;
    }

    /** Returns true if field jobSubmissionId is set (has been assigned a value) and false otherwise */
    public boolean isSetJobSubmissionId() {
      return this.jobSubmissionId != null;
    }

    public void setJobSubmissionIdIsSet(boolean value) {
      if (!value) {
        this.jobSubmissionId = null;
      }
    }

    public void setFieldValue(_Fields field, Object value) {
      switch (field) {
      case AUTHZ_TOKEN:
        if (value == null) {
          unsetAuthzToken();
        } else {
          setAuthzToken((org.apache.airavata.model.security.AuthzToken)value);
        }
        break;

      case JOB_SUBMISSION_ID:
        if (value == null) {
          unsetJobSubmissionId();
        } else {
          setJobSubmissionId((String)value);
        }
        break;

      }
    }

    public Object getFieldValue(_Fields field) {
      switch (field) {
      case AUTHZ_TOKEN:
        return getAuthzToken();

      case JOB_SUBMISSION_ID:
        return getJobSubmissionId();

      }
      throw new IllegalStateException();
    }

    /** Returns true if field corresponding to fieldID is set (has been assigned a value) and false otherwise */
    public boolean isSet(_Fields field) {
      if (field == null) {
        throw new IllegalArgumentException();
      }

      switch (field) {
      case AUTHZ_TOKEN:
        return isSetAuthzToken();
      case JOB_SUBMISSION_ID:
        return isSetJobSubmissionId();
      }
      throw new IllegalStateException();
    }

    @Override
    public boolean equals(Object that) {
      if (that == null)
        return false;
      if (that instanceof getSSHJobSubmission_args)
        return this.equals((getSSHJobSubmission_args)that);
      return false;
    }

    public boolean equals(getSSHJobSubmission_args that) {
      if (that == null)
        return false;

      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_jobSubmissionId = true && this.isSetJobSubmissionId();
      boolean that_present_jobSubmissionId = true && that.isSetJobSubmissionId();
      if (this_present_jobSubmissionId || that_present_jobSubmissionId) {
        if (!(this_present_jobSubmissionId && that_present_jobSubmissionId))
          return false;
        if (!this.jobSubmissionId.equals(that.jobSubmissionId))
          return false;
      }

      return true;
    }

    @Override
    public int hashCode() {
      List<Object> list = new ArrayList<Object>();

      boolean present_authzToken = true && (isSetAuthzToken());
      list.add(present_authzToken);
      if (present_authzToken)
        list.add(authzToken);

      boolean present_jobSubmissionId = true && (isSetJobSubmissionId());
      list.add(present_jobSubmissionId);
      if (present_jobSubmissionId)
        list.add(jobSubmissionId);

      return list.hashCode();
    }

    @Override
    public int compareTo(getSSHJobSubmission_args other) {
      if (!getClass().equals(other.getClass())) {
        return getClass().getName().compareTo(other.getClass().getName());
      }

      int lastComparison = 0;

      lastComparison = 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 = Boolean.valueOf(isSetJobSubmissionId()).compareTo(other.isSetJobSubmissionId());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetJobSubmissionId()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.jobSubmissionId, other.jobSubmissionId);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      return 0;
    }

    public _Fields fieldForId(int fieldId) {
      return _Fields.findByThriftId(fieldId);
    }

    public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
      schemes.get(iprot.getScheme()).getScheme().read(iprot, this);
    }

    public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException {
      schemes.get(oprot.getScheme()).getScheme().write(oprot, this);
    }

    @Override
    public String toString() {
      StringBuilder sb = new StringBuilder("getSSHJobSubmission_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("jobSubmissionId:");
      if (this.jobSubmissionId == null) {
        sb.append("null");
      } else {
        sb.append(this.jobSubmissionId);
      }
      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 (jobSubmissionId == null) {
        throw new org.apache.thrift.protocol.TProtocolException("Required field 'jobSubmissionId' 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, 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 getSSHJobSubmission_argsStandardSchemeFactory implements SchemeFactory {
      public getSSHJobSubmission_argsStandardScheme getScheme() {
        return new getSSHJobSubmission_argsStandardScheme();
      }
    }

    private static class getSSHJobSubmission_argsStandardScheme extends StandardScheme<getSSHJobSubmission_args> {

      public void read(org.apache.thrift.protocol.TProtocol iprot, getSSHJobSubmission_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: // JOB_SUBMISSION_ID
              if (schemeField.type == org.apache.thrift.protocol.TType.STRING) {
                struct.jobSubmissionId = iprot.readString();
                struct.setJobSubmissionIdIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            default:
              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
          }
          iprot.readFieldEnd();
        }
        iprot.readStructEnd();

        // check for required fields of primitive type, which can't be checked in the validate method
        struct.validate();
      }

      public void write(org.apache.thrift.protocol.TProtocol oprot, getSSHJobSubmission_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.jobSubmissionId != null) {
          oprot.writeFieldBegin(JOB_SUBMISSION_ID_FIELD_DESC);
          oprot.writeString(struct.jobSubmissionId);
          oprot.writeFieldEnd();
        }
        oprot.writeFieldStop();
        oprot.writeStructEnd();
      }

    }

    private static class getSSHJobSubmission_argsTupleSchemeFactory implements SchemeFactory {
      public getSSHJobSubmission_argsTupleScheme getScheme() {
        return new getSSHJobSubmission_argsTupleScheme();
      }
    }

    private static class getSSHJobSubmission_argsTupleScheme extends TupleScheme<getSSHJobSubmission_args> {

      @Override
      public void write(org.apache.thrift.protocol.TProtocol prot, getSSHJobSubmission_args struct) throws org.apache.thrift.TException {
        TTupleProtocol oprot = (TTupleProtocol) prot;
        struct.authzToken.write(oprot);
        oprot.writeString(struct.jobSubmissionId);
      }

      @Override
      public void read(org.apache.thrift.protocol.TProtocol prot, getSSHJobSubmission_args struct) throws org.apache.thrift.TException {
        TTupleProtocol iprot = (TTupleProtocol) prot;
        struct.authzToken = new org.apache.airavata.model.security.AuthzToken();
        struct.authzToken.read(iprot);
        struct.setAuthzTokenIsSet(true);
        struct.jobSubmissionId = iprot.readString();
        struct.setJobSubmissionIdIsSet(true);
      }
    }

  }

  public static class getSSHJobSubmission_result implements org.apache.thrift.TBase<getSSHJobSubmission_result, getSSHJobSubmission_result._Fields>, java.io.Serializable, Cloneable, Comparable<getSSHJobSubmission_result>   {
    private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("getSSHJobSubmission_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 IRE_FIELD_DESC = new org.apache.thrift.protocol.TField("ire", org.apache.thrift.protocol.TType.STRUCT, (short)1);
    private static final org.apache.thrift.protocol.TField ACE_FIELD_DESC = new org.apache.thrift.protocol.TField("ace", org.apache.thrift.protocol.TType.STRUCT, (short)2);
    private static final org.apache.thrift.protocol.TField ASE_FIELD_DESC = new org.apache.thrift.protocol.TField("ase", org.apache.thrift.protocol.TType.STRUCT, (short)3);
    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)4);

    private static final Map<Class<? extends IScheme>, SchemeFactory> schemes = new HashMap<Class<? extends IScheme>, SchemeFactory>();
    static {
      schemes.put(StandardScheme.class, new getSSHJobSubmission_resultStandardSchemeFactory());
      schemes.put(TupleScheme.class, new getSSHJobSubmission_resultTupleSchemeFactory());
    }

    public org.apache.airavata.model.appcatalog.computeresource.SSHJobSubmission success; // required
    public org.apache.airavata.model.error.InvalidRequestException ire; // required
    public org.apache.airavata.model.error.AiravataClientException ace; // required
    public org.apache.airavata.model.error.AiravataSystemException ase; // 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"),
      IRE((short)1, "ire"),
      ACE((short)2, "ace"),
      ASE((short)3, "ase"),
      AE((short)4, "ae");

      private static final Map<String, _Fields> byName = new HashMap<String, _Fields>();

      static {
        for (_Fields field : EnumSet.allOf(_Fields.class)) {
          byName.put(field.getFieldName(), field);
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, or null if its not found.
       */
      public static _Fields findByThriftId(int fieldId) {
        switch(fieldId) {
          case 0: // SUCCESS
            return SUCCESS;
          case 1: // IRE
            return IRE;
          case 2: // ACE
            return ACE;
          case 3: // ASE
            return ASE;
          case 4: // 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 IllegalArgumentException("Field " + fieldId + " doesn't exist!");
        return fields;
      }

      /**
       * Find the _Fields constant that matches name, or null if its not found.
       */
      public static _Fields findByName(String name) {
        return byName.get(name);
      }

      private final short _thriftId;
      private final String _fieldName;

      _Fields(short thriftId, String fieldName) {
        _thriftId = thriftId;
        _fieldName = fieldName;
      }

      public short getThriftFieldId() {
        return _thriftId;
      }

      public String getFieldName() {
        return _fieldName;
      }
    }

    // isset id assignments
    public static final Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
    static {
      Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new EnumMap<_Fields, org.apache.thrift.meta_data.FieldMetaData>(_Fields.class);
      tmpMap.put(_Fields.SUCCESS, new org.apache.thrift.meta_data.FieldMetaData("success", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.StructMetaData(org.apache.thrift.protocol.TType.STRUCT, org.apache.airavata.model.appcatalog.computeresource.SSHJobSubmission.class)));
      tmpMap.put(_Fields.IRE, new org.apache.thrift.meta_data.FieldMetaData("ire", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRUCT)));
      tmpMap.put(_Fields.ACE, new org.apache.thrift.meta_data.FieldMetaData("ace", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRUCT)));
      tmpMap.put(_Fields.ASE, new org.apache.thrift.meta_data.FieldMetaData("ase", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRUCT)));
      tmpMap.put(_Fields.AE, new org.apache.thrift.meta_data.FieldMetaData("ae", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRUCT)));
      metaDataMap = Collections.unmodifiableMap(tmpMap);
      org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(getSSHJobSubmission_result.class, metaDataMap);
    }

    public getSSHJobSubmission_result() {
    }

    public getSSHJobSubmission_result(
      org.apache.airavata.model.appcatalog.computeresource.SSHJobSubmission success,
      org.apache.airavata.model.error.InvalidRequestException ire,
      org.apache.airavata.model.error.AiravataClientException ace,
      org.apache.airavata.model.error.AiravataSystemException ase,
      org.apache.airavata.model.error.AuthorizationException ae)
    {
      this();
      this.success = success;
      this.ire = ire;
      this.ace = ace;
      this.ase = ase;
      this.ae = ae;
    }

    /**
     * Performs a deep copy on <i>other</i>.
     */
    public getSSHJobSubmission_result(getSSHJobSubmission_result other) {
      if (other.isSetSuccess()) {
        this.success = new org.apache.airavata.model.appcatalog.computeresource.SSHJobSubmission(other.success);
      }
      if (other.isSetIre()) {
        this.ire = new org.apache.airavata.model.error.InvalidRequestException(other.ire);
      }
      if (other.isSetAce()) {
        this.ace = new org.apache.airavata.model.error.AiravataClientException(other.ace);
      }
      if (other.isSetAse()) {
        this.ase = new org.apache.airavata.model.error.AiravataSystemException(other.ase);
      }
      if (other.isSetAe()) {
        this.ae = new org.apache.airavata.model.error.AuthorizationException(other.ae);
      }
    }

    public getSSHJobSubmission_result deepCopy() {
      return new getSSHJobSubmission_result(this);
    }

    @Override
    public void clear() {
      this.success = null;
      this.ire = null;
      this.ace = null;
      this.ase = null;
      this.ae = null;
    }

    public org.apache.airavata.model.appcatalog.computeresource.SSHJobSubmission getSuccess() {
      return this.success;
    }

    public getSSHJobSubmission_result setSuccess(org.apache.airavata.model.appcatalog.computeresource.SSHJobSubmission 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.model.error.InvalidRequestException getIre() {
      return this.ire;
    }

    public getSSHJobSubmission_result setIre(org.apache.airavata.model.error.InvalidRequestException ire) {
      this.ire = ire;
      return this;
    }

    public void unsetIre() {
      this.ire = null;
    }

    /** Returns true if field ire is set (has been assigned a value) and false otherwise */
    public boolean isSetIre() {
      return this.ire != null;
    }

    public void setIreIsSet(boolean value) {
      if (!value) {
        this.ire = null;
      }
    }

    public org.apache.airavata.model.error.AiravataClientException getAce() {
      return this.ace;
    }

    public getSSHJobSubmission_result setAce(org.apache.airavata.model.error.AiravataClientException ace) {
      this.ace = ace;
      return this;
    }

    public void unsetAce() {
      this.ace = null;
    }

    /** Returns true if field ace is set (has been assigned a value) and false otherwise */
    public boolean isSetAce() {
      return this.ace != null;
    }

    public void setAceIsSet(boolean value) {
      if (!value) {
        this.ace = null;
      }
    }

    public org.apache.airavata.model.error.AiravataSystemException getAse() {
      return this.ase;
    }

    public getSSHJobSubmission_result setAse(org.apache.airavata.model.error.AiravataSystemException ase) {
      this.ase = ase;
      return this;
    }

    public void unsetAse() {
      this.ase = null;
    }

    /** Returns true if field ase is set (has been assigned a value) and false otherwise */
    public boolean isSetAse() {
      return this.ase != null;
    }

    public void setAseIsSet(boolean value) {
      if (!value) {
        this.ase = null;
      }
    }

    public org.apache.airavata.model.error.AuthorizationException getAe() {
      return this.ae;
    }

    public getSSHJobSubmission_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, Object value) {
      switch (field) {
      case SUCCESS:
        if (value == null) {
          unsetSuccess();
        } else {
          setSuccess((org.apache.airavata.model.appcatalog.computeresource.SSHJobSubmission)value);
        }
        break;

      case IRE:
        if (value == null) {
          unsetIre();
        } else {
          setIre((org.apache.airavata.model.error.InvalidRequestException)value);
        }
        break;

      case ACE:
        if (value == null) {
          unsetAce();
        } else {
          setAce((org.apache.airavata.model.error.AiravataClientException)value);
        }
        break;

      case ASE:
        if (value == null) {
          unsetAse();
        } else {
          setAse((org.apache.airavata.model.error.AiravataSystemException)value);
        }
        break;

      case AE:
        if (value == null) {
          unsetAe();
        } else {
          setAe((org.apache.airavata.model.error.AuthorizationException)value);
        }
        break;

      }
    }

    public Object getFieldValue(_Fields field) {
      switch (field) {
      case SUCCESS:
        return getSuccess();

      case IRE:
        return getIre();

      case ACE:
        return getAce();

      case ASE:
        return getAse();

      case AE:
        return getAe();

      }
      throw new IllegalStateException();
    }

    /** Returns true if field corresponding to fieldID is set (has been assigned a value) and false otherwise */
    public boolean isSet(_Fields field) {
      if (field == null) {
        throw new IllegalArgumentException();
      }

      switch (field) {
      case SUCCESS:
        return isSetSuccess();
      case IRE:
        return isSetIre();
      case ACE:
        return isSetAce();
      case ASE:
        return isSetAse();
      case AE:
        return isSetAe();
      }
      throw new IllegalStateException();
    }

    @Override
    public boolean equals(Object that) {
      if (that == null)
        return false;
      if (that instanceof getSSHJobSubmission_result)
        return this.equals((getSSHJobSubmission_result)that);
      return false;
    }

    public boolean equals(getSSHJobSubmission_result that) {
      if (that == null)
        return false;

      boolean this_present_success = true && this.isSetSuccess();
      boolean that_present_success = true && that.isSetSuccess();
      if (this_present_success || that_present_success) {
        if (!(this_present_success && that_present_success))
          return false;
        if (!this.success.equals(that.success))
          return false;
      }

      boolean this_present_ire = true && this.isSetIre();
      boolean that_present_ire = true && that.isSetIre();
      if (this_present_ire || that_present_ire) {
        if (!(this_present_ire && that_present_ire))
          return false;
        if (!this.ire.equals(that.ire))
          return false;
      }

      boolean this_present_ace = true && this.isSetAce();
      boolean that_present_ace = true && that.isSetAce();
      if (this_present_ace || that_present_ace) {
        if (!(this_present_ace && that_present_ace))
          return false;
        if (!this.ace.equals(that.ace))
          return false;
      }

      boolean this_present_ase = true && this.isSetAse();
      boolean that_present_ase = true && that.isSetAse();
      if (this_present_ase || that_present_ase) {
        if (!(this_present_ase && that_present_ase))
          return false;
        if (!this.ase.equals(that.ase))
          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() {
      List<Object> list = new ArrayList<Object>();

      boolean present_success = true && (isSetSuccess());
      list.add(present_success);
      if (present_success)
        list.add(success);

      boolean present_ire = true && (isSetIre());
      list.add(present_ire);
      if (present_ire)
        list.add(ire);

      boolean present_ace = true && (isSetAce());
      list.add(present_ace);
      if (present_ace)
        list.add(ace);

      boolean present_ase = true && (isSetAse());
      list.add(present_ase);
      if (present_ase)
        list.add(ase);

      boolean present_ae = true && (isSetAe());
      list.add(present_ae);
      if (present_ae)
        list.add(ae);

      return list.hashCode();
    }

    @Override
    public int compareTo(getSSHJobSubmission_result other) {
      if (!getClass().equals(other.getClass())) {
        return getClass().getName().compareTo(other.getClass().getName());
      }

      int lastComparison = 0;

      lastComparison = Boolean.valueOf(isSetSuccess()).compareTo(other.isSetSuccess());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetSuccess()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.success, other.success);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = Boolean.valueOf(isSetIre()).compareTo(other.isSetIre());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetIre()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.ire, other.ire);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = Boolean.valueOf(isSetAce()).compareTo(other.isSetAce());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetAce()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.ace, other.ace);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = Boolean.valueOf(isSetAse()).compareTo(other.isSetAse());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetAse()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.ase, other.ase);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = 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 {
      schemes.get(iprot.getScheme()).getScheme().read(iprot, this);
    }

    public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException {
      schemes.get(oprot.getScheme()).getScheme().write(oprot, this);
      }

    @Override
    public String toString() {
      StringBuilder sb = new StringBuilder("getSSHJobSubmission_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("ire:");
      if (this.ire == null) {
        sb.append("null");
      } else {
        sb.append(this.ire);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("ace:");
      if (this.ace == null) {
        sb.append("null");
      } else {
        sb.append(this.ace);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("ase:");
      if (this.ase == null) {
        sb.append("null");
      } else {
        sb.append(this.ase);
      }
      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, 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 getSSHJobSubmission_resultStandardSchemeFactory implements SchemeFactory {
      public getSSHJobSubmission_resultStandardScheme getScheme() {
        return new getSSHJobSubmission_resultStandardScheme();
      }
    }

    private static class getSSHJobSubmission_resultStandardScheme extends StandardScheme<getSSHJobSubmission_result> {

      public void read(org.apache.thrift.protocol.TProtocol iprot, getSSHJobSubmission_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.appcatalog.computeresource.SSHJobSubmission();
                struct.success.read(iprot);
                struct.setSuccessIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 1: // IRE
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.ire = new org.apache.airavata.model.error.InvalidRequestException();
                struct.ire.read(iprot);
                struct.setIreIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 2: // ACE
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.ace = new org.apache.airavata.model.error.AiravataClientException();
                struct.ace.read(iprot);
                struct.setAceIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 3: // ASE
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.ase = new org.apache.airavata.model.error.AiravataSystemException();
                struct.ase.read(iprot);
                struct.setAseIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 4: // 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, getSSHJobSubmission_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.ire != null) {
          oprot.writeFieldBegin(IRE_FIELD_DESC);
          struct.ire.write(oprot);
          oprot.writeFieldEnd();
        }
        if (struct.ace != null) {
          oprot.writeFieldBegin(ACE_FIELD_DESC);
          struct.ace.write(oprot);
          oprot.writeFieldEnd();
        }
        if (struct.ase != null) {
          oprot.writeFieldBegin(ASE_FIELD_DESC);
          struct.ase.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 getSSHJobSubmission_resultTupleSchemeFactory implements SchemeFactory {
      public getSSHJobSubmission_resultTupleScheme getScheme() {
        return new getSSHJobSubmission_resultTupleScheme();
      }
    }

    private static class getSSHJobSubmission_resultTupleScheme extends TupleScheme<getSSHJobSubmission_result> {

      @Override
      public void write(org.apache.thrift.protocol.TProtocol prot, getSSHJobSubmission_result struct) throws org.apache.thrift.TException {
        TTupleProtocol oprot = (TTupleProtocol) prot;
        BitSet optionals = new BitSet();
        if (struct.isSetSuccess()) {
          optionals.set(0);
        }
        if (struct.isSetIre()) {
          optionals.set(1);
        }
        if (struct.isSetAce()) {
          optionals.set(2);
        }
        if (struct.isSetAse()) {
          optionals.set(3);
        }
        if (struct.isSetAe()) {
          optionals.set(4);
        }
        oprot.writeBitSet(optionals, 5);
        if (struct.isSetSuccess()) {
          struct.success.write(oprot);
        }
        if (struct.isSetIre()) {
          struct.ire.write(oprot);
        }
        if (struct.isSetAce()) {
          struct.ace.write(oprot);
        }
        if (struct.isSetAse()) {
          struct.ase.write(oprot);
        }
        if (struct.isSetAe()) {
          struct.ae.write(oprot);
        }
      }

      @Override
      public void read(org.apache.thrift.protocol.TProtocol prot, getSSHJobSubmission_result struct) throws org.apache.thrift.TException {
        TTupleProtocol iprot = (TTupleProtocol) prot;
        BitSet incoming = iprot.readBitSet(5);
        if (incoming.get(0)) {
          struct.success = new org.apache.airavata.model.appcatalog.computeresource.SSHJobSubmission();
          struct.success.read(iprot);
          struct.setSuccessIsSet(true);
        }
        if (incoming.get(1)) {
          struct.ire = new org.apache.airavata.model.error.InvalidRequestException();
          struct.ire.read(iprot);
          struct.setIreIsSet(true);
        }
        if (incoming.get(2)) {
          struct.ace = new org.apache.airavata.model.error.AiravataClientException();
          struct.ace.read(iprot);
          struct.setAceIsSet(true);
        }
        if (incoming.get(3)) {
          struct.ase = new org.apache.airavata.model.error.AiravataSystemException();
          struct.ase.read(iprot);
          struct.setAseIsSet(true);
        }
        if (incoming.get(4)) {
          struct.ae = new org.apache.airavata.model.error.AuthorizationException();
          struct.ae.read(iprot);
          struct.setAeIsSet(true);
        }
      }
    }

  }

  public static class addUNICOREJobSubmissionDetails_args implements org.apache.thrift.TBase<addUNICOREJobSubmissionDetails_args, addUNICOREJobSubmissionDetails_args._Fields>, java.io.Serializable, Cloneable, Comparable<addUNICOREJobSubmissionDetails_args>   {
    private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("addUNICOREJobSubmissionDetails_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 COMPUTE_RESOURCE_ID_FIELD_DESC = new org.apache.thrift.protocol.TField("computeResourceId", org.apache.thrift.protocol.TType.STRING, (short)2);
    private static final org.apache.thrift.protocol.TField PRIORITY_ORDER_FIELD_DESC = new org.apache.thrift.protocol.TField("priorityOrder", org.apache.thrift.protocol.TType.I32, (short)3);
    private static final org.apache.thrift.protocol.TField UNICORE_JOB_SUBMISSION_FIELD_DESC = new org.apache.thrift.protocol.TField("unicoreJobSubmission", org.apache.thrift.protocol.TType.STRUCT, (short)4);

    private static final Map<Class<? extends IScheme>, SchemeFactory> schemes = new HashMap<Class<? extends IScheme>, SchemeFactory>();
    static {
      schemes.put(StandardScheme.class, new addUNICOREJobSubmissionDetails_argsStandardSchemeFactory());
      schemes.put(TupleScheme.class, new addUNICOREJobSubmissionDetails_argsTupleSchemeFactory());
    }

    public org.apache.airavata.model.security.AuthzToken authzToken; // required
    public String computeResourceId; // required
    public int priorityOrder; // required
    public org.apache.airavata.model.appcatalog.computeresource.UnicoreJobSubmission unicoreJobSubmission; // required

    /** 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"),
      COMPUTE_RESOURCE_ID((short)2, "computeResourceId"),
      PRIORITY_ORDER((short)3, "priorityOrder"),
      UNICORE_JOB_SUBMISSION((short)4, "unicoreJobSubmission");

      private static final Map<String, _Fields> byName = new HashMap<String, _Fields>();

      static {
        for (_Fields field : EnumSet.allOf(_Fields.class)) {
          byName.put(field.getFieldName(), field);
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, or null if its not found.
       */
      public static _Fields findByThriftId(int fieldId) {
        switch(fieldId) {
          case 1: // AUTHZ_TOKEN
            return AUTHZ_TOKEN;
          case 2: // COMPUTE_RESOURCE_ID
            return COMPUTE_RESOURCE_ID;
          case 3: // PRIORITY_ORDER
            return PRIORITY_ORDER;
          case 4: // UNICORE_JOB_SUBMISSION
            return UNICORE_JOB_SUBMISSION;
          default:
            return null;
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, throwing an exception
       * if it is not found.
       */
      public static _Fields findByThriftIdOrThrow(int fieldId) {
        _Fields fields = findByThriftId(fieldId);
        if (fields == null) throw new IllegalArgumentException("Field " + fieldId + " doesn't exist!");
        return fields;
      }

      /**
       * Find the _Fields constant that matches name, or null if its not found.
       */
      public static _Fields findByName(String name) {
        return byName.get(name);
      }

      private final short _thriftId;
      private final String _fieldName;

      _Fields(short thriftId, String fieldName) {
        _thriftId = thriftId;
        _fieldName = fieldName;
      }

      public short getThriftFieldId() {
        return _thriftId;
      }

      public String getFieldName() {
        return _fieldName;
      }
    }

    // isset id assignments
    private static final int __PRIORITYORDER_ISSET_ID = 0;
    private byte __isset_bitfield = 0;
    public static final Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
    static {
      Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new EnumMap<_Fields, org.apache.thrift.meta_data.FieldMetaData>(_Fields.class);
      tmpMap.put(_Fields.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.COMPUTE_RESOURCE_ID, new org.apache.thrift.meta_data.FieldMetaData("computeResourceId", org.apache.thrift.TFieldRequirementType.REQUIRED, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING)));
      tmpMap.put(_Fields.PRIORITY_ORDER, new org.apache.thrift.meta_data.FieldMetaData("priorityOrder", org.apache.thrift.TFieldRequirementType.REQUIRED, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.I32)));
      tmpMap.put(_Fields.UNICORE_JOB_SUBMISSION, new org.apache.thrift.meta_data.FieldMetaData("unicoreJobSubmission", org.apache.thrift.TFieldRequirementType.REQUIRED, 
          new org.apache.thrift.meta_data.StructMetaData(org.apache.thrift.protocol.TType.STRUCT, org.apache.airavata.model.appcatalog.computeresource.UnicoreJobSubmission.class)));
      metaDataMap = Collections.unmodifiableMap(tmpMap);
      org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(addUNICOREJobSubmissionDetails_args.class, metaDataMap);
    }

    public addUNICOREJobSubmissionDetails_args() {
    }

    public addUNICOREJobSubmissionDetails_args(
      org.apache.airavata.model.security.AuthzToken authzToken,
      String computeResourceId,
      int priorityOrder,
      org.apache.airavata.model.appcatalog.computeresource.UnicoreJobSubmission unicoreJobSubmission)
    {
      this();
      this.authzToken = authzToken;
      this.computeResourceId = computeResourceId;
      this.priorityOrder = priorityOrder;
      setPriorityOrderIsSet(true);
      this.unicoreJobSubmission = unicoreJobSubmission;
    }

    /**
     * Performs a deep copy on <i>other</i>.
     */
    public addUNICOREJobSubmissionDetails_args(addUNICOREJobSubmissionDetails_args other) {
      __isset_bitfield = other.__isset_bitfield;
      if (other.isSetAuthzToken()) {
        this.authzToken = new org.apache.airavata.model.security.AuthzToken(other.authzToken);
      }
      if (other.isSetComputeResourceId()) {
        this.computeResourceId = other.computeResourceId;
      }
      this.priorityOrder = other.priorityOrder;
      if (other.isSetUnicoreJobSubmission()) {
        this.unicoreJobSubmission = new org.apache.airavata.model.appcatalog.computeresource.UnicoreJobSubmission(other.unicoreJobSubmission);
      }
    }

    public addUNICOREJobSubmissionDetails_args deepCopy() {
      return new addUNICOREJobSubmissionDetails_args(this);
    }

    @Override
    public void clear() {
      this.authzToken = null;
      this.computeResourceId = null;
      setPriorityOrderIsSet(false);
      this.priorityOrder = 0;
      this.unicoreJobSubmission = null;
    }

    public org.apache.airavata.model.security.AuthzToken getAuthzToken() {
      return this.authzToken;
    }

    public addUNICOREJobSubmissionDetails_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 String getComputeResourceId() {
      return this.computeResourceId;
    }

    public addUNICOREJobSubmissionDetails_args setComputeResourceId(String computeResourceId) {
      this.computeResourceId = computeResourceId;
      return this;
    }

    public void unsetComputeResourceId() {
      this.computeResourceId = null;
    }

    /** Returns true if field computeResourceId is set (has been assigned a value) and false otherwise */
    public boolean isSetComputeResourceId() {
      return this.computeResourceId != null;
    }

    public void setComputeResourceIdIsSet(boolean value) {
      if (!value) {
        this.computeResourceId = null;
      }
    }

    public int getPriorityOrder() {
      return this.priorityOrder;
    }

    public addUNICOREJobSubmissionDetails_args setPriorityOrder(int priorityOrder) {
      this.priorityOrder = priorityOrder;
      setPriorityOrderIsSet(true);
      return this;
    }

    public void unsetPriorityOrder() {
      __isset_bitfield = EncodingUtils.clearBit(__isset_bitfield, __PRIORITYORDER_ISSET_ID);
    }

    /** Returns true if field priorityOrder is set (has been assigned a value) and false otherwise */
    public boolean isSetPriorityOrder() {
      return EncodingUtils.testBit(__isset_bitfield, __PRIORITYORDER_ISSET_ID);
    }

    public void setPriorityOrderIsSet(boolean value) {
      __isset_bitfield = EncodingUtils.setBit(__isset_bitfield, __PRIORITYORDER_ISSET_ID, value);
    }

    public org.apache.airavata.model.appcatalog.computeresource.UnicoreJobSubmission getUnicoreJobSubmission() {
      return this.unicoreJobSubmission;
    }

    public addUNICOREJobSubmissionDetails_args setUnicoreJobSubmission(org.apache.airavata.model.appcatalog.computeresource.UnicoreJobSubmission unicoreJobSubmission) {
      this.unicoreJobSubmission = unicoreJobSubmission;
      return this;
    }

    public void unsetUnicoreJobSubmission() {
      this.unicoreJobSubmission = null;
    }

    /** Returns true if field unicoreJobSubmission is set (has been assigned a value) and false otherwise */
    public boolean isSetUnicoreJobSubmission() {
      return this.unicoreJobSubmission != null;
    }

    public void setUnicoreJobSubmissionIsSet(boolean value) {
      if (!value) {
        this.unicoreJobSubmission = null;
      }
    }

    public void setFieldValue(_Fields field, Object value) {
      switch (field) {
      case AUTHZ_TOKEN:
        if (value == null) {
          unsetAuthzToken();
        } else {
          setAuthzToken((org.apache.airavata.model.security.AuthzToken)value);
        }
        break;

      case COMPUTE_RESOURCE_ID:
        if (value == null) {
          unsetComputeResourceId();
        } else {
          setComputeResourceId((String)value);
        }
        break;

      case PRIORITY_ORDER:
        if (value == null) {
          unsetPriorityOrder();
        } else {
          setPriorityOrder((Integer)value);
        }
        break;

      case UNICORE_JOB_SUBMISSION:
        if (value == null) {
          unsetUnicoreJobSubmission();
        } else {
          setUnicoreJobSubmission((org.apache.airavata.model.appcatalog.computeresource.UnicoreJobSubmission)value);
        }
        break;

      }
    }

    public Object getFieldValue(_Fields field) {
      switch (field) {
      case AUTHZ_TOKEN:
        return getAuthzToken();

      case COMPUTE_RESOURCE_ID:
        return getComputeResourceId();

      case PRIORITY_ORDER:
        return Integer.valueOf(getPriorityOrder());

      case UNICORE_JOB_SUBMISSION:
        return getUnicoreJobSubmission();

      }
      throw new IllegalStateException();
    }

    /** Returns true if field corresponding to fieldID is set (has been assigned a value) and false otherwise */
    public boolean isSet(_Fields field) {
      if (field == null) {
        throw new IllegalArgumentException();
      }

      switch (field) {
      case AUTHZ_TOKEN:
        return isSetAuthzToken();
      case COMPUTE_RESOURCE_ID:
        return isSetComputeResourceId();
      case PRIORITY_ORDER:
        return isSetPriorityOrder();
      case UNICORE_JOB_SUBMISSION:
        return isSetUnicoreJobSubmission();
      }
      throw new IllegalStateException();
    }

    @Override
    public boolean equals(Object that) {
      if (that == null)
        return false;
      if (that instanceof addUNICOREJobSubmissionDetails_args)
        return this.equals((addUNICOREJobSubmissionDetails_args)that);
      return false;
    }

    public boolean equals(addUNICOREJobSubmissionDetails_args that) {
      if (that == null)
        return false;

      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_computeResourceId = true && this.isSetComputeResourceId();
      boolean that_present_computeResourceId = true && that.isSetComputeResourceId();
      if (this_present_computeResourceId || that_present_computeResourceId) {
        if (!(this_present_computeResourceId && that_present_computeResourceId))
          return false;
        if (!this.computeResourceId.equals(that.computeResourceId))
          return false;
      }

      boolean this_present_priorityOrder = true;
      boolean that_present_priorityOrder = true;
      if (this_present_priorityOrder || that_present_priorityOrder) {
        if (!(this_present_priorityOrder && that_present_priorityOrder))
          return false;
        if (this.priorityOrder != that.priorityOrder)
          return false;
      }

      boolean this_present_unicoreJobSubmission = true && this.isSetUnicoreJobSubmission();
      boolean that_present_unicoreJobSubmission = true && that.isSetUnicoreJobSubmission();
      if (this_present_unicoreJobSubmission || that_present_unicoreJobSubmission) {
        if (!(this_present_unicoreJobSubmission && that_present_unicoreJobSubmission))
          return false;
        if (!this.unicoreJobSubmission.equals(that.unicoreJobSubmission))
          return false;
      }

      return true;
    }

    @Override
    public int hashCode() {
      List<Object> list = new ArrayList<Object>();

      boolean present_authzToken = true && (isSetAuthzToken());
      list.add(present_authzToken);
      if (present_authzToken)
        list.add(authzToken);

      boolean present_computeResourceId = true && (isSetComputeResourceId());
      list.add(present_computeResourceId);
      if (present_computeResourceId)
        list.add(computeResourceId);

      boolean present_priorityOrder = true;
      list.add(present_priorityOrder);
      if (present_priorityOrder)
        list.add(priorityOrder);

      boolean present_unicoreJobSubmission = true && (isSetUnicoreJobSubmission());
      list.add(present_unicoreJobSubmission);
      if (present_unicoreJobSubmission)
        list.add(unicoreJobSubmission);

      return list.hashCode();
    }

    @Override
    public int compareTo(addUNICOREJobSubmissionDetails_args other) {
      if (!getClass().equals(other.getClass())) {
        return getClass().getName().compareTo(other.getClass().getName());
      }

      int lastComparison = 0;

      lastComparison = 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 = Boolean.valueOf(isSetComputeResourceId()).compareTo(other.isSetComputeResourceId());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetComputeResourceId()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.computeResourceId, other.computeResourceId);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = Boolean.valueOf(isSetPriorityOrder()).compareTo(other.isSetPriorityOrder());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetPriorityOrder()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.priorityOrder, other.priorityOrder);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = Boolean.valueOf(isSetUnicoreJobSubmission()).compareTo(other.isSetUnicoreJobSubmission());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetUnicoreJobSubmission()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.unicoreJobSubmission, other.unicoreJobSubmission);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      return 0;
    }

    public _Fields fieldForId(int fieldId) {
      return _Fields.findByThriftId(fieldId);
    }

    public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
      schemes.get(iprot.getScheme()).getScheme().read(iprot, this);
    }

    public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException {
      schemes.get(oprot.getScheme()).getScheme().write(oprot, this);
    }

    @Override
    public String toString() {
      StringBuilder sb = new StringBuilder("addUNICOREJobSubmissionDetails_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("computeResourceId:");
      if (this.computeResourceId == null) {
        sb.append("null");
      } else {
        sb.append(this.computeResourceId);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("priorityOrder:");
      sb.append(this.priorityOrder);
      first = false;
      if (!first) sb.append(", ");
      sb.append("unicoreJobSubmission:");
      if (this.unicoreJobSubmission == null) {
        sb.append("null");
      } else {
        sb.append(this.unicoreJobSubmission);
      }
      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 (computeResourceId == null) {
        throw new org.apache.thrift.protocol.TProtocolException("Required field 'computeResourceId' was not present! Struct: " + toString());
      }
      // alas, we cannot check 'priorityOrder' because it's a primitive and you chose the non-beans generator.
      if (unicoreJobSubmission == null) {
        throw new org.apache.thrift.protocol.TProtocolException("Required field 'unicoreJobSubmission' was not present! Struct: " + toString());
      }
      // check for sub-struct validity
      if (authzToken != null) {
        authzToken.validate();
      }
      if (unicoreJobSubmission != null) {
        unicoreJobSubmission.validate();
      }
    }

    private void writeObject(java.io.ObjectOutputStream out) throws java.io.IOException {
      try {
        write(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(out)));
      } catch (org.apache.thrift.TException te) {
        throw new java.io.IOException(te);
      }
    }

    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, ClassNotFoundException {
      try {
        // 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 addUNICOREJobSubmissionDetails_argsStandardSchemeFactory implements SchemeFactory {
      public addUNICOREJobSubmissionDetails_argsStandardScheme getScheme() {
        return new addUNICOREJobSubmissionDetails_argsStandardScheme();
      }
    }

    private static class addUNICOREJobSubmissionDetails_argsStandardScheme extends StandardScheme<addUNICOREJobSubmissionDetails_args> {

      public void read(org.apache.thrift.protocol.TProtocol iprot, addUNICOREJobSubmissionDetails_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: // COMPUTE_RESOURCE_ID
              if (schemeField.type == org.apache.thrift.protocol.TType.STRING) {
                struct.computeResourceId = iprot.readString();
                struct.setComputeResourceIdIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 3: // PRIORITY_ORDER
              if (schemeField.type == org.apache.thrift.protocol.TType.I32) {
                struct.priorityOrder = iprot.readI32();
                struct.setPriorityOrderIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 4: // UNICORE_JOB_SUBMISSION
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.unicoreJobSubmission = new org.apache.airavata.model.appcatalog.computeresource.UnicoreJobSubmission();
                struct.unicoreJobSubmission.read(iprot);
                struct.setUnicoreJobSubmissionIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            default:
              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
          }
          iprot.readFieldEnd();
        }
        iprot.readStructEnd();

        // check for required fields of primitive type, which can't be checked in the validate method
        if (!struct.isSetPriorityOrder()) {
          throw new org.apache.thrift.protocol.TProtocolException("Required field 'priorityOrder' was not found in serialized data! Struct: " + toString());
        }
        struct.validate();
      }

      public void write(org.apache.thrift.protocol.TProtocol oprot, addUNICOREJobSubmissionDetails_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.computeResourceId != null) {
          oprot.writeFieldBegin(COMPUTE_RESOURCE_ID_FIELD_DESC);
          oprot.writeString(struct.computeResourceId);
          oprot.writeFieldEnd();
        }
        oprot.writeFieldBegin(PRIORITY_ORDER_FIELD_DESC);
        oprot.writeI32(struct.priorityOrder);
        oprot.writeFieldEnd();
        if (struct.unicoreJobSubmission != null) {
          oprot.writeFieldBegin(UNICORE_JOB_SUBMISSION_FIELD_DESC);
          struct.unicoreJobSubmission.write(oprot);
          oprot.writeFieldEnd();
        }
        oprot.writeFieldStop();
        oprot.writeStructEnd();
      }

    }

    private static class addUNICOREJobSubmissionDetails_argsTupleSchemeFactory implements SchemeFactory {
      public addUNICOREJobSubmissionDetails_argsTupleScheme getScheme() {
        return new addUNICOREJobSubmissionDetails_argsTupleScheme();
      }
    }

    private static class addUNICOREJobSubmissionDetails_argsTupleScheme extends TupleScheme<addUNICOREJobSubmissionDetails_args> {

      @Override
      public void write(org.apache.thrift.protocol.TProtocol prot, addUNICOREJobSubmissionDetails_args struct) throws org.apache.thrift.TException {
        TTupleProtocol oprot = (TTupleProtocol) prot;
        struct.authzToken.write(oprot);
        oprot.writeString(struct.computeResourceId);
        oprot.writeI32(struct.priorityOrder);
        struct.unicoreJobSubmission.write(oprot);
      }

      @Override
      public void read(org.apache.thrift.protocol.TProtocol prot, addUNICOREJobSubmissionDetails_args struct) throws org.apache.thrift.TException {
        TTupleProtocol iprot = (TTupleProtocol) prot;
        struct.authzToken = new org.apache.airavata.model.security.AuthzToken();
        struct.authzToken.read(iprot);
        struct.setAuthzTokenIsSet(true);
        struct.computeResourceId = iprot.readString();
        struct.setComputeResourceIdIsSet(true);
        struct.priorityOrder = iprot.readI32();
        struct.setPriorityOrderIsSet(true);
        struct.unicoreJobSubmission = new org.apache.airavata.model.appcatalog.computeresource.UnicoreJobSubmission();
        struct.unicoreJobSubmission.read(iprot);
        struct.setUnicoreJobSubmissionIsSet(true);
      }
    }

  }

  public static class addUNICOREJobSubmissionDetails_result implements org.apache.thrift.TBase<addUNICOREJobSubmissionDetails_result, addUNICOREJobSubmissionDetails_result._Fields>, java.io.Serializable, Cloneable, Comparable<addUNICOREJobSubmissionDetails_result>   {
    private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("addUNICOREJobSubmissionDetails_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 IRE_FIELD_DESC = new org.apache.thrift.protocol.TField("ire", org.apache.thrift.protocol.TType.STRUCT, (short)1);
    private static final org.apache.thrift.protocol.TField ACE_FIELD_DESC = new org.apache.thrift.protocol.TField("ace", org.apache.thrift.protocol.TType.STRUCT, (short)2);
    private static final org.apache.thrift.protocol.TField ASE_FIELD_DESC = new org.apache.thrift.protocol.TField("ase", org.apache.thrift.protocol.TType.STRUCT, (short)3);
    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)4);

    private static final Map<Class<? extends IScheme>, SchemeFactory> schemes = new HashMap<Class<? extends IScheme>, SchemeFactory>();
    static {
      schemes.put(StandardScheme.class, new addUNICOREJobSubmissionDetails_resultStandardSchemeFactory());
      schemes.put(TupleScheme.class, new addUNICOREJobSubmissionDetails_resultTupleSchemeFactory());
    }

    public String success; // required
    public org.apache.airavata.model.error.InvalidRequestException ire; // required
    public org.apache.airavata.model.error.AiravataClientException ace; // required
    public org.apache.airavata.model.error.AiravataSystemException ase; // 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"),
      IRE((short)1, "ire"),
      ACE((short)2, "ace"),
      ASE((short)3, "ase"),
      AE((short)4, "ae");

      private static final Map<String, _Fields> byName = new HashMap<String, _Fields>();

      static {
        for (_Fields field : EnumSet.allOf(_Fields.class)) {
          byName.put(field.getFieldName(), field);
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, or null if its not found.
       */
      public static _Fields findByThriftId(int fieldId) {
        switch(fieldId) {
          case 0: // SUCCESS
            return SUCCESS;
          case 1: // IRE
            return IRE;
          case 2: // ACE
            return ACE;
          case 3: // ASE
            return ASE;
          case 4: // 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 IllegalArgumentException("Field " + fieldId + " doesn't exist!");
        return fields;
      }

      /**
       * Find the _Fields constant that matches name, or null if its not found.
       */
      public static _Fields findByName(String name) {
        return byName.get(name);
      }

      private final short _thriftId;
      private final String _fieldName;

      _Fields(short thriftId, String fieldName) {
        _thriftId = thriftId;
        _fieldName = fieldName;
      }

      public short getThriftFieldId() {
        return _thriftId;
      }

      public String getFieldName() {
        return _fieldName;
      }
    }

    // isset id assignments
    public static final Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
    static {
      Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new EnumMap<_Fields, org.apache.thrift.meta_data.FieldMetaData>(_Fields.class);
      tmpMap.put(_Fields.SUCCESS, new org.apache.thrift.meta_data.FieldMetaData("success", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING)));
      tmpMap.put(_Fields.IRE, new org.apache.thrift.meta_data.FieldMetaData("ire", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRUCT)));
      tmpMap.put(_Fields.ACE, new org.apache.thrift.meta_data.FieldMetaData("ace", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRUCT)));
      tmpMap.put(_Fields.ASE, new org.apache.thrift.meta_data.FieldMetaData("ase", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRUCT)));
      tmpMap.put(_Fields.AE, new org.apache.thrift.meta_data.FieldMetaData("ae", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRUCT)));
      metaDataMap = Collections.unmodifiableMap(tmpMap);
      org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(addUNICOREJobSubmissionDetails_result.class, metaDataMap);
    }

    public addUNICOREJobSubmissionDetails_result() {
    }

    public addUNICOREJobSubmissionDetails_result(
      String success,
      org.apache.airavata.model.error.InvalidRequestException ire,
      org.apache.airavata.model.error.AiravataClientException ace,
      org.apache.airavata.model.error.AiravataSystemException ase,
      org.apache.airavata.model.error.AuthorizationException ae)
    {
      this();
      this.success = success;
      this.ire = ire;
      this.ace = ace;
      this.ase = ase;
      this.ae = ae;
    }

    /**
     * Performs a deep copy on <i>other</i>.
     */
    public addUNICOREJobSubmissionDetails_result(addUNICOREJobSubmissionDetails_result other) {
      if (other.isSetSuccess()) {
        this.success = other.success;
      }
      if (other.isSetIre()) {
        this.ire = new org.apache.airavata.model.error.InvalidRequestException(other.ire);
      }
      if (other.isSetAce()) {
        this.ace = new org.apache.airavata.model.error.AiravataClientException(other.ace);
      }
      if (other.isSetAse()) {
        this.ase = new org.apache.airavata.model.error.AiravataSystemException(other.ase);
      }
      if (other.isSetAe()) {
        this.ae = new org.apache.airavata.model.error.AuthorizationException(other.ae);
      }
    }

    public addUNICOREJobSubmissionDetails_result deepCopy() {
      return new addUNICOREJobSubmissionDetails_result(this);
    }

    @Override
    public void clear() {
      this.success = null;
      this.ire = null;
      this.ace = null;
      this.ase = null;
      this.ae = null;
    }

    public String getSuccess() {
      return this.success;
    }

    public addUNICOREJobSubmissionDetails_result setSuccess(String success) {
      this.success = success;
      return this;
    }

    public void unsetSuccess() {
      this.success = null;
    }

    /** Returns true if field success is set (has been assigned a value) and false otherwise */
    public boolean isSetSuccess() {
      return this.success != null;
    }

    public void setSuccessIsSet(boolean value) {
      if (!value) {
        this.success = null;
      }
    }

    public org.apache.airavata.model.error.InvalidRequestException getIre() {
      return this.ire;
    }

    public addUNICOREJobSubmissionDetails_result setIre(org.apache.airavata.model.error.InvalidRequestException ire) {
      this.ire = ire;
      return this;
    }

    public void unsetIre() {
      this.ire = null;
    }

    /** Returns true if field ire is set (has been assigned a value) and false otherwise */
    public boolean isSetIre() {
      return this.ire != null;
    }

    public void setIreIsSet(boolean value) {
      if (!value) {
        this.ire = null;
      }
    }

    public org.apache.airavata.model.error.AiravataClientException getAce() {
      return this.ace;
    }

    public addUNICOREJobSubmissionDetails_result setAce(org.apache.airavata.model.error.AiravataClientException ace) {
      this.ace = ace;
      return this;
    }

    public void unsetAce() {
      this.ace = null;
    }

    /** Returns true if field ace is set (has been assigned a value) and false otherwise */
    public boolean isSetAce() {
      return this.ace != null;
    }

    public void setAceIsSet(boolean value) {
      if (!value) {
        this.ace = null;
      }
    }

    public org.apache.airavata.model.error.AiravataSystemException getAse() {
      return this.ase;
    }

    public addUNICOREJobSubmissionDetails_result setAse(org.apache.airavata.model.error.AiravataSystemException ase) {
      this.ase = ase;
      return this;
    }

    public void unsetAse() {
      this.ase = null;
    }

    /** Returns true if field ase is set (has been assigned a value) and false otherwise */
    public boolean isSetAse() {
      return this.ase != null;
    }

    public void setAseIsSet(boolean value) {
      if (!value) {
        this.ase = null;
      }
    }

    public org.apache.airavata.model.error.AuthorizationException getAe() {
      return this.ae;
    }

    public addUNICOREJobSubmissionDetails_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, Object value) {
      switch (field) {
      case SUCCESS:
        if (value == null) {
          unsetSuccess();
        } else {
          setSuccess((String)value);
        }
        break;

      case IRE:
        if (value == null) {
          unsetIre();
        } else {
          setIre((org.apache.airavata.model.error.InvalidRequestException)value);
        }
        break;

      case ACE:
        if (value == null) {
          unsetAce();
        } else {
          setAce((org.apache.airavata.model.error.AiravataClientException)value);
        }
        break;

      case ASE:
        if (value == null) {
          unsetAse();
        } else {
          setAse((org.apache.airavata.model.error.AiravataSystemException)value);
        }
        break;

      case AE:
        if (value == null) {
          unsetAe();
        } else {
          setAe((org.apache.airavata.model.error.AuthorizationException)value);
        }
        break;

      }
    }

    public Object getFieldValue(_Fields field) {
      switch (field) {
      case SUCCESS:
        return getSuccess();

      case IRE:
        return getIre();

      case ACE:
        return getAce();

      case ASE:
        return getAse();

      case AE:
        return getAe();

      }
      throw new IllegalStateException();
    }

    /** Returns true if field corresponding to fieldID is set (has been assigned a value) and false otherwise */
    public boolean isSet(_Fields field) {
      if (field == null) {
        throw new IllegalArgumentException();
      }

      switch (field) {
      case SUCCESS:
        return isSetSuccess();
      case IRE:
        return isSetIre();
      case ACE:
        return isSetAce();
      case ASE:
        return isSetAse();
      case AE:
        return isSetAe();
      }
      throw new IllegalStateException();
    }

    @Override
    public boolean equals(Object that) {
      if (that == null)
        return false;
      if (that instanceof addUNICOREJobSubmissionDetails_result)
        return this.equals((addUNICOREJobSubmissionDetails_result)that);
      return false;
    }

    public boolean equals(addUNICOREJobSubmissionDetails_result that) {
      if (that == null)
        return false;

      boolean this_present_success = true && this.isSetSuccess();
      boolean that_present_success = true && that.isSetSuccess();
      if (this_present_success || that_present_success) {
        if (!(this_present_success && that_present_success))
          return false;
        if (!this.success.equals(that.success))
          return false;
      }

      boolean this_present_ire = true && this.isSetIre();
      boolean that_present_ire = true && that.isSetIre();
      if (this_present_ire || that_present_ire) {
        if (!(this_present_ire && that_present_ire))
          return false;
        if (!this.ire.equals(that.ire))
          return false;
      }

      boolean this_present_ace = true && this.isSetAce();
      boolean that_present_ace = true && that.isSetAce();
      if (this_present_ace || that_present_ace) {
        if (!(this_present_ace && that_present_ace))
          return false;
        if (!this.ace.equals(that.ace))
          return false;
      }

      boolean this_present_ase = true && this.isSetAse();
      boolean that_present_ase = true && that.isSetAse();
      if (this_present_ase || that_present_ase) {
        if (!(this_present_ase && that_present_ase))
          return false;
        if (!this.ase.equals(that.ase))
          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() {
      List<Object> list = new ArrayList<Object>();

      boolean present_success = true && (isSetSuccess());
      list.add(present_success);
      if (present_success)
        list.add(success);

      boolean present_ire = true && (isSetIre());
      list.add(present_ire);
      if (present_ire)
        list.add(ire);

      boolean present_ace = true && (isSetAce());
      list.add(present_ace);
      if (present_ace)
        list.add(ace);

      boolean present_ase = true && (isSetAse());
      list.add(present_ase);
      if (present_ase)
        list.add(ase);

      boolean present_ae = true && (isSetAe());
      list.add(present_ae);
      if (present_ae)
        list.add(ae);

      return list.hashCode();
    }

    @Override
    public int compareTo(addUNICOREJobSubmissionDetails_result other) {
      if (!getClass().equals(other.getClass())) {
        return getClass().getName().compareTo(other.getClass().getName());
      }

      int lastComparison = 0;

      lastComparison = Boolean.valueOf(isSetSuccess()).compareTo(other.isSetSuccess());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetSuccess()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.success, other.success);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = Boolean.valueOf(isSetIre()).compareTo(other.isSetIre());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetIre()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.ire, other.ire);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = Boolean.valueOf(isSetAce()).compareTo(other.isSetAce());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetAce()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.ace, other.ace);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = Boolean.valueOf(isSetAse()).compareTo(other.isSetAse());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetAse()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.ase, other.ase);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = 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 {
      schemes.get(iprot.getScheme()).getScheme().read(iprot, this);
    }

    public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException {
      schemes.get(oprot.getScheme()).getScheme().write(oprot, this);
      }

    @Override
    public String toString() {
      StringBuilder sb = new StringBuilder("addUNICOREJobSubmissionDetails_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("ire:");
      if (this.ire == null) {
        sb.append("null");
      } else {
        sb.append(this.ire);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("ace:");
      if (this.ace == null) {
        sb.append("null");
      } else {
        sb.append(this.ace);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("ase:");
      if (this.ase == null) {
        sb.append("null");
      } else {
        sb.append(this.ase);
      }
      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, 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 addUNICOREJobSubmissionDetails_resultStandardSchemeFactory implements SchemeFactory {
      public addUNICOREJobSubmissionDetails_resultStandardScheme getScheme() {
        return new addUNICOREJobSubmissionDetails_resultStandardScheme();
      }
    }

    private static class addUNICOREJobSubmissionDetails_resultStandardScheme extends StandardScheme<addUNICOREJobSubmissionDetails_result> {

      public void read(org.apache.thrift.protocol.TProtocol iprot, addUNICOREJobSubmissionDetails_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: // IRE
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.ire = new org.apache.airavata.model.error.InvalidRequestException();
                struct.ire.read(iprot);
                struct.setIreIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 2: // ACE
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.ace = new org.apache.airavata.model.error.AiravataClientException();
                struct.ace.read(iprot);
                struct.setAceIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 3: // ASE
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.ase = new org.apache.airavata.model.error.AiravataSystemException();
                struct.ase.read(iprot);
                struct.setAseIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 4: // 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, addUNICOREJobSubmissionDetails_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.ire != null) {
          oprot.writeFieldBegin(IRE_FIELD_DESC);
          struct.ire.write(oprot);
          oprot.writeFieldEnd();
        }
        if (struct.ace != null) {
          oprot.writeFieldBegin(ACE_FIELD_DESC);
          struct.ace.write(oprot);
          oprot.writeFieldEnd();
        }
        if (struct.ase != null) {
          oprot.writeFieldBegin(ASE_FIELD_DESC);
          struct.ase.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 addUNICOREJobSubmissionDetails_resultTupleSchemeFactory implements SchemeFactory {
      public addUNICOREJobSubmissionDetails_resultTupleScheme getScheme() {
        return new addUNICOREJobSubmissionDetails_resultTupleScheme();
      }
    }

    private static class addUNICOREJobSubmissionDetails_resultTupleScheme extends TupleScheme<addUNICOREJobSubmissionDetails_result> {

      @Override
      public void write(org.apache.thrift.protocol.TProtocol prot, addUNICOREJobSubmissionDetails_result struct) throws org.apache.thrift.TException {
        TTupleProtocol oprot = (TTupleProtocol) prot;
        BitSet optionals = new BitSet();
        if (struct.isSetSuccess()) {
          optionals.set(0);
        }
        if (struct.isSetIre()) {
          optionals.set(1);
        }
        if (struct.isSetAce()) {
          optionals.set(2);
        }
        if (struct.isSetAse()) {
          optionals.set(3);
        }
        if (struct.isSetAe()) {
          optionals.set(4);
        }
        oprot.writeBitSet(optionals, 5);
        if (struct.isSetSuccess()) {
          oprot.writeString(struct.success);
        }
        if (struct.isSetIre()) {
          struct.ire.write(oprot);
        }
        if (struct.isSetAce()) {
          struct.ace.write(oprot);
        }
        if (struct.isSetAse()) {
          struct.ase.write(oprot);
        }
        if (struct.isSetAe()) {
          struct.ae.write(oprot);
        }
      }

      @Override
      public void read(org.apache.thrift.protocol.TProtocol prot, addUNICOREJobSubmissionDetails_result struct) throws org.apache.thrift.TException {
        TTupleProtocol iprot = (TTupleProtocol) prot;
        BitSet incoming = iprot.readBitSet(5);
        if (incoming.get(0)) {
          struct.success = iprot.readString();
          struct.setSuccessIsSet(true);
        }
        if (incoming.get(1)) {
          struct.ire = new org.apache.airavata.model.error.InvalidRequestException();
          struct.ire.read(iprot);
          struct.setIreIsSet(true);
        }
        if (incoming.get(2)) {
          struct.ace = new org.apache.airavata.model.error.AiravataClientException();
          struct.ace.read(iprot);
          struct.setAceIsSet(true);
        }
        if (incoming.get(3)) {
          struct.ase = new org.apache.airavata.model.error.AiravataSystemException();
          struct.ase.read(iprot);
          struct.setAseIsSet(true);
        }
        if (incoming.get(4)) {
          struct.ae = new org.apache.airavata.model.error.AuthorizationException();
          struct.ae.read(iprot);
          struct.setAeIsSet(true);
        }
      }
    }

  }

  public static class getUnicoreJobSubmission_args implements org.apache.thrift.TBase<getUnicoreJobSubmission_args, getUnicoreJobSubmission_args._Fields>, java.io.Serializable, Cloneable, Comparable<getUnicoreJobSubmission_args>   {
    private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("getUnicoreJobSubmission_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 JOB_SUBMISSION_ID_FIELD_DESC = new org.apache.thrift.protocol.TField("jobSubmissionId", org.apache.thrift.protocol.TType.STRING, (short)2);

    private static final Map<Class<? extends IScheme>, SchemeFactory> schemes = new HashMap<Class<? extends IScheme>, SchemeFactory>();
    static {
      schemes.put(StandardScheme.class, new getUnicoreJobSubmission_argsStandardSchemeFactory());
      schemes.put(TupleScheme.class, new getUnicoreJobSubmission_argsTupleSchemeFactory());
    }

    public org.apache.airavata.model.security.AuthzToken authzToken; // required
    public String jobSubmissionId; // required

    /** 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"),
      JOB_SUBMISSION_ID((short)2, "jobSubmissionId");

      private static final Map<String, _Fields> byName = new HashMap<String, _Fields>();

      static {
        for (_Fields field : EnumSet.allOf(_Fields.class)) {
          byName.put(field.getFieldName(), field);
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, or null if its not found.
       */
      public static _Fields findByThriftId(int fieldId) {
        switch(fieldId) {
          case 1: // AUTHZ_TOKEN
            return AUTHZ_TOKEN;
          case 2: // JOB_SUBMISSION_ID
            return JOB_SUBMISSION_ID;
          default:
            return null;
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, throwing an exception
       * if it is not found.
       */
      public static _Fields findByThriftIdOrThrow(int fieldId) {
        _Fields fields = findByThriftId(fieldId);
        if (fields == null) throw new IllegalArgumentException("Field " + fieldId + " doesn't exist!");
        return fields;
      }

      /**
       * Find the _Fields constant that matches name, or null if its not found.
       */
      public static _Fields findByName(String name) {
        return byName.get(name);
      }

      private final short _thriftId;
      private final String _fieldName;

      _Fields(short thriftId, String fieldName) {
        _thriftId = thriftId;
        _fieldName = fieldName;
      }

      public short getThriftFieldId() {
        return _thriftId;
      }

      public String getFieldName() {
        return _fieldName;
      }
    }

    // isset id assignments
    public static final Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
    static {
      Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new EnumMap<_Fields, org.apache.thrift.meta_data.FieldMetaData>(_Fields.class);
      tmpMap.put(_Fields.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.JOB_SUBMISSION_ID, new org.apache.thrift.meta_data.FieldMetaData("jobSubmissionId", org.apache.thrift.TFieldRequirementType.REQUIRED, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING)));
      metaDataMap = Collections.unmodifiableMap(tmpMap);
      org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(getUnicoreJobSubmission_args.class, metaDataMap);
    }

    public getUnicoreJobSubmission_args() {
    }

    public getUnicoreJobSubmission_args(
      org.apache.airavata.model.security.AuthzToken authzToken,
      String jobSubmissionId)
    {
      this();
      this.authzToken = authzToken;
      this.jobSubmissionId = jobSubmissionId;
    }

    /**
     * Performs a deep copy on <i>other</i>.
     */
    public getUnicoreJobSubmission_args(getUnicoreJobSubmission_args other) {
      if (other.isSetAuthzToken()) {
        this.authzToken = new org.apache.airavata.model.security.AuthzToken(other.authzToken);
      }
      if (other.isSetJobSubmissionId()) {
        this.jobSubmissionId = other.jobSubmissionId;
      }
    }

    public getUnicoreJobSubmission_args deepCopy() {
      return new getUnicoreJobSubmission_args(this);
    }

    @Override
    public void clear() {
      this.authzToken = null;
      this.jobSubmissionId = null;
    }

    public org.apache.airavata.model.security.AuthzToken getAuthzToken() {
      return this.authzToken;
    }

    public getUnicoreJobSubmission_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 String getJobSubmissionId() {
      return this.jobSubmissionId;
    }

    public getUnicoreJobSubmission_args setJobSubmissionId(String jobSubmissionId) {
      this.jobSubmissionId = jobSubmissionId;
      return this;
    }

    public void unsetJobSubmissionId() {
      this.jobSubmissionId = null;
    }

    /** Returns true if field jobSubmissionId is set (has been assigned a value) and false otherwise */
    public boolean isSetJobSubmissionId() {
      return this.jobSubmissionId != null;
    }

    public void setJobSubmissionIdIsSet(boolean value) {
      if (!value) {
        this.jobSubmissionId = null;
      }
    }

    public void setFieldValue(_Fields field, Object value) {
      switch (field) {
      case AUTHZ_TOKEN:
        if (value == null) {
          unsetAuthzToken();
        } else {
          setAuthzToken((org.apache.airavata.model.security.AuthzToken)value);
        }
        break;

      case JOB_SUBMISSION_ID:
        if (value == null) {
          unsetJobSubmissionId();
        } else {
          setJobSubmissionId((String)value);
        }
        break;

      }
    }

    public Object getFieldValue(_Fields field) {
      switch (field) {
      case AUTHZ_TOKEN:
        return getAuthzToken();

      case JOB_SUBMISSION_ID:
        return getJobSubmissionId();

      }
      throw new IllegalStateException();
    }

    /** Returns true if field corresponding to fieldID is set (has been assigned a value) and false otherwise */
    public boolean isSet(_Fields field) {
      if (field == null) {
        throw new IllegalArgumentException();
      }

      switch (field) {
      case AUTHZ_TOKEN:
        return isSetAuthzToken();
      case JOB_SUBMISSION_ID:
        return isSetJobSubmissionId();
      }
      throw new IllegalStateException();
    }

    @Override
    public boolean equals(Object that) {
      if (that == null)
        return false;
      if (that instanceof getUnicoreJobSubmission_args)
        return this.equals((getUnicoreJobSubmission_args)that);
      return false;
    }

    public boolean equals(getUnicoreJobSubmission_args that) {
      if (that == null)
        return false;

      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_jobSubmissionId = true && this.isSetJobSubmissionId();
      boolean that_present_jobSubmissionId = true && that.isSetJobSubmissionId();
      if (this_present_jobSubmissionId || that_present_jobSubmissionId) {
        if (!(this_present_jobSubmissionId && that_present_jobSubmissionId))
          return false;
        if (!this.jobSubmissionId.equals(that.jobSubmissionId))
          return false;
      }

      return true;
    }

    @Override
    public int hashCode() {
      List<Object> list = new ArrayList<Object>();

      boolean present_authzToken = true && (isSetAuthzToken());
      list.add(present_authzToken);
      if (present_authzToken)
        list.add(authzToken);

      boolean present_jobSubmissionId = true && (isSetJobSubmissionId());
      list.add(present_jobSubmissionId);
      if (present_jobSubmissionId)
        list.add(jobSubmissionId);

      return list.hashCode();
    }

    @Override
    public int compareTo(getUnicoreJobSubmission_args other) {
      if (!getClass().equals(other.getClass())) {
        return getClass().getName().compareTo(other.getClass().getName());
      }

      int lastComparison = 0;

      lastComparison = 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 = Boolean.valueOf(isSetJobSubmissionId()).compareTo(other.isSetJobSubmissionId());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetJobSubmissionId()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.jobSubmissionId, other.jobSubmissionId);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      return 0;
    }

    public _Fields fieldForId(int fieldId) {
      return _Fields.findByThriftId(fieldId);
    }

    public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
      schemes.get(iprot.getScheme()).getScheme().read(iprot, this);
    }

    public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException {
      schemes.get(oprot.getScheme()).getScheme().write(oprot, this);
    }

    @Override
    public String toString() {
      StringBuilder sb = new StringBuilder("getUnicoreJobSubmission_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("jobSubmissionId:");
      if (this.jobSubmissionId == null) {
        sb.append("null");
      } else {
        sb.append(this.jobSubmissionId);
      }
      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 (jobSubmissionId == null) {
        throw new org.apache.thrift.protocol.TProtocolException("Required field 'jobSubmissionId' 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, 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 getUnicoreJobSubmission_argsStandardSchemeFactory implements SchemeFactory {
      public getUnicoreJobSubmission_argsStandardScheme getScheme() {
        return new getUnicoreJobSubmission_argsStandardScheme();
      }
    }

    private static class getUnicoreJobSubmission_argsStandardScheme extends StandardScheme<getUnicoreJobSubmission_args> {

      public void read(org.apache.thrift.protocol.TProtocol iprot, getUnicoreJobSubmission_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: // JOB_SUBMISSION_ID
              if (schemeField.type == org.apache.thrift.protocol.TType.STRING) {
                struct.jobSubmissionId = iprot.readString();
                struct.setJobSubmissionIdIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            default:
              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
          }
          iprot.readFieldEnd();
        }
        iprot.readStructEnd();

        // check for required fields of primitive type, which can't be checked in the validate method
        struct.validate();
      }

      public void write(org.apache.thrift.protocol.TProtocol oprot, getUnicoreJobSubmission_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.jobSubmissionId != null) {
          oprot.writeFieldBegin(JOB_SUBMISSION_ID_FIELD_DESC);
          oprot.writeString(struct.jobSubmissionId);
          oprot.writeFieldEnd();
        }
        oprot.writeFieldStop();
        oprot.writeStructEnd();
      }

    }

    private static class getUnicoreJobSubmission_argsTupleSchemeFactory implements SchemeFactory {
      public getUnicoreJobSubmission_argsTupleScheme getScheme() {
        return new getUnicoreJobSubmission_argsTupleScheme();
      }
    }

    private static class getUnicoreJobSubmission_argsTupleScheme extends TupleScheme<getUnicoreJobSubmission_args> {

      @Override
      public void write(org.apache.thrift.protocol.TProtocol prot, getUnicoreJobSubmission_args struct) throws org.apache.thrift.TException {
        TTupleProtocol oprot = (TTupleProtocol) prot;
        struct.authzToken.write(oprot);
        oprot.writeString(struct.jobSubmissionId);
      }

      @Override
      public void read(org.apache.thrift.protocol.TProtocol prot, getUnicoreJobSubmission_args struct) throws org.apache.thrift.TException {
        TTupleProtocol iprot = (TTupleProtocol) prot;
        struct.authzToken = new org.apache.airavata.model.security.AuthzToken();
        struct.authzToken.read(iprot);
        struct.setAuthzTokenIsSet(true);
        struct.jobSubmissionId = iprot.readString();
        struct.setJobSubmissionIdIsSet(true);
      }
    }

  }

  public static class getUnicoreJobSubmission_result implements org.apache.thrift.TBase<getUnicoreJobSubmission_result, getUnicoreJobSubmission_result._Fields>, java.io.Serializable, Cloneable, Comparable<getUnicoreJobSubmission_result>   {
    private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("getUnicoreJobSubmission_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 IRE_FIELD_DESC = new org.apache.thrift.protocol.TField("ire", org.apache.thrift.protocol.TType.STRUCT, (short)1);
    private static final org.apache.thrift.protocol.TField ACE_FIELD_DESC = new org.apache.thrift.protocol.TField("ace", org.apache.thrift.protocol.TType.STRUCT, (short)2);
    private static final org.apache.thrift.protocol.TField ASE_FIELD_DESC = new org.apache.thrift.protocol.TField("ase", org.apache.thrift.protocol.TType.STRUCT, (short)3);
    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)4);

    private static final Map<Class<? extends IScheme>, SchemeFactory> schemes = new HashMap<Class<? extends IScheme>, SchemeFactory>();
    static {
      schemes.put(StandardScheme.class, new getUnicoreJobSubmission_resultStandardSchemeFactory());
      schemes.put(TupleScheme.class, new getUnicoreJobSubmission_resultTupleSchemeFactory());
    }

    public org.apache.airavata.model.appcatalog.computeresource.UnicoreJobSubmission success; // required
    public org.apache.airavata.model.error.InvalidRequestException ire; // required
    public org.apache.airavata.model.error.AiravataClientException ace; // required
    public org.apache.airavata.model.error.AiravataSystemException ase; // 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"),
      IRE((short)1, "ire"),
      ACE((short)2, "ace"),
      ASE((short)3, "ase"),
      AE((short)4, "ae");

      private static final Map<String, _Fields> byName = new HashMap<String, _Fields>();

      static {
        for (_Fields field : EnumSet.allOf(_Fields.class)) {
          byName.put(field.getFieldName(), field);
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, or null if its not found.
       */
      public static _Fields findByThriftId(int fieldId) {
        switch(fieldId) {
          case 0: // SUCCESS
            return SUCCESS;
          case 1: // IRE
            return IRE;
          case 2: // ACE
            return ACE;
          case 3: // ASE
            return ASE;
          case 4: // 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 IllegalArgumentException("Field " + fieldId + " doesn't exist!");
        return fields;
      }

      /**
       * Find the _Fields constant that matches name, or null if its not found.
       */
      public static _Fields findByName(String name) {
        return byName.get(name);
      }

      private final short _thriftId;
      private final String _fieldName;

      _Fields(short thriftId, String fieldName) {
        _thriftId = thriftId;
        _fieldName = fieldName;
      }

      public short getThriftFieldId() {
        return _thriftId;
      }

      public String getFieldName() {
        return _fieldName;
      }
    }

    // isset id assignments
    public static final Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
    static {
      Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new EnumMap<_Fields, org.apache.thrift.meta_data.FieldMetaData>(_Fields.class);
      tmpMap.put(_Fields.SUCCESS, new org.apache.thrift.meta_data.FieldMetaData("success", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.StructMetaData(org.apache.thrift.protocol.TType.STRUCT, org.apache.airavata.model.appcatalog.computeresource.UnicoreJobSubmission.class)));
      tmpMap.put(_Fields.IRE, new org.apache.thrift.meta_data.FieldMetaData("ire", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRUCT)));
      tmpMap.put(_Fields.ACE, new org.apache.thrift.meta_data.FieldMetaData("ace", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRUCT)));
      tmpMap.put(_Fields.ASE, new org.apache.thrift.meta_data.FieldMetaData("ase", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRUCT)));
      tmpMap.put(_Fields.AE, new org.apache.thrift.meta_data.FieldMetaData("ae", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRUCT)));
      metaDataMap = Collections.unmodifiableMap(tmpMap);
      org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(getUnicoreJobSubmission_result.class, metaDataMap);
    }

    public getUnicoreJobSubmission_result() {
    }

    public getUnicoreJobSubmission_result(
      org.apache.airavata.model.appcatalog.computeresource.UnicoreJobSubmission success,
      org.apache.airavata.model.error.InvalidRequestException ire,
      org.apache.airavata.model.error.AiravataClientException ace,
      org.apache.airavata.model.error.AiravataSystemException ase,
      org.apache.airavata.model.error.AuthorizationException ae)
    {
      this();
      this.success = success;
      this.ire = ire;
      this.ace = ace;
      this.ase = ase;
      this.ae = ae;
    }

    /**
     * Performs a deep copy on <i>other</i>.
     */
    public getUnicoreJobSubmission_result(getUnicoreJobSubmission_result other) {
      if (other.isSetSuccess()) {
        this.success = new org.apache.airavata.model.appcatalog.computeresource.UnicoreJobSubmission(other.success);
      }
      if (other.isSetIre()) {
        this.ire = new org.apache.airavata.model.error.InvalidRequestException(other.ire);
      }
      if (other.isSetAce()) {
        this.ace = new org.apache.airavata.model.error.AiravataClientException(other.ace);
      }
      if (other.isSetAse()) {
        this.ase = new org.apache.airavata.model.error.AiravataSystemException(other.ase);
      }
      if (other.isSetAe()) {
        this.ae = new org.apache.airavata.model.error.AuthorizationException(other.ae);
      }
    }

    public getUnicoreJobSubmission_result deepCopy() {
      return new getUnicoreJobSubmission_result(this);
    }

    @Override
    public void clear() {
      this.success = null;
      this.ire = null;
      this.ace = null;
      this.ase = null;
      this.ae = null;
    }

    public org.apache.airavata.model.appcatalog.computeresource.UnicoreJobSubmission getSuccess() {
      return this.success;
    }

    public getUnicoreJobSubmission_result setSuccess(org.apache.airavata.model.appcatalog.computeresource.UnicoreJobSubmission 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.model.error.InvalidRequestException getIre() {
      return this.ire;
    }

    public getUnicoreJobSubmission_result setIre(org.apache.airavata.model.error.InvalidRequestException ire) {
      this.ire = ire;
      return this;
    }

    public void unsetIre() {
      this.ire = null;
    }

    /** Returns true if field ire is set (has been assigned a value) and false otherwise */
    public boolean isSetIre() {
      return this.ire != null;
    }

    public void setIreIsSet(boolean value) {
      if (!value) {
        this.ire = null;
      }
    }

    public org.apache.airavata.model.error.AiravataClientException getAce() {
      return this.ace;
    }

    public getUnicoreJobSubmission_result setAce(org.apache.airavata.model.error.AiravataClientException ace) {
      this.ace = ace;
      return this;
    }

    public void unsetAce() {
      this.ace = null;
    }

    /** Returns true if field ace is set (has been assigned a value) and false otherwise */
    public boolean isSetAce() {
      return this.ace != null;
    }

    public void setAceIsSet(boolean value) {
      if (!value) {
        this.ace = null;
      }
    }

    public org.apache.airavata.model.error.AiravataSystemException getAse() {
      return this.ase;
    }

    public getUnicoreJobSubmission_result setAse(org.apache.airavata.model.error.AiravataSystemException ase) {
      this.ase = ase;
      return this;
    }

    public void unsetAse() {
      this.ase = null;
    }

    /** Returns true if field ase is set (has been assigned a value) and false otherwise */
    public boolean isSetAse() {
      return this.ase != null;
    }

    public void setAseIsSet(boolean value) {
      if (!value) {
        this.ase = null;
      }
    }

    public org.apache.airavata.model.error.AuthorizationException getAe() {
      return this.ae;
    }

    public getUnicoreJobSubmission_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, Object value) {
      switch (field) {
      case SUCCESS:
        if (value == null) {
          unsetSuccess();
        } else {
          setSuccess((org.apache.airavata.model.appcatalog.computeresource.UnicoreJobSubmission)value);
        }
        break;

      case IRE:
        if (value == null) {
          unsetIre();
        } else {
          setIre((org.apache.airavata.model.error.InvalidRequestException)value);
        }
        break;

      case ACE:
        if (value == null) {
          unsetAce();
        } else {
          setAce((org.apache.airavata.model.error.AiravataClientException)value);
        }
        break;

      case ASE:
        if (value == null) {
          unsetAse();
        } else {
          setAse((org.apache.airavata.model.error.AiravataSystemException)value);
        }
        break;

      case AE:
        if (value == null) {
          unsetAe();
        } else {
          setAe((org.apache.airavata.model.error.AuthorizationException)value);
        }
        break;

      }
    }

    public Object getFieldValue(_Fields field) {
      switch (field) {
      case SUCCESS:
        return getSuccess();

      case IRE:
        return getIre();

      case ACE:
        return getAce();

      case ASE:
        return getAse();

      case AE:
        return getAe();

      }
      throw new IllegalStateException();
    }

    /** Returns true if field corresponding to fieldID is set (has been assigned a value) and false otherwise */
    public boolean isSet(_Fields field) {
      if (field == null) {
        throw new IllegalArgumentException();
      }

      switch (field) {
      case SUCCESS:
        return isSetSuccess();
      case IRE:
        return isSetIre();
      case ACE:
        return isSetAce();
      case ASE:
        return isSetAse();
      case AE:
        return isSetAe();
      }
      throw new IllegalStateException();
    }

    @Override
    public boolean equals(Object that) {
      if (that == null)
        return false;
      if (that instanceof getUnicoreJobSubmission_result)
        return this.equals((getUnicoreJobSubmission_result)that);
      return false;
    }

    public boolean equals(getUnicoreJobSubmission_result that) {
      if (that == null)
        return false;

      boolean this_present_success = true && this.isSetSuccess();
      boolean that_present_success = true && that.isSetSuccess();
      if (this_present_success || that_present_success) {
        if (!(this_present_success && that_present_success))
          return false;
        if (!this.success.equals(that.success))
          return false;
      }

      boolean this_present_ire = true && this.isSetIre();
      boolean that_present_ire = true && that.isSetIre();
      if (this_present_ire || that_present_ire) {
        if (!(this_present_ire && that_present_ire))
          return false;
        if (!this.ire.equals(that.ire))
          return false;
      }

      boolean this_present_ace = true && this.isSetAce();
      boolean that_present_ace = true && that.isSetAce();
      if (this_present_ace || that_present_ace) {
        if (!(this_present_ace && that_present_ace))
          return false;
        if (!this.ace.equals(that.ace))
          return false;
      }

      boolean this_present_ase = true && this.isSetAse();
      boolean that_present_ase = true && that.isSetAse();
      if (this_present_ase || that_present_ase) {
        if (!(this_present_ase && that_present_ase))
          return false;
        if (!this.ase.equals(that.ase))
          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() {
      List<Object> list = new ArrayList<Object>();

      boolean present_success = true && (isSetSuccess());
      list.add(present_success);
      if (present_success)
        list.add(success);

      boolean present_ire = true && (isSetIre());
      list.add(present_ire);
      if (present_ire)
        list.add(ire);

      boolean present_ace = true && (isSetAce());
      list.add(present_ace);
      if (present_ace)
        list.add(ace);

      boolean present_ase = true && (isSetAse());
      list.add(present_ase);
      if (present_ase)
        list.add(ase);

      boolean present_ae = true && (isSetAe());
      list.add(present_ae);
      if (present_ae)
        list.add(ae);

      return list.hashCode();
    }

    @Override
    public int compareTo(getUnicoreJobSubmission_result other) {
      if (!getClass().equals(other.getClass())) {
        return getClass().getName().compareTo(other.getClass().getName());
      }

      int lastComparison = 0;

      lastComparison = Boolean.valueOf(isSetSuccess()).compareTo(other.isSetSuccess());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetSuccess()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.success, other.success);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = Boolean.valueOf(isSetIre()).compareTo(other.isSetIre());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetIre()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.ire, other.ire);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = Boolean.valueOf(isSetAce()).compareTo(other.isSetAce());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetAce()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.ace, other.ace);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = Boolean.valueOf(isSetAse()).compareTo(other.isSetAse());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetAse()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.ase, other.ase);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = 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 {
      schemes.get(iprot.getScheme()).getScheme().read(iprot, this);
    }

    public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException {
      schemes.get(oprot.getScheme()).getScheme().write(oprot, this);
      }

    @Override
    public String toString() {
      StringBuilder sb = new StringBuilder("getUnicoreJobSubmission_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("ire:");
      if (this.ire == null) {
        sb.append("null");
      } else {
        sb.append(this.ire);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("ace:");
      if (this.ace == null) {
        sb.append("null");
      } else {
        sb.append(this.ace);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("ase:");
      if (this.ase == null) {
        sb.append("null");
      } else {
        sb.append(this.ase);
      }
      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, 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 getUnicoreJobSubmission_resultStandardSchemeFactory implements SchemeFactory {
      public getUnicoreJobSubmission_resultStandardScheme getScheme() {
        return new getUnicoreJobSubmission_resultStandardScheme();
      }
    }

    private static class getUnicoreJobSubmission_resultStandardScheme extends StandardScheme<getUnicoreJobSubmission_result> {

      public void read(org.apache.thrift.protocol.TProtocol iprot, getUnicoreJobSubmission_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.appcatalog.computeresource.UnicoreJobSubmission();
                struct.success.read(iprot);
                struct.setSuccessIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 1: // IRE
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.ire = new org.apache.airavata.model.error.InvalidRequestException();
                struct.ire.read(iprot);
                struct.setIreIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 2: // ACE
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.ace = new org.apache.airavata.model.error.AiravataClientException();
                struct.ace.read(iprot);
                struct.setAceIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 3: // ASE
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.ase = new org.apache.airavata.model.error.AiravataSystemException();
                struct.ase.read(iprot);
                struct.setAseIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 4: // 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, getUnicoreJobSubmission_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.ire != null) {
          oprot.writeFieldBegin(IRE_FIELD_DESC);
          struct.ire.write(oprot);
          oprot.writeFieldEnd();
        }
        if (struct.ace != null) {
          oprot.writeFieldBegin(ACE_FIELD_DESC);
          struct.ace.write(oprot);
          oprot.writeFieldEnd();
        }
        if (struct.ase != null) {
          oprot.writeFieldBegin(ASE_FIELD_DESC);
          struct.ase.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 getUnicoreJobSubmission_resultTupleSchemeFactory implements SchemeFactory {
      public getUnicoreJobSubmission_resultTupleScheme getScheme() {
        return new getUnicoreJobSubmission_resultTupleScheme();
      }
    }

    private static class getUnicoreJobSubmission_resultTupleScheme extends TupleScheme<getUnicoreJobSubmission_result> {

      @Override
      public void write(org.apache.thrift.protocol.TProtocol prot, getUnicoreJobSubmission_result struct) throws org.apache.thrift.TException {
        TTupleProtocol oprot = (TTupleProtocol) prot;
        BitSet optionals = new BitSet();
        if (struct.isSetSuccess()) {
          optionals.set(0);
        }
        if (struct.isSetIre()) {
          optionals.set(1);
        }
        if (struct.isSetAce()) {
          optionals.set(2);
        }
        if (struct.isSetAse()) {
          optionals.set(3);
        }
        if (struct.isSetAe()) {
          optionals.set(4);
        }
        oprot.writeBitSet(optionals, 5);
        if (struct.isSetSuccess()) {
          struct.success.write(oprot);
        }
        if (struct.isSetIre()) {
          struct.ire.write(oprot);
        }
        if (struct.isSetAce()) {
          struct.ace.write(oprot);
        }
        if (struct.isSetAse()) {
          struct.ase.write(oprot);
        }
        if (struct.isSetAe()) {
          struct.ae.write(oprot);
        }
      }

      @Override
      public void read(org.apache.thrift.protocol.TProtocol prot, getUnicoreJobSubmission_result struct) throws org.apache.thrift.TException {
        TTupleProtocol iprot = (TTupleProtocol) prot;
        BitSet incoming = iprot.readBitSet(5);
        if (incoming.get(0)) {
          struct.success = new org.apache.airavata.model.appcatalog.computeresource.UnicoreJobSubmission();
          struct.success.read(iprot);
          struct.setSuccessIsSet(true);
        }
        if (incoming.get(1)) {
          struct.ire = new org.apache.airavata.model.error.InvalidRequestException();
          struct.ire.read(iprot);
          struct.setIreIsSet(true);
        }
        if (incoming.get(2)) {
          struct.ace = new org.apache.airavata.model.error.AiravataClientException();
          struct.ace.read(iprot);
          struct.setAceIsSet(true);
        }
        if (incoming.get(3)) {
          struct.ase = new org.apache.airavata.model.error.AiravataSystemException();
          struct.ase.read(iprot);
          struct.setAseIsSet(true);
        }
        if (incoming.get(4)) {
          struct.ae = new org.apache.airavata.model.error.AuthorizationException();
          struct.ae.read(iprot);
          struct.setAeIsSet(true);
        }
      }
    }

  }

  public static class addCloudJobSubmissionDetails_args implements org.apache.thrift.TBase<addCloudJobSubmissionDetails_args, addCloudJobSubmissionDetails_args._Fields>, java.io.Serializable, Cloneable, Comparable<addCloudJobSubmissionDetails_args>   {
    private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("addCloudJobSubmissionDetails_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 COMPUTE_RESOURCE_ID_FIELD_DESC = new org.apache.thrift.protocol.TField("computeResourceId", org.apache.thrift.protocol.TType.STRING, (short)2);
    private static final org.apache.thrift.protocol.TField PRIORITY_ORDER_FIELD_DESC = new org.apache.thrift.protocol.TField("priorityOrder", org.apache.thrift.protocol.TType.I32, (short)3);
    private static final org.apache.thrift.protocol.TField CLOUD_SUBMISSION_FIELD_DESC = new org.apache.thrift.protocol.TField("cloudSubmission", org.apache.thrift.protocol.TType.STRUCT, (short)4);

    private static final Map<Class<? extends IScheme>, SchemeFactory> schemes = new HashMap<Class<? extends IScheme>, SchemeFactory>();
    static {
      schemes.put(StandardScheme.class, new addCloudJobSubmissionDetails_argsStandardSchemeFactory());
      schemes.put(TupleScheme.class, new addCloudJobSubmissionDetails_argsTupleSchemeFactory());
    }

    public org.apache.airavata.model.security.AuthzToken authzToken; // required
    public String computeResourceId; // required
    public int priorityOrder; // required
    public org.apache.airavata.model.appcatalog.computeresource.CloudJobSubmission cloudSubmission; // required

    /** 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"),
      COMPUTE_RESOURCE_ID((short)2, "computeResourceId"),
      PRIORITY_ORDER((short)3, "priorityOrder"),
      CLOUD_SUBMISSION((short)4, "cloudSubmission");

      private static final Map<String, _Fields> byName = new HashMap<String, _Fields>();

      static {
        for (_Fields field : EnumSet.allOf(_Fields.class)) {
          byName.put(field.getFieldName(), field);
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, or null if its not found.
       */
      public static _Fields findByThriftId(int fieldId) {
        switch(fieldId) {
          case 1: // AUTHZ_TOKEN
            return AUTHZ_TOKEN;
          case 2: // COMPUTE_RESOURCE_ID
            return COMPUTE_RESOURCE_ID;
          case 3: // PRIORITY_ORDER
            return PRIORITY_ORDER;
          case 4: // CLOUD_SUBMISSION
            return CLOUD_SUBMISSION;
          default:
            return null;
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, throwing an exception
       * if it is not found.
       */
      public static _Fields findByThriftIdOrThrow(int fieldId) {
        _Fields fields = findByThriftId(fieldId);
        if (fields == null) throw new IllegalArgumentException("Field " + fieldId + " doesn't exist!");
        return fields;
      }

      /**
       * Find the _Fields constant that matches name, or null if its not found.
       */
      public static _Fields findByName(String name) {
        return byName.get(name);
      }

      private final short _thriftId;
      private final String _fieldName;

      _Fields(short thriftId, String fieldName) {
        _thriftId = thriftId;
        _fieldName = fieldName;
      }

      public short getThriftFieldId() {
        return _thriftId;
      }

      public String getFieldName() {
        return _fieldName;
      }
    }

    // isset id assignments
    private static final int __PRIORITYORDER_ISSET_ID = 0;
    private byte __isset_bitfield = 0;
    public static final Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
    static {
      Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new EnumMap<_Fields, org.apache.thrift.meta_data.FieldMetaData>(_Fields.class);
      tmpMap.put(_Fields.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.COMPUTE_RESOURCE_ID, new org.apache.thrift.meta_data.FieldMetaData("computeResourceId", org.apache.thrift.TFieldRequirementType.REQUIRED, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING)));
      tmpMap.put(_Fields.PRIORITY_ORDER, new org.apache.thrift.meta_data.FieldMetaData("priorityOrder", org.apache.thrift.TFieldRequirementType.REQUIRED, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.I32)));
      tmpMap.put(_Fields.CLOUD_SUBMISSION, new org.apache.thrift.meta_data.FieldMetaData("cloudSubmission", org.apache.thrift.TFieldRequirementType.REQUIRED, 
          new org.apache.thrift.meta_data.StructMetaData(org.apache.thrift.protocol.TType.STRUCT, org.apache.airavata.model.appcatalog.computeresource.CloudJobSubmission.class)));
      metaDataMap = Collections.unmodifiableMap(tmpMap);
      org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(addCloudJobSubmissionDetails_args.class, metaDataMap);
    }

    public addCloudJobSubmissionDetails_args() {
    }

    public addCloudJobSubmissionDetails_args(
      org.apache.airavata.model.security.AuthzToken authzToken,
      String computeResourceId,
      int priorityOrder,
      org.apache.airavata.model.appcatalog.computeresource.CloudJobSubmission cloudSubmission)
    {
      this();
      this.authzToken = authzToken;
      this.computeResourceId = computeResourceId;
      this.priorityOrder = priorityOrder;
      setPriorityOrderIsSet(true);
      this.cloudSubmission = cloudSubmission;
    }

    /**
     * Performs a deep copy on <i>other</i>.
     */
    public addCloudJobSubmissionDetails_args(addCloudJobSubmissionDetails_args other) {
      __isset_bitfield = other.__isset_bitfield;
      if (other.isSetAuthzToken()) {
        this.authzToken = new org.apache.airavata.model.security.AuthzToken(other.authzToken);
      }
      if (other.isSetComputeResourceId()) {
        this.computeResourceId = other.computeResourceId;
      }
      this.priorityOrder = other.priorityOrder;
      if (other.isSetCloudSubmission()) {
        this.cloudSubmission = new org.apache.airavata.model.appcatalog.computeresource.CloudJobSubmission(other.cloudSubmission);
      }
    }

    public addCloudJobSubmissionDetails_args deepCopy() {
      return new addCloudJobSubmissionDetails_args(this);
    }

    @Override
    public void clear() {
      this.authzToken = null;
      this.computeResourceId = null;
      setPriorityOrderIsSet(false);
      this.priorityOrder = 0;
      this.cloudSubmission = null;
    }

    public org.apache.airavata.model.security.AuthzToken getAuthzToken() {
      return this.authzToken;
    }

    public addCloudJobSubmissionDetails_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 String getComputeResourceId() {
      return this.computeResourceId;
    }

    public addCloudJobSubmissionDetails_args setComputeResourceId(String computeResourceId) {
      this.computeResourceId = computeResourceId;
      return this;
    }

    public void unsetComputeResourceId() {
      this.computeResourceId = null;
    }

    /** Returns true if field computeResourceId is set (has been assigned a value) and false otherwise */
    public boolean isSetComputeResourceId() {
      return this.computeResourceId != null;
    }

    public void setComputeResourceIdIsSet(boolean value) {
      if (!value) {
        this.computeResourceId = null;
      }
    }

    public int getPriorityOrder() {
      return this.priorityOrder;
    }

    public addCloudJobSubmissionDetails_args setPriorityOrder(int priorityOrder) {
      this.priorityOrder = priorityOrder;
      setPriorityOrderIsSet(true);
      return this;
    }

    public void unsetPriorityOrder() {
      __isset_bitfield = EncodingUtils.clearBit(__isset_bitfield, __PRIORITYORDER_ISSET_ID);
    }

    /** Returns true if field priorityOrder is set (has been assigned a value) and false otherwise */
    public boolean isSetPriorityOrder() {
      return EncodingUtils.testBit(__isset_bitfield, __PRIORITYORDER_ISSET_ID);
    }

    public void setPriorityOrderIsSet(boolean value) {
      __isset_bitfield = EncodingUtils.setBit(__isset_bitfield, __PRIORITYORDER_ISSET_ID, value);
    }

    public org.apache.airavata.model.appcatalog.computeresource.CloudJobSubmission getCloudSubmission() {
      return this.cloudSubmission;
    }

    public addCloudJobSubmissionDetails_args setCloudSubmission(org.apache.airavata.model.appcatalog.computeresource.CloudJobSubmission cloudSubmission) {
      this.cloudSubmission = cloudSubmission;
      return this;
    }

    public void unsetCloudSubmission() {
      this.cloudSubmission = null;
    }

    /** Returns true if field cloudSubmission is set (has been assigned a value) and false otherwise */
    public boolean isSetCloudSubmission() {
      return this.cloudSubmission != null;
    }

    public void setCloudSubmissionIsSet(boolean value) {
      if (!value) {
        this.cloudSubmission = null;
      }
    }

    public void setFieldValue(_Fields field, Object value) {
      switch (field) {
      case AUTHZ_TOKEN:
        if (value == null) {
          unsetAuthzToken();
        } else {
          setAuthzToken((org.apache.airavata.model.security.AuthzToken)value);
        }
        break;

      case COMPUTE_RESOURCE_ID:
        if (value == null) {
          unsetComputeResourceId();
        } else {
          setComputeResourceId((String)value);
        }
        break;

      case PRIORITY_ORDER:
        if (value == null) {
          unsetPriorityOrder();
        } else {
          setPriorityOrder((Integer)value);
        }
        break;

      case CLOUD_SUBMISSION:
        if (value == null) {
          unsetCloudSubmission();
        } else {
          setCloudSubmission((org.apache.airavata.model.appcatalog.computeresource.CloudJobSubmission)value);
        }
        break;

      }
    }

    public Object getFieldValue(_Fields field) {
      switch (field) {
      case AUTHZ_TOKEN:
        return getAuthzToken();

      case COMPUTE_RESOURCE_ID:
        return getComputeResourceId();

      case PRIORITY_ORDER:
        return Integer.valueOf(getPriorityOrder());

      case CLOUD_SUBMISSION:
        return getCloudSubmission();

      }
      throw new IllegalStateException();
    }

    /** Returns true if field corresponding to fieldID is set (has been assigned a value) and false otherwise */
    public boolean isSet(_Fields field) {
      if (field == null) {
        throw new IllegalArgumentException();
      }

      switch (field) {
      case AUTHZ_TOKEN:
        return isSetAuthzToken();
      case COMPUTE_RESOURCE_ID:
        return isSetComputeResourceId();
      case PRIORITY_ORDER:
        return isSetPriorityOrder();
      case CLOUD_SUBMISSION:
        return isSetCloudSubmission();
      }
      throw new IllegalStateException();
    }

    @Override
    public boolean equals(Object that) {
      if (that == null)
        return false;
      if (that instanceof addCloudJobSubmissionDetails_args)
        return this.equals((addCloudJobSubmissionDetails_args)that);
      return false;
    }

    public boolean equals(addCloudJobSubmissionDetails_args that) {
      if (that == null)
        return false;

      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_computeResourceId = true && this.isSetComputeResourceId();
      boolean that_present_computeResourceId = true && that.isSetComputeResourceId();
      if (this_present_computeResourceId || that_present_computeResourceId) {
        if (!(this_present_computeResourceId && that_present_computeResourceId))
          return false;
        if (!this.computeResourceId.equals(that.computeResourceId))
          return false;
      }

      boolean this_present_priorityOrder = true;
      boolean that_present_priorityOrder = true;
      if (this_present_priorityOrder || that_present_priorityOrder) {
        if (!(this_present_priorityOrder && that_present_priorityOrder))
          return false;
        if (this.priorityOrder != that.priorityOrder)
          return false;
      }

      boolean this_present_cloudSubmission = true && this.isSetCloudSubmission();
      boolean that_present_cloudSubmission = true && that.isSetCloudSubmission();
      if (this_present_cloudSubmission || that_present_cloudSubmission) {
        if (!(this_present_cloudSubmission && that_present_cloudSubmission))
          return false;
        if (!this.cloudSubmission.equals(that.cloudSubmission))
          return false;
      }

      return true;
    }

    @Override
    public int hashCode() {
      List<Object> list = new ArrayList<Object>();

      boolean present_authzToken = true && (isSetAuthzToken());
      list.add(present_authzToken);
      if (present_authzToken)
        list.add(authzToken);

      boolean present_computeResourceId = true && (isSetComputeResourceId());
      list.add(present_computeResourceId);
      if (present_computeResourceId)
        list.add(computeResourceId);

      boolean present_priorityOrder = true;
      list.add(present_priorityOrder);
      if (present_priorityOrder)
        list.add(priorityOrder);

      boolean present_cloudSubmission = true && (isSetCloudSubmission());
      list.add(present_cloudSubmission);
      if (present_cloudSubmission)
        list.add(cloudSubmission);

      return list.hashCode();
    }

    @Override
    public int compareTo(addCloudJobSubmissionDetails_args other) {
      if (!getClass().equals(other.getClass())) {
        return getClass().getName().compareTo(other.getClass().getName());
      }

      int lastComparison = 0;

      lastComparison = 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 = Boolean.valueOf(isSetComputeResourceId()).compareTo(other.isSetComputeResourceId());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetComputeResourceId()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.computeResourceId, other.computeResourceId);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = Boolean.valueOf(isSetPriorityOrder()).compareTo(other.isSetPriorityOrder());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetPriorityOrder()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.priorityOrder, other.priorityOrder);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = Boolean.valueOf(isSetCloudSubmission()).compareTo(other.isSetCloudSubmission());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetCloudSubmission()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.cloudSubmission, other.cloudSubmission);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      return 0;
    }

    public _Fields fieldForId(int fieldId) {
      return _Fields.findByThriftId(fieldId);
    }

    public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
      schemes.get(iprot.getScheme()).getScheme().read(iprot, this);
    }

    public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException {
      schemes.get(oprot.getScheme()).getScheme().write(oprot, this);
    }

    @Override
    public String toString() {
      StringBuilder sb = new StringBuilder("addCloudJobSubmissionDetails_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("computeResourceId:");
      if (this.computeResourceId == null) {
        sb.append("null");
      } else {
        sb.append(this.computeResourceId);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("priorityOrder:");
      sb.append(this.priorityOrder);
      first = false;
      if (!first) sb.append(", ");
      sb.append("cloudSubmission:");
      if (this.cloudSubmission == null) {
        sb.append("null");
      } else {
        sb.append(this.cloudSubmission);
      }
      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 (computeResourceId == null) {
        throw new org.apache.thrift.protocol.TProtocolException("Required field 'computeResourceId' was not present! Struct: " + toString());
      }
      // alas, we cannot check 'priorityOrder' because it's a primitive and you chose the non-beans generator.
      if (cloudSubmission == null) {
        throw new org.apache.thrift.protocol.TProtocolException("Required field 'cloudSubmission' was not present! Struct: " + toString());
      }
      // check for sub-struct validity
      if (authzToken != null) {
        authzToken.validate();
      }
      if (cloudSubmission != null) {
        cloudSubmission.validate();
      }
    }

    private void writeObject(java.io.ObjectOutputStream out) throws java.io.IOException {
      try {
        write(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(out)));
      } catch (org.apache.thrift.TException te) {
        throw new java.io.IOException(te);
      }
    }

    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, ClassNotFoundException {
      try {
        // 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 addCloudJobSubmissionDetails_argsStandardSchemeFactory implements SchemeFactory {
      public addCloudJobSubmissionDetails_argsStandardScheme getScheme() {
        return new addCloudJobSubmissionDetails_argsStandardScheme();
      }
    }

    private static class addCloudJobSubmissionDetails_argsStandardScheme extends StandardScheme<addCloudJobSubmissionDetails_args> {

      public void read(org.apache.thrift.protocol.TProtocol iprot, addCloudJobSubmissionDetails_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: // COMPUTE_RESOURCE_ID
              if (schemeField.type == org.apache.thrift.protocol.TType.STRING) {
                struct.computeResourceId = iprot.readString();
                struct.setComputeResourceIdIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 3: // PRIORITY_ORDER
              if (schemeField.type == org.apache.thrift.protocol.TType.I32) {
                struct.priorityOrder = iprot.readI32();
                struct.setPriorityOrderIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 4: // CLOUD_SUBMISSION
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.cloudSubmission = new org.apache.airavata.model.appcatalog.computeresource.CloudJobSubmission();
                struct.cloudSubmission.read(iprot);
                struct.setCloudSubmissionIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            default:
              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
          }
          iprot.readFieldEnd();
        }
        iprot.readStructEnd();

        // check for required fields of primitive type, which can't be checked in the validate method
        if (!struct.isSetPriorityOrder()) {
          throw new org.apache.thrift.protocol.TProtocolException("Required field 'priorityOrder' was not found in serialized data! Struct: " + toString());
        }
        struct.validate();
      }

      public void write(org.apache.thrift.protocol.TProtocol oprot, addCloudJobSubmissionDetails_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.computeResourceId != null) {
          oprot.writeFieldBegin(COMPUTE_RESOURCE_ID_FIELD_DESC);
          oprot.writeString(struct.computeResourceId);
          oprot.writeFieldEnd();
        }
        oprot.writeFieldBegin(PRIORITY_ORDER_FIELD_DESC);
        oprot.writeI32(struct.priorityOrder);
        oprot.writeFieldEnd();
        if (struct.cloudSubmission != null) {
          oprot.writeFieldBegin(CLOUD_SUBMISSION_FIELD_DESC);
          struct.cloudSubmission.write(oprot);
          oprot.writeFieldEnd();
        }
        oprot.writeFieldStop();
        oprot.writeStructEnd();
      }

    }

    private static class addCloudJobSubmissionDetails_argsTupleSchemeFactory implements SchemeFactory {
      public addCloudJobSubmissionDetails_argsTupleScheme getScheme() {
        return new addCloudJobSubmissionDetails_argsTupleScheme();
      }
    }

    private static class addCloudJobSubmissionDetails_argsTupleScheme extends TupleScheme<addCloudJobSubmissionDetails_args> {

      @Override
      public void write(org.apache.thrift.protocol.TProtocol prot, addCloudJobSubmissionDetails_args struct) throws org.apache.thrift.TException {
        TTupleProtocol oprot = (TTupleProtocol) prot;
        struct.authzToken.write(oprot);
        oprot.writeString(struct.computeResourceId);
        oprot.writeI32(struct.priorityOrder);
        struct.cloudSubmission.write(oprot);
      }

      @Override
      public void read(org.apache.thrift.protocol.TProtocol prot, addCloudJobSubmissionDetails_args struct) throws org.apache.thrift.TException {
        TTupleProtocol iprot = (TTupleProtocol) prot;
        struct.authzToken = new org.apache.airavata.model.security.AuthzToken();
        struct.authzToken.read(iprot);
        struct.setAuthzTokenIsSet(true);
        struct.computeResourceId = iprot.readString();
        struct.setComputeResourceIdIsSet(true);
        struct.priorityOrder = iprot.readI32();
        struct.setPriorityOrderIsSet(true);
        struct.cloudSubmission = new org.apache.airavata.model.appcatalog.computeresource.CloudJobSubmission();
        struct.cloudSubmission.read(iprot);
        struct.setCloudSubmissionIsSet(true);
      }
    }

  }

  public static class addCloudJobSubmissionDetails_result implements org.apache.thrift.TBase<addCloudJobSubmissionDetails_result, addCloudJobSubmissionDetails_result._Fields>, java.io.Serializable, Cloneable, Comparable<addCloudJobSubmissionDetails_result>   {
    private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("addCloudJobSubmissionDetails_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 IRE_FIELD_DESC = new org.apache.thrift.protocol.TField("ire", org.apache.thrift.protocol.TType.STRUCT, (short)1);
    private static final org.apache.thrift.protocol.TField ACE_FIELD_DESC = new org.apache.thrift.protocol.TField("ace", org.apache.thrift.protocol.TType.STRUCT, (short)2);
    private static final org.apache.thrift.protocol.TField ASE_FIELD_DESC = new org.apache.thrift.protocol.TField("ase", org.apache.thrift.protocol.TType.STRUCT, (short)3);
    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)4);

    private static final Map<Class<? extends IScheme>, SchemeFactory> schemes = new HashMap<Class<? extends IScheme>, SchemeFactory>();
    static {
      schemes.put(StandardScheme.class, new addCloudJobSubmissionDetails_resultStandardSchemeFactory());
      schemes.put(TupleScheme.class, new addCloudJobSubmissionDetails_resultTupleSchemeFactory());
    }

    public String success; // required
    public org.apache.airavata.model.error.InvalidRequestException ire; // required
    public org.apache.airavata.model.error.AiravataClientException ace; // required
    public org.apache.airavata.model.error.AiravataSystemException ase; // 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"),
      IRE((short)1, "ire"),
      ACE((short)2, "ace"),
      ASE((short)3, "ase"),
      AE((short)4, "ae");

      private static final Map<String, _Fields> byName = new HashMap<String, _Fields>();

      static {
        for (_Fields field : EnumSet.allOf(_Fields.class)) {
          byName.put(field.getFieldName(), field);
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, or null if its not found.
       */
      public static _Fields findByThriftId(int fieldId) {
        switch(fieldId) {
          case 0: // SUCCESS
            return SUCCESS;
          case 1: // IRE
            return IRE;
          case 2: // ACE
            return ACE;
          case 3: // ASE
            return ASE;
          case 4: // 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 IllegalArgumentException("Field " + fieldId + " doesn't exist!");
        return fields;
      }

      /**
       * Find the _Fields constant that matches name, or null if its not found.
       */
      public static _Fields findByName(String name) {
        return byName.get(name);
      }

      private final short _thriftId;
      private final String _fieldName;

      _Fields(short thriftId, String fieldName) {
        _thriftId = thriftId;
        _fieldName = fieldName;
      }

      public short getThriftFieldId() {
        return _thriftId;
      }

      public String getFieldName() {
        return _fieldName;
      }
    }

    // isset id assignments
    public static final Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
    static {
      Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new EnumMap<_Fields, org.apache.thrift.meta_data.FieldMetaData>(_Fields.class);
      tmpMap.put(_Fields.SUCCESS, new org.apache.thrift.meta_data.FieldMetaData("success", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING)));
      tmpMap.put(_Fields.IRE, new org.apache.thrift.meta_data.FieldMetaData("ire", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRUCT)));
      tmpMap.put(_Fields.ACE, new org.apache.thrift.meta_data.FieldMetaData("ace", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRUCT)));
      tmpMap.put(_Fields.ASE, new org.apache.thrift.meta_data.FieldMetaData("ase", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRUCT)));
      tmpMap.put(_Fields.AE, new org.apache.thrift.meta_data.FieldMetaData("ae", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRUCT)));
      metaDataMap = Collections.unmodifiableMap(tmpMap);
      org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(addCloudJobSubmissionDetails_result.class, metaDataMap);
    }

    public addCloudJobSubmissionDetails_result() {
    }

    public addCloudJobSubmissionDetails_result(
      String success,
      org.apache.airavata.model.error.InvalidRequestException ire,
      org.apache.airavata.model.error.AiravataClientException ace,
      org.apache.airavata.model.error.AiravataSystemException ase,
      org.apache.airavata.model.error.AuthorizationException ae)
    {
      this();
      this.success = success;
      this.ire = ire;
      this.ace = ace;
      this.ase = ase;
      this.ae = ae;
    }

    /**
     * Performs a deep copy on <i>other</i>.
     */
    public addCloudJobSubmissionDetails_result(addCloudJobSubmissionDetails_result other) {
      if (other.isSetSuccess()) {
        this.success = other.success;
      }
      if (other.isSetIre()) {
        this.ire = new org.apache.airavata.model.error.InvalidRequestException(other.ire);
      }
      if (other.isSetAce()) {
        this.ace = new org.apache.airavata.model.error.AiravataClientException(other.ace);
      }
      if (other.isSetAse()) {
        this.ase = new org.apache.airavata.model.error.AiravataSystemException(other.ase);
      }
      if (other.isSetAe()) {
        this.ae = new org.apache.airavata.model.error.AuthorizationException(other.ae);
      }
    }

    public addCloudJobSubmissionDetails_result deepCopy() {
      return new addCloudJobSubmissionDetails_result(this);
    }

    @Override
    public void clear() {
      this.success = null;
      this.ire = null;
      this.ace = null;
      this.ase = null;
      this.ae = null;
    }

    public String getSuccess() {
      return this.success;
    }

    public addCloudJobSubmissionDetails_result setSuccess(String success) {
      this.success = success;
      return this;
    }

    public void unsetSuccess() {
      this.success = null;
    }

    /** Returns true if field success is set (has been assigned a value) and false otherwise */
    public boolean isSetSuccess() {
      return this.success != null;
    }

    public void setSuccessIsSet(boolean value) {
      if (!value) {
        this.success = null;
      }
    }

    public org.apache.airavata.model.error.InvalidRequestException getIre() {
      return this.ire;
    }

    public addCloudJobSubmissionDetails_result setIre(org.apache.airavata.model.error.InvalidRequestException ire) {
      this.ire = ire;
      return this;
    }

    public void unsetIre() {
      this.ire = null;
    }

    /** Returns true if field ire is set (has been assigned a value) and false otherwise */
    public boolean isSetIre() {
      return this.ire != null;
    }

    public void setIreIsSet(boolean value) {
      if (!value) {
        this.ire = null;
      }
    }

    public org.apache.airavata.model.error.AiravataClientException getAce() {
      return this.ace;
    }

    public addCloudJobSubmissionDetails_result setAce(org.apache.airavata.model.error.AiravataClientException ace) {
      this.ace = ace;
      return this;
    }

    public void unsetAce() {
      this.ace = null;
    }

    /** Returns true if field ace is set (has been assigned a value) and false otherwise */
    public boolean isSetAce() {
      return this.ace != null;
    }

    public void setAceIsSet(boolean value) {
      if (!value) {
        this.ace = null;
      }
    }

    public org.apache.airavata.model.error.AiravataSystemException getAse() {
      return this.ase;
    }

    public addCloudJobSubmissionDetails_result setAse(org.apache.airavata.model.error.AiravataSystemException ase) {
      this.ase = ase;
      return this;
    }

    public void unsetAse() {
      this.ase = null;
    }

    /** Returns true if field ase is set (has been assigned a value) and false otherwise */
    public boolean isSetAse() {
      return this.ase != null;
    }

    public void setAseIsSet(boolean value) {
      if (!value) {
        this.ase = null;
      }
    }

    public org.apache.airavata.model.error.AuthorizationException getAe() {
      return this.ae;
    }

    public addCloudJobSubmissionDetails_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, Object value) {
      switch (field) {
      case SUCCESS:
        if (value == null) {
          unsetSuccess();
        } else {
          setSuccess((String)value);
        }
        break;

      case IRE:
        if (value == null) {
          unsetIre();
        } else {
          setIre((org.apache.airavata.model.error.InvalidRequestException)value);
        }
        break;

      case ACE:
        if (value == null) {
          unsetAce();
        } else {
          setAce((org.apache.airavata.model.error.AiravataClientException)value);
        }
        break;

      case ASE:
        if (value == null) {
          unsetAse();
        } else {
          setAse((org.apache.airavata.model.error.AiravataSystemException)value);
        }
        break;

      case AE:
        if (value == null) {
          unsetAe();
        } else {
          setAe((org.apache.airavata.model.error.AuthorizationException)value);
        }
        break;

      }
    }

    public Object getFieldValue(_Fields field) {
      switch (field) {
      case SUCCESS:
        return getSuccess();

      case IRE:
        return getIre();

      case ACE:
        return getAce();

      case ASE:
        return getAse();

      case AE:
        return getAe();

      }
      throw new IllegalStateException();
    }

    /** Returns true if field corresponding to fieldID is set (has been assigned a value) and false otherwise */
    public boolean isSet(_Fields field) {
      if (field == null) {
        throw new IllegalArgumentException();
      }

      switch (field) {
      case SUCCESS:
        return isSetSuccess();
      case IRE:
        return isSetIre();
      case ACE:
        return isSetAce();
      case ASE:
        return isSetAse();
      case AE:
        return isSetAe();
      }
      throw new IllegalStateException();
    }

    @Override
    public boolean equals(Object that) {
      if (that == null)
        return false;
      if (that instanceof addCloudJobSubmissionDetails_result)
        return this.equals((addCloudJobSubmissionDetails_result)that);
      return false;
    }

    public boolean equals(addCloudJobSubmissionDetails_result that) {
      if (that == null)
        return false;

      boolean this_present_success = true && this.isSetSuccess();
      boolean that_present_success = true && that.isSetSuccess();
      if (this_present_success || that_present_success) {
        if (!(this_present_success && that_present_success))
          return false;
        if (!this.success.equals(that.success))
          return false;
      }

      boolean this_present_ire = true && this.isSetIre();
      boolean that_present_ire = true && that.isSetIre();
      if (this_present_ire || that_present_ire) {
        if (!(this_present_ire && that_present_ire))
          return false;
        if (!this.ire.equals(that.ire))
          return false;
      }

      boolean this_present_ace = true && this.isSetAce();
      boolean that_present_ace = true && that.isSetAce();
      if (this_present_ace || that_present_ace) {
        if (!(this_present_ace && that_present_ace))
          return false;
        if (!this.ace.equals(that.ace))
          return false;
      }

      boolean this_present_ase = true && this.isSetAse();
      boolean that_present_ase = true && that.isSetAse();
      if (this_present_ase || that_present_ase) {
        if (!(this_present_ase && that_present_ase))
          return false;
        if (!this.ase.equals(that.ase))
          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() {
      List<Object> list = new ArrayList<Object>();

      boolean present_success = true && (isSetSuccess());
      list.add(present_success);
      if (present_success)
        list.add(success);

      boolean present_ire = true && (isSetIre());
      list.add(present_ire);
      if (present_ire)
        list.add(ire);

      boolean present_ace = true && (isSetAce());
      list.add(present_ace);
      if (present_ace)
        list.add(ace);

      boolean present_ase = true && (isSetAse());
      list.add(present_ase);
      if (present_ase)
        list.add(ase);

      boolean present_ae = true && (isSetAe());
      list.add(present_ae);
      if (present_ae)
        list.add(ae);

      return list.hashCode();
    }

    @Override
    public int compareTo(addCloudJobSubmissionDetails_result other) {
      if (!getClass().equals(other.getClass())) {
        return getClass().getName().compareTo(other.getClass().getName());
      }

      int lastComparison = 0;

      lastComparison = Boolean.valueOf(isSetSuccess()).compareTo(other.isSetSuccess());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetSuccess()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.success, other.success);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = Boolean.valueOf(isSetIre()).compareTo(other.isSetIre());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetIre()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.ire, other.ire);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = Boolean.valueOf(isSetAce()).compareTo(other.isSetAce());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetAce()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.ace, other.ace);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = Boolean.valueOf(isSetAse()).compareTo(other.isSetAse());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetAse()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.ase, other.ase);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = 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 {
      schemes.get(iprot.getScheme()).getScheme().read(iprot, this);
    }

    public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException {
      schemes.get(oprot.getScheme()).getScheme().write(oprot, this);
      }

    @Override
    public String toString() {
      StringBuilder sb = new StringBuilder("addCloudJobSubmissionDetails_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("ire:");
      if (this.ire == null) {
        sb.append("null");
      } else {
        sb.append(this.ire);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("ace:");
      if (this.ace == null) {
        sb.append("null");
      } else {
        sb.append(this.ace);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("ase:");
      if (this.ase == null) {
        sb.append("null");
      } else {
        sb.append(this.ase);
      }
      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, 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 addCloudJobSubmissionDetails_resultStandardSchemeFactory implements SchemeFactory {
      public addCloudJobSubmissionDetails_resultStandardScheme getScheme() {
        return new addCloudJobSubmissionDetails_resultStandardScheme();
      }
    }

    private static class addCloudJobSubmissionDetails_resultStandardScheme extends StandardScheme<addCloudJobSubmissionDetails_result> {

      public void read(org.apache.thrift.protocol.TProtocol iprot, addCloudJobSubmissionDetails_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: // IRE
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.ire = new org.apache.airavata.model.error.InvalidRequestException();
                struct.ire.read(iprot);
                struct.setIreIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 2: // ACE
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.ace = new org.apache.airavata.model.error.AiravataClientException();
                struct.ace.read(iprot);
                struct.setAceIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 3: // ASE
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.ase = new org.apache.airavata.model.error.AiravataSystemException();
                struct.ase.read(iprot);
                struct.setAseIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 4: // 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, addCloudJobSubmissionDetails_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.ire != null) {
          oprot.writeFieldBegin(IRE_FIELD_DESC);
          struct.ire.write(oprot);
          oprot.writeFieldEnd();
        }
        if (struct.ace != null) {
          oprot.writeFieldBegin(ACE_FIELD_DESC);
          struct.ace.write(oprot);
          oprot.writeFieldEnd();
        }
        if (struct.ase != null) {
          oprot.writeFieldBegin(ASE_FIELD_DESC);
          struct.ase.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 addCloudJobSubmissionDetails_resultTupleSchemeFactory implements SchemeFactory {
      public addCloudJobSubmissionDetails_resultTupleScheme getScheme() {
        return new addCloudJobSubmissionDetails_resultTupleScheme();
      }
    }

    private static class addCloudJobSubmissionDetails_resultTupleScheme extends TupleScheme<addCloudJobSubmissionDetails_result> {

      @Override
      public void write(org.apache.thrift.protocol.TProtocol prot, addCloudJobSubmissionDetails_result struct) throws org.apache.thrift.TException {
        TTupleProtocol oprot = (TTupleProtocol) prot;
        BitSet optionals = new BitSet();
        if (struct.isSetSuccess()) {
          optionals.set(0);
        }
        if (struct.isSetIre()) {
          optionals.set(1);
        }
        if (struct.isSetAce()) {
          optionals.set(2);
        }
        if (struct.isSetAse()) {
          optionals.set(3);
        }
        if (struct.isSetAe()) {
          optionals.set(4);
        }
        oprot.writeBitSet(optionals, 5);
        if (struct.isSetSuccess()) {
          oprot.writeString(struct.success);
        }
        if (struct.isSetIre()) {
          struct.ire.write(oprot);
        }
        if (struct.isSetAce()) {
          struct.ace.write(oprot);
        }
        if (struct.isSetAse()) {
          struct.ase.write(oprot);
        }
        if (struct.isSetAe()) {
          struct.ae.write(oprot);
        }
      }

      @Override
      public void read(org.apache.thrift.protocol.TProtocol prot, addCloudJobSubmissionDetails_result struct) throws org.apache.thrift.TException {
        TTupleProtocol iprot = (TTupleProtocol) prot;
        BitSet incoming = iprot.readBitSet(5);
        if (incoming.get(0)) {
          struct.success = iprot.readString();
          struct.setSuccessIsSet(true);
        }
        if (incoming.get(1)) {
          struct.ire = new org.apache.airavata.model.error.InvalidRequestException();
          struct.ire.read(iprot);
          struct.setIreIsSet(true);
        }
        if (incoming.get(2)) {
          struct.ace = new org.apache.airavata.model.error.AiravataClientException();
          struct.ace.read(iprot);
          struct.setAceIsSet(true);
        }
        if (incoming.get(3)) {
          struct.ase = new org.apache.airavata.model.error.AiravataSystemException();
          struct.ase.read(iprot);
          struct.setAseIsSet(true);
        }
        if (incoming.get(4)) {
          struct.ae = new org.apache.airavata.model.error.AuthorizationException();
          struct.ae.read(iprot);
          struct.setAeIsSet(true);
        }
      }
    }

  }

  public static class getCloudJobSubmission_args implements org.apache.thrift.TBase<getCloudJobSubmission_args, getCloudJobSubmission_args._Fields>, java.io.Serializable, Cloneable, Comparable<getCloudJobSubmission_args>   {
    private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("getCloudJobSubmission_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 JOB_SUBMISSION_ID_FIELD_DESC = new org.apache.thrift.protocol.TField("jobSubmissionId", org.apache.thrift.protocol.TType.STRING, (short)2);

    private static final Map<Class<? extends IScheme>, SchemeFactory> schemes = new HashMap<Class<? extends IScheme>, SchemeFactory>();
    static {
      schemes.put(StandardScheme.class, new getCloudJobSubmission_argsStandardSchemeFactory());
      schemes.put(TupleScheme.class, new getCloudJobSubmission_argsTupleSchemeFactory());
    }

    public org.apache.airavata.model.security.AuthzToken authzToken; // required
    public String jobSubmissionId; // required

    /** 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"),
      JOB_SUBMISSION_ID((short)2, "jobSubmissionId");

      private static final Map<String, _Fields> byName = new HashMap<String, _Fields>();

      static {
        for (_Fields field : EnumSet.allOf(_Fields.class)) {
          byName.put(field.getFieldName(), field);
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, or null if its not found.
       */
      public static _Fields findByThriftId(int fieldId) {
        switch(fieldId) {
          case 1: // AUTHZ_TOKEN
            return AUTHZ_TOKEN;
          case 2: // JOB_SUBMISSION_ID
            return JOB_SUBMISSION_ID;
          default:
            return null;
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, throwing an exception
       * if it is not found.
       */
      public static _Fields findByThriftIdOrThrow(int fieldId) {
        _Fields fields = findByThriftId(fieldId);
        if (fields == null) throw new IllegalArgumentException("Field " + fieldId + " doesn't exist!");
        return fields;
      }

      /**
       * Find the _Fields constant that matches name, or null if its not found.
       */
      public static _Fields findByName(String name) {
        return byName.get(name);
      }

      private final short _thriftId;
      private final String _fieldName;

      _Fields(short thriftId, String fieldName) {
        _thriftId = thriftId;
        _fieldName = fieldName;
      }

      public short getThriftFieldId() {
        return _thriftId;
      }

      public String getFieldName() {
        return _fieldName;
      }
    }

    // isset id assignments
    public static final Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
    static {
      Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new EnumMap<_Fields, org.apache.thrift.meta_data.FieldMetaData>(_Fields.class);
      tmpMap.put(_Fields.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.JOB_SUBMISSION_ID, new org.apache.thrift.meta_data.FieldMetaData("jobSubmissionId", org.apache.thrift.TFieldRequirementType.REQUIRED, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING)));
      metaDataMap = Collections.unmodifiableMap(tmpMap);
      org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(getCloudJobSubmission_args.class, metaDataMap);
    }

    public getCloudJobSubmission_args() {
    }

    public getCloudJobSubmission_args(
      org.apache.airavata.model.security.AuthzToken authzToken,
      String jobSubmissionId)
    {
      this();
      this.authzToken = authzToken;
      this.jobSubmissionId = jobSubmissionId;
    }

    /**
     * Performs a deep copy on <i>other</i>.
     */
    public getCloudJobSubmission_args(getCloudJobSubmission_args other) {
      if (other.isSetAuthzToken()) {
        this.authzToken = new org.apache.airavata.model.security.AuthzToken(other.authzToken);
      }
      if (other.isSetJobSubmissionId()) {
        this.jobSubmissionId = other.jobSubmissionId;
      }
    }

    public getCloudJobSubmission_args deepCopy() {
      return new getCloudJobSubmission_args(this);
    }

    @Override
    public void clear() {
      this.authzToken = null;
      this.jobSubmissionId = null;
    }

    public org.apache.airavata.model.security.AuthzToken getAuthzToken() {
      return this.authzToken;
    }

    public getCloudJobSubmission_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 String getJobSubmissionId() {
      return this.jobSubmissionId;
    }

    public getCloudJobSubmission_args setJobSubmissionId(String jobSubmissionId) {
      this.jobSubmissionId = jobSubmissionId;
      return this;
    }

    public void unsetJobSubmissionId() {
      this.jobSubmissionId = null;
    }

    /** Returns true if field jobSubmissionId is set (has been assigned a value) and false otherwise */
    public boolean isSetJobSubmissionId() {
      return this.jobSubmissionId != null;
    }

    public void setJobSubmissionIdIsSet(boolean value) {
      if (!value) {
        this.jobSubmissionId = null;
      }
    }

    public void setFieldValue(_Fields field, Object value) {
      switch (field) {
      case AUTHZ_TOKEN:
        if (value == null) {
          unsetAuthzToken();
        } else {
          setAuthzToken((org.apache.airavata.model.security.AuthzToken)value);
        }
        break;

      case JOB_SUBMISSION_ID:
        if (value == null) {
          unsetJobSubmissionId();
        } else {
          setJobSubmissionId((String)value);
        }
        break;

      }
    }

    public Object getFieldValue(_Fields field) {
      switch (field) {
      case AUTHZ_TOKEN:
        return getAuthzToken();

      case JOB_SUBMISSION_ID:
        return getJobSubmissionId();

      }
      throw new IllegalStateException();
    }

    /** Returns true if field corresponding to fieldID is set (has been assigned a value) and false otherwise */
    public boolean isSet(_Fields field) {
      if (field == null) {
        throw new IllegalArgumentException();
      }

      switch (field) {
      case AUTHZ_TOKEN:
        return isSetAuthzToken();
      case JOB_SUBMISSION_ID:
        return isSetJobSubmissionId();
      }
      throw new IllegalStateException();
    }

    @Override
    public boolean equals(Object that) {
      if (that == null)
        return false;
      if (that instanceof getCloudJobSubmission_args)
        return this.equals((getCloudJobSubmission_args)that);
      return false;
    }

    public boolean equals(getCloudJobSubmission_args that) {
      if (that == null)
        return false;

      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_jobSubmissionId = true && this.isSetJobSubmissionId();
      boolean that_present_jobSubmissionId = true && that.isSetJobSubmissionId();
      if (this_present_jobSubmissionId || that_present_jobSubmissionId) {
        if (!(this_present_jobSubmissionId && that_present_jobSubmissionId))
          return false;
        if (!this.jobSubmissionId.equals(that.jobSubmissionId))
          return false;
      }

      return true;
    }

    @Override
    public int hashCode() {
      List<Object> list = new ArrayList<Object>();

      boolean present_authzToken = true && (isSetAuthzToken());
      list.add(present_authzToken);
      if (present_authzToken)
        list.add(authzToken);

      boolean present_jobSubmissionId = true && (isSetJobSubmissionId());
      list.add(present_jobSubmissionId);
      if (present_jobSubmissionId)
        list.add(jobSubmissionId);

      return list.hashCode();
    }

    @Override
    public int compareTo(getCloudJobSubmission_args other) {
      if (!getClass().equals(other.getClass())) {
        return getClass().getName().compareTo(other.getClass().getName());
      }

      int lastComparison = 0;

      lastComparison = 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 = Boolean.valueOf(isSetJobSubmissionId()).compareTo(other.isSetJobSubmissionId());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetJobSubmissionId()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.jobSubmissionId, other.jobSubmissionId);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      return 0;
    }

    public _Fields fieldForId(int fieldId) {
      return _Fields.findByThriftId(fieldId);
    }

    public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
      schemes.get(iprot.getScheme()).getScheme().read(iprot, this);
    }

    public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException {
      schemes.get(oprot.getScheme()).getScheme().write(oprot, this);
    }

    @Override
    public String toString() {
      StringBuilder sb = new StringBuilder("getCloudJobSubmission_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("jobSubmissionId:");
      if (this.jobSubmissionId == null) {
        sb.append("null");
      } else {
        sb.append(this.jobSubmissionId);
      }
      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 (jobSubmissionId == null) {
        throw new org.apache.thrift.protocol.TProtocolException("Required field 'jobSubmissionId' 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, 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 getCloudJobSubmission_argsStandardSchemeFactory implements SchemeFactory {
      public getCloudJobSubmission_argsStandardScheme getScheme() {
        return new getCloudJobSubmission_argsStandardScheme();
      }
    }

    private static class getCloudJobSubmission_argsStandardScheme extends StandardScheme<getCloudJobSubmission_args> {

      public void read(org.apache.thrift.protocol.TProtocol iprot, getCloudJobSubmission_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: // JOB_SUBMISSION_ID
              if (schemeField.type == org.apache.thrift.protocol.TType.STRING) {
                struct.jobSubmissionId = iprot.readString();
                struct.setJobSubmissionIdIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            default:
              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
          }
          iprot.readFieldEnd();
        }
        iprot.readStructEnd();

        // check for required fields of primitive type, which can't be checked in the validate method
        struct.validate();
      }

      public void write(org.apache.thrift.protocol.TProtocol oprot, getCloudJobSubmission_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.jobSubmissionId != null) {
          oprot.writeFieldBegin(JOB_SUBMISSION_ID_FIELD_DESC);
          oprot.writeString(struct.jobSubmissionId);
          oprot.writeFieldEnd();
        }
        oprot.writeFieldStop();
        oprot.writeStructEnd();
      }

    }

    private static class getCloudJobSubmission_argsTupleSchemeFactory implements SchemeFactory {
      public getCloudJobSubmission_argsTupleScheme getScheme() {
        return new getCloudJobSubmission_argsTupleScheme();
      }
    }

    private static class getCloudJobSubmission_argsTupleScheme extends TupleScheme<getCloudJobSubmission_args> {

      @Override
      public void write(org.apache.thrift.protocol.TProtocol prot, getCloudJobSubmission_args struct) throws org.apache.thrift.TException {
        TTupleProtocol oprot = (TTupleProtocol) prot;
        struct.authzToken.write(oprot);
        oprot.writeString(struct.jobSubmissionId);
      }

      @Override
      public void read(org.apache.thrift.protocol.TProtocol prot, getCloudJobSubmission_args struct) throws org.apache.thrift.TException {
        TTupleProtocol iprot = (TTupleProtocol) prot;
        struct.authzToken = new org.apache.airavata.model.security.AuthzToken();
        struct.authzToken.read(iprot);
        struct.setAuthzTokenIsSet(true);
        struct.jobSubmissionId = iprot.readString();
        struct.setJobSubmissionIdIsSet(true);
      }
    }

  }

  public static class getCloudJobSubmission_result implements org.apache.thrift.TBase<getCloudJobSubmission_result, getCloudJobSubmission_result._Fields>, java.io.Serializable, Cloneable, Comparable<getCloudJobSubmission_result>   {
    private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("getCloudJobSubmission_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 IRE_FIELD_DESC = new org.apache.thrift.protocol.TField("ire", org.apache.thrift.protocol.TType.STRUCT, (short)1);
    private static final org.apache.thrift.protocol.TField ACE_FIELD_DESC = new org.apache.thrift.protocol.TField("ace", org.apache.thrift.protocol.TType.STRUCT, (short)2);
    private static final org.apache.thrift.protocol.TField ASE_FIELD_DESC = new org.apache.thrift.protocol.TField("ase", org.apache.thrift.protocol.TType.STRUCT, (short)3);
    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)4);

    private static final Map<Class<? extends IScheme>, SchemeFactory> schemes = new HashMap<Class<? extends IScheme>, SchemeFactory>();
    static {
      schemes.put(StandardScheme.class, new getCloudJobSubmission_resultStandardSchemeFactory());
      schemes.put(TupleScheme.class, new getCloudJobSubmission_resultTupleSchemeFactory());
    }

    public org.apache.airavata.model.appcatalog.computeresource.CloudJobSubmission success; // required
    public org.apache.airavata.model.error.InvalidRequestException ire; // required
    public org.apache.airavata.model.error.AiravataClientException ace; // required
    public org.apache.airavata.model.error.AiravataSystemException ase; // 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"),
      IRE((short)1, "ire"),
      ACE((short)2, "ace"),
      ASE((short)3, "ase"),
      AE((short)4, "ae");

      private static final Map<String, _Fields> byName = new HashMap<String, _Fields>();

      static {
        for (_Fields field : EnumSet.allOf(_Fields.class)) {
          byName.put(field.getFieldName(), field);
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, or null if its not found.
       */
      public static _Fields findByThriftId(int fieldId) {
        switch(fieldId) {
          case 0: // SUCCESS
            return SUCCESS;
          case 1: // IRE
            return IRE;
          case 2: // ACE
            return ACE;
          case 3: // ASE
            return ASE;
          case 4: // 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 IllegalArgumentException("Field " + fieldId + " doesn't exist!");
        return fields;
      }

      /**
       * Find the _Fields constant that matches name, or null if its not found.
       */
      public static _Fields findByName(String name) {
        return byName.get(name);
      }

      private final short _thriftId;
      private final String _fieldName;

      _Fields(short thriftId, String fieldName) {
        _thriftId = thriftId;
        _fieldName = fieldName;
      }

      public short getThriftFieldId() {
        return _thriftId;
      }

      public String getFieldName() {
        return _fieldName;
      }
    }

    // isset id assignments
    public static final Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
    static {
      Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new EnumMap<_Fields, org.apache.thrift.meta_data.FieldMetaData>(_Fields.class);
      tmpMap.put(_Fields.SUCCESS, new org.apache.thrift.meta_data.FieldMetaData("success", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.StructMetaData(org.apache.thrift.protocol.TType.STRUCT, org.apache.airavata.model.appcatalog.computeresource.CloudJobSubmission.class)));
      tmpMap.put(_Fields.IRE, new org.apache.thrift.meta_data.FieldMetaData("ire", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRUCT)));
      tmpMap.put(_Fields.ACE, new org.apache.thrift.meta_data.FieldMetaData("ace", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRUCT)));
      tmpMap.put(_Fields.ASE, new org.apache.thrift.meta_data.FieldMetaData("ase", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRUCT)));
      tmpMap.put(_Fields.AE, new org.apache.thrift.meta_data.FieldMetaData("ae", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRUCT)));
      metaDataMap = Collections.unmodifiableMap(tmpMap);
      org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(getCloudJobSubmission_result.class, metaDataMap);
    }

    public getCloudJobSubmission_result() {
    }

    public getCloudJobSubmission_result(
      org.apache.airavata.model.appcatalog.computeresource.CloudJobSubmission success,
      org.apache.airavata.model.error.InvalidRequestException ire,
      org.apache.airavata.model.error.AiravataClientException ace,
      org.apache.airavata.model.error.AiravataSystemException ase,
      org.apache.airavata.model.error.AuthorizationException ae)
    {
      this();
      this.success = success;
      this.ire = ire;
      this.ace = ace;
      this.ase = ase;
      this.ae = ae;
    }

    /**
     * Performs a deep copy on <i>other</i>.
     */
    public getCloudJobSubmission_result(getCloudJobSubmission_result other) {
      if (other.isSetSuccess()) {
        this.success = new org.apache.airavata.model.appcatalog.computeresource.CloudJobSubmission(other.success);
      }
      if (other.isSetIre()) {
        this.ire = new org.apache.airavata.model.error.InvalidRequestException(other.ire);
      }
      if (other.isSetAce()) {
        this.ace = new org.apache.airavata.model.error.AiravataClientException(other.ace);
      }
      if (other.isSetAse()) {
        this.ase = new org.apache.airavata.model.error.AiravataSystemException(other.ase);
      }
      if (other.isSetAe()) {
        this.ae = new org.apache.airavata.model.error.AuthorizationException(other.ae);
      }
    }

    public getCloudJobSubmission_result deepCopy() {
      return new getCloudJobSubmission_result(this);
    }

    @Override
    public void clear() {
      this.success = null;
      this.ire = null;
      this.ace = null;
      this.ase = null;
      this.ae = null;
    }

    public org.apache.airavata.model.appcatalog.computeresource.CloudJobSubmission getSuccess() {
      return this.success;
    }

    public getCloudJobSubmission_result setSuccess(org.apache.airavata.model.appcatalog.computeresource.CloudJobSubmission 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.model.error.InvalidRequestException getIre() {
      return this.ire;
    }

    public getCloudJobSubmission_result setIre(org.apache.airavata.model.error.InvalidRequestException ire) {
      this.ire = ire;
      return this;
    }

    public void unsetIre() {
      this.ire = null;
    }

    /** Returns true if field ire is set (has been assigned a value) and false otherwise */
    public boolean isSetIre() {
      return this.ire != null;
    }

    public void setIreIsSet(boolean value) {
      if (!value) {
        this.ire = null;
      }
    }

    public org.apache.airavata.model.error.AiravataClientException getAce() {
      return this.ace;
    }

    public getCloudJobSubmission_result setAce(org.apache.airavata.model.error.AiravataClientException ace) {
      this.ace = ace;
      return this;
    }

    public void unsetAce() {
      this.ace = null;
    }

    /** Returns true if field ace is set (has been assigned a value) and false otherwise */
    public boolean isSetAce() {
      return this.ace != null;
    }

    public void setAceIsSet(boolean value) {
      if (!value) {
        this.ace = null;
      }
    }

    public org.apache.airavata.model.error.AiravataSystemException getAse() {
      return this.ase;
    }

    public getCloudJobSubmission_result setAse(org.apache.airavata.model.error.AiravataSystemException ase) {
      this.ase = ase;
      return this;
    }

    public void unsetAse() {
      this.ase = null;
    }

    /** Returns true if field ase is set (has been assigned a value) and false otherwise */
    public boolean isSetAse() {
      return this.ase != null;
    }

    public void setAseIsSet(boolean value) {
      if (!value) {
        this.ase = null;
      }
    }

    public org.apache.airavata.model.error.AuthorizationException getAe() {
      return this.ae;
    }

    public getCloudJobSubmission_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, Object value) {
      switch (field) {
      case SUCCESS:
        if (value == null) {
          unsetSuccess();
        } else {
          setSuccess((org.apache.airavata.model.appcatalog.computeresource.CloudJobSubmission)value);
        }
        break;

      case IRE:
        if (value == null) {
          unsetIre();
        } else {
          setIre((org.apache.airavata.model.error.InvalidRequestException)value);
        }
        break;

      case ACE:
        if (value == null) {
          unsetAce();
        } else {
          setAce((org.apache.airavata.model.error.AiravataClientException)value);
        }
        break;

      case ASE:
        if (value == null) {
          unsetAse();
        } else {
          setAse((org.apache.airavata.model.error.AiravataSystemException)value);
        }
        break;

      case AE:
        if (value == null) {
          unsetAe();
        } else {
          setAe((org.apache.airavata.model.error.AuthorizationException)value);
        }
        break;

      }
    }

    public Object getFieldValue(_Fields field) {
      switch (field) {
      case SUCCESS:
        return getSuccess();

      case IRE:
        return getIre();

      case ACE:
        return getAce();

      case ASE:
        return getAse();

      case AE:
        return getAe();

      }
      throw new IllegalStateException();
    }

    /** Returns true if field corresponding to fieldID is set (has been assigned a value) and false otherwise */
    public boolean isSet(_Fields field) {
      if (field == null) {
        throw new IllegalArgumentException();
      }

      switch (field) {
      case SUCCESS:
        return isSetSuccess();
      case IRE:
        return isSetIre();
      case ACE:
        return isSetAce();
      case ASE:
        return isSetAse();
      case AE:
        return isSetAe();
      }
      throw new IllegalStateException();
    }

    @Override
    public boolean equals(Object that) {
      if (that == null)
        return false;
      if (that instanceof getCloudJobSubmission_result)
        return this.equals((getCloudJobSubmission_result)that);
      return false;
    }

    public boolean equals(getCloudJobSubmission_result that) {
      if (that == null)
        return false;

      boolean this_present_success = true && this.isSetSuccess();
      boolean that_present_success = true && that.isSetSuccess();
      if (this_present_success || that_present_success) {
        if (!(this_present_success && that_present_success))
          return false;
        if (!this.success.equals(that.success))
          return false;
      }

      boolean this_present_ire = true && this.isSetIre();
      boolean that_present_ire = true && that.isSetIre();
      if (this_present_ire || that_present_ire) {
        if (!(this_present_ire && that_present_ire))
          return false;
        if (!this.ire.equals(that.ire))
          return false;
      }

      boolean this_present_ace = true && this.isSetAce();
      boolean that_present_ace = true && that.isSetAce();
      if (this_present_ace || that_present_ace) {
        if (!(this_present_ace && that_present_ace))
          return false;
        if (!this.ace.equals(that.ace))
          return false;
      }

      boolean this_present_ase = true && this.isSetAse();
      boolean that_present_ase = true && that.isSetAse();
      if (this_present_ase || that_present_ase) {
        if (!(this_present_ase && that_present_ase))
          return false;
        if (!this.ase.equals(that.ase))
          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() {
      List<Object> list = new ArrayList<Object>();

      boolean present_success = true && (isSetSuccess());
      list.add(present_success);
      if (present_success)
        list.add(success);

      boolean present_ire = true && (isSetIre());
      list.add(present_ire);
      if (present_ire)
        list.add(ire);

      boolean present_ace = true && (isSetAce());
      list.add(present_ace);
      if (present_ace)
        list.add(ace);

      boolean present_ase = true && (isSetAse());
      list.add(present_ase);
      if (present_ase)
        list.add(ase);

      boolean present_ae = true && (isSetAe());
      list.add(present_ae);
      if (present_ae)
        list.add(ae);

      return list.hashCode();
    }

    @Override
    public int compareTo(getCloudJobSubmission_result other) {
      if (!getClass().equals(other.getClass())) {
        return getClass().getName().compareTo(other.getClass().getName());
      }

      int lastComparison = 0;

      lastComparison = Boolean.valueOf(isSetSuccess()).compareTo(other.isSetSuccess());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetSuccess()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.success, other.success);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = Boolean.valueOf(isSetIre()).compareTo(other.isSetIre());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetIre()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.ire, other.ire);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = Boolean.valueOf(isSetAce()).compareTo(other.isSetAce());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetAce()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.ace, other.ace);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = Boolean.valueOf(isSetAse()).compareTo(other.isSetAse());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetAse()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.ase, other.ase);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = 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 {
      schemes.get(iprot.getScheme()).getScheme().read(iprot, this);
    }

    public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException {
      schemes.get(oprot.getScheme()).getScheme().write(oprot, this);
      }

    @Override
    public String toString() {
      StringBuilder sb = new StringBuilder("getCloudJobSubmission_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("ire:");
      if (this.ire == null) {
        sb.append("null");
      } else {
        sb.append(this.ire);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("ace:");
      if (this.ace == null) {
        sb.append("null");
      } else {
        sb.append(this.ace);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("ase:");
      if (this.ase == null) {
        sb.append("null");
      } else {
        sb.append(this.ase);
      }
      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, 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 getCloudJobSubmission_resultStandardSchemeFactory implements SchemeFactory {
      public getCloudJobSubmission_resultStandardScheme getScheme() {
        return new getCloudJobSubmission_resultStandardScheme();
      }
    }

    private static class getCloudJobSubmission_resultStandardScheme extends StandardScheme<getCloudJobSubmission_result> {

      public void read(org.apache.thrift.protocol.TProtocol iprot, getCloudJobSubmission_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.appcatalog.computeresource.CloudJobSubmission();
                struct.success.read(iprot);
                struct.setSuccessIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 1: // IRE
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.ire = new org.apache.airavata.model.error.InvalidRequestException();
                struct.ire.read(iprot);
                struct.setIreIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 2: // ACE
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.ace = new org.apache.airavata.model.error.AiravataClientException();
                struct.ace.read(iprot);
                struct.setAceIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 3: // ASE
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.ase = new org.apache.airavata.model.error.AiravataSystemException();
                struct.ase.read(iprot);
                struct.setAseIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 4: // 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, getCloudJobSubmission_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.ire != null) {
          oprot.writeFieldBegin(IRE_FIELD_DESC);
          struct.ire.write(oprot);
          oprot.writeFieldEnd();
        }
        if (struct.ace != null) {
          oprot.writeFieldBegin(ACE_FIELD_DESC);
          struct.ace.write(oprot);
          oprot.writeFieldEnd();
        }
        if (struct.ase != null) {
          oprot.writeFieldBegin(ASE_FIELD_DESC);
          struct.ase.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 getCloudJobSubmission_resultTupleSchemeFactory implements SchemeFactory {
      public getCloudJobSubmission_resultTupleScheme getScheme() {
        return new getCloudJobSubmission_resultTupleScheme();
      }
    }

    private static class getCloudJobSubmission_resultTupleScheme extends TupleScheme<getCloudJobSubmission_result> {

      @Override
      public void write(org.apache.thrift.protocol.TProtocol prot, getCloudJobSubmission_result struct) throws org.apache.thrift.TException {
        TTupleProtocol oprot = (TTupleProtocol) prot;
        BitSet optionals = new BitSet();
        if (struct.isSetSuccess()) {
          optionals.set(0);
        }
        if (struct.isSetIre()) {
          optionals.set(1);
        }
        if (struct.isSetAce()) {
          optionals.set(2);
        }
        if (struct.isSetAse()) {
          optionals.set(3);
        }
        if (struct.isSetAe()) {
          optionals.set(4);
        }
        oprot.writeBitSet(optionals, 5);
        if (struct.isSetSuccess()) {
          struct.success.write(oprot);
        }
        if (struct.isSetIre()) {
          struct.ire.write(oprot);
        }
        if (struct.isSetAce()) {
          struct.ace.write(oprot);
        }
        if (struct.isSetAse()) {
          struct.ase.write(oprot);
        }
        if (struct.isSetAe()) {
          struct.ae.write(oprot);
        }
      }

      @Override
      public void read(org.apache.thrift.protocol.TProtocol prot, getCloudJobSubmission_result struct) throws org.apache.thrift.TException {
        TTupleProtocol iprot = (TTupleProtocol) prot;
        BitSet incoming = iprot.readBitSet(5);
        if (incoming.get(0)) {
          struct.success = new org.apache.airavata.model.appcatalog.computeresource.CloudJobSubmission();
          struct.success.read(iprot);
          struct.setSuccessIsSet(true);
        }
        if (incoming.get(1)) {
          struct.ire = new org.apache.airavata.model.error.InvalidRequestException();
          struct.ire.read(iprot);
          struct.setIreIsSet(true);
        }
        if (incoming.get(2)) {
          struct.ace = new org.apache.airavata.model.error.AiravataClientException();
          struct.ace.read(iprot);
          struct.setAceIsSet(true);
        }
        if (incoming.get(3)) {
          struct.ase = new org.apache.airavata.model.error.AiravataSystemException();
          struct.ase.read(iprot);
          struct.setAseIsSet(true);
        }
        if (incoming.get(4)) {
          struct.ae = new org.apache.airavata.model.error.AuthorizationException();
          struct.ae.read(iprot);
          struct.setAeIsSet(true);
        }
      }
    }

  }

  public static class updateSSHJobSubmissionDetails_args implements org.apache.thrift.TBase<updateSSHJobSubmissionDetails_args, updateSSHJobSubmissionDetails_args._Fields>, java.io.Serializable, Cloneable, Comparable<updateSSHJobSubmissionDetails_args>   {
    private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("updateSSHJobSubmissionDetails_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 JOB_SUBMISSION_INTERFACE_ID_FIELD_DESC = new org.apache.thrift.protocol.TField("jobSubmissionInterfaceId", org.apache.thrift.protocol.TType.STRING, (short)2);
    private static final org.apache.thrift.protocol.TField SSH_JOB_SUBMISSION_FIELD_DESC = new org.apache.thrift.protocol.TField("sshJobSubmission", org.apache.thrift.protocol.TType.STRUCT, (short)3);

    private static final Map<Class<? extends IScheme>, SchemeFactory> schemes = new HashMap<Class<? extends IScheme>, SchemeFactory>();
    static {
      schemes.put(StandardScheme.class, new updateSSHJobSubmissionDetails_argsStandardSchemeFactory());
      schemes.put(TupleScheme.class, new updateSSHJobSubmissionDetails_argsTupleSchemeFactory());
    }

    public org.apache.airavata.model.security.AuthzToken authzToken; // required
    public String jobSubmissionInterfaceId; // required
    public org.apache.airavata.model.appcatalog.computeresource.SSHJobSubmission sshJobSubmission; // required

    /** 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"),
      JOB_SUBMISSION_INTERFACE_ID((short)2, "jobSubmissionInterfaceId"),
      SSH_JOB_SUBMISSION((short)3, "sshJobSubmission");

      private static final Map<String, _Fields> byName = new HashMap<String, _Fields>();

      static {
        for (_Fields field : EnumSet.allOf(_Fields.class)) {
          byName.put(field.getFieldName(), field);
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, or null if its not found.
       */
      public static _Fields findByThriftId(int fieldId) {
        switch(fieldId) {
          case 1: // AUTHZ_TOKEN
            return AUTHZ_TOKEN;
          case 2: // JOB_SUBMISSION_INTERFACE_ID
            return JOB_SUBMISSION_INTERFACE_ID;
          case 3: // SSH_JOB_SUBMISSION
            return SSH_JOB_SUBMISSION;
          default:
            return null;
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, throwing an exception
       * if it is not found.
       */
      public static _Fields findByThriftIdOrThrow(int fieldId) {
        _Fields fields = findByThriftId(fieldId);
        if (fields == null) throw new IllegalArgumentException("Field " + fieldId + " doesn't exist!");
        return fields;
      }

      /**
       * Find the _Fields constant that matches name, or null if its not found.
       */
      public static _Fields findByName(String name) {
        return byName.get(name);
      }

      private final short _thriftId;
      private final String _fieldName;

      _Fields(short thriftId, String fieldName) {
        _thriftId = thriftId;
        _fieldName = fieldName;
      }

      public short getThriftFieldId() {
        return _thriftId;
      }

      public String getFieldName() {
        return _fieldName;
      }
    }

    // isset id assignments
    public static final Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
    static {
      Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new EnumMap<_Fields, org.apache.thrift.meta_data.FieldMetaData>(_Fields.class);
      tmpMap.put(_Fields.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.JOB_SUBMISSION_INTERFACE_ID, new org.apache.thrift.meta_data.FieldMetaData("jobSubmissionInterfaceId", org.apache.thrift.TFieldRequirementType.REQUIRED, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING)));
      tmpMap.put(_Fields.SSH_JOB_SUBMISSION, new org.apache.thrift.meta_data.FieldMetaData("sshJobSubmission", org.apache.thrift.TFieldRequirementType.REQUIRED, 
          new org.apache.thrift.meta_data.StructMetaData(org.apache.thrift.protocol.TType.STRUCT, org.apache.airavata.model.appcatalog.computeresource.SSHJobSubmission.class)));
      metaDataMap = Collections.unmodifiableMap(tmpMap);
      org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(updateSSHJobSubmissionDetails_args.class, metaDataMap);
    }

    public updateSSHJobSubmissionDetails_args() {
    }

    public updateSSHJobSubmissionDetails_args(
      org.apache.airavata.model.security.AuthzToken authzToken,
      String jobSubmissionInterfaceId,
      org.apache.airavata.model.appcatalog.computeresource.SSHJobSubmission sshJobSubmission)
    {
      this();
      this.authzToken = authzToken;
      this.jobSubmissionInterfaceId = jobSubmissionInterfaceId;
      this.sshJobSubmission = sshJobSubmission;
    }

    /**
     * Performs a deep copy on <i>other</i>.
     */
    public updateSSHJobSubmissionDetails_args(updateSSHJobSubmissionDetails_args other) {
      if (other.isSetAuthzToken()) {
        this.authzToken = new org.apache.airavata.model.security.AuthzToken(other.authzToken);
      }
      if (other.isSetJobSubmissionInterfaceId()) {
        this.jobSubmissionInterfaceId = other.jobSubmissionInterfaceId;
      }
      if (other.isSetSshJobSubmission()) {
        this.sshJobSubmission = new org.apache.airavata.model.appcatalog.computeresource.SSHJobSubmission(other.sshJobSubmission);
      }
    }

    public updateSSHJobSubmissionDetails_args deepCopy() {
      return new updateSSHJobSubmissionDetails_args(this);
    }

    @Override
    public void clear() {
      this.authzToken = null;
      this.jobSubmissionInterfaceId = null;
      this.sshJobSubmission = null;
    }

    public org.apache.airavata.model.security.AuthzToken getAuthzToken() {
      return this.authzToken;
    }

    public updateSSHJobSubmissionDetails_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 String getJobSubmissionInterfaceId() {
      return this.jobSubmissionInterfaceId;
    }

    public updateSSHJobSubmissionDetails_args setJobSubmissionInterfaceId(String jobSubmissionInterfaceId) {
      this.jobSubmissionInterfaceId = jobSubmissionInterfaceId;
      return this;
    }

    public void unsetJobSubmissionInterfaceId() {
      this.jobSubmissionInterfaceId = null;
    }

    /** Returns true if field jobSubmissionInterfaceId is set (has been assigned a value) and false otherwise */
    public boolean isSetJobSubmissionInterfaceId() {
      return this.jobSubmissionInterfaceId != null;
    }

    public void setJobSubmissionInterfaceIdIsSet(boolean value) {
      if (!value) {
        this.jobSubmissionInterfaceId = null;
      }
    }

    public org.apache.airavata.model.appcatalog.computeresource.SSHJobSubmission getSshJobSubmission() {
      return this.sshJobSubmission;
    }

    public updateSSHJobSubmissionDetails_args setSshJobSubmission(org.apache.airavata.model.appcatalog.computeresource.SSHJobSubmission sshJobSubmission) {
      this.sshJobSubmission = sshJobSubmission;
      return this;
    }

    public void unsetSshJobSubmission() {
      this.sshJobSubmission = null;
    }

    /** Returns true if field sshJobSubmission is set (has been assigned a value) and false otherwise */
    public boolean isSetSshJobSubmission() {
      return this.sshJobSubmission != null;
    }

    public void setSshJobSubmissionIsSet(boolean value) {
      if (!value) {
        this.sshJobSubmission = null;
      }
    }

    public void setFieldValue(_Fields field, Object value) {
      switch (field) {
      case AUTHZ_TOKEN:
        if (value == null) {
          unsetAuthzToken();
        } else {
          setAuthzToken((org.apache.airavata.model.security.AuthzToken)value);
        }
        break;

      case JOB_SUBMISSION_INTERFACE_ID:
        if (value == null) {
          unsetJobSubmissionInterfaceId();
        } else {
          setJobSubmissionInterfaceId((String)value);
        }
        break;

      case SSH_JOB_SUBMISSION:
        if (value == null) {
          unsetSshJobSubmission();
        } else {
          setSshJobSubmission((org.apache.airavata.model.appcatalog.computeresource.SSHJobSubmission)value);
        }
        break;

      }
    }

    public Object getFieldValue(_Fields field) {
      switch (field) {
      case AUTHZ_TOKEN:
        return getAuthzToken();

      case JOB_SUBMISSION_INTERFACE_ID:
        return getJobSubmissionInterfaceId();

      case SSH_JOB_SUBMISSION:
        return getSshJobSubmission();

      }
      throw new IllegalStateException();
    }

    /** Returns true if field corresponding to fieldID is set (has been assigned a value) and false otherwise */
    public boolean isSet(_Fields field) {
      if (field == null) {
        throw new IllegalArgumentException();
      }

      switch (field) {
      case AUTHZ_TOKEN:
        return isSetAuthzToken();
      case JOB_SUBMISSION_INTERFACE_ID:
        return isSetJobSubmissionInterfaceId();
      case SSH_JOB_SUBMISSION:
        return isSetSshJobSubmission();
      }
      throw new IllegalStateException();
    }

    @Override
    public boolean equals(Object that) {
      if (that == null)
        return false;
      if (that instanceof updateSSHJobSubmissionDetails_args)
        return this.equals((updateSSHJobSubmissionDetails_args)that);
      return false;
    }

    public boolean equals(updateSSHJobSubmissionDetails_args that) {
      if (that == null)
        return false;

      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_jobSubmissionInterfaceId = true && this.isSetJobSubmissionInterfaceId();
      boolean that_present_jobSubmissionInterfaceId = true && that.isSetJobSubmissionInterfaceId();
      if (this_present_jobSubmissionInterfaceId || that_present_jobSubmissionInterfaceId) {
        if (!(this_present_jobSubmissionInterfaceId && that_present_jobSubmissionInterfaceId))
          return false;
        if (!this.jobSubmissionInterfaceId.equals(that.jobSubmissionInterfaceId))
          return false;
      }

      boolean this_present_sshJobSubmission = true && this.isSetSshJobSubmission();
      boolean that_present_sshJobSubmission = true && that.isSetSshJobSubmission();
      if (this_present_sshJobSubmission || that_present_sshJobSubmission) {
        if (!(this_present_sshJobSubmission && that_present_sshJobSubmission))
          return false;
        if (!this.sshJobSubmission.equals(that.sshJobSubmission))
          return false;
      }

      return true;
    }

    @Override
    public int hashCode() {
      List<Object> list = new ArrayList<Object>();

      boolean present_authzToken = true && (isSetAuthzToken());
      list.add(present_authzToken);
      if (present_authzToken)
        list.add(authzToken);

      boolean present_jobSubmissionInterfaceId = true && (isSetJobSubmissionInterfaceId());
      list.add(present_jobSubmissionInterfaceId);
      if (present_jobSubmissionInterfaceId)
        list.add(jobSubmissionInterfaceId);

      boolean present_sshJobSubmission = true && (isSetSshJobSubmission());
      list.add(present_sshJobSubmission);
      if (present_sshJobSubmission)
        list.add(sshJobSubmission);

      return list.hashCode();
    }

    @Override
    public int compareTo(updateSSHJobSubmissionDetails_args other) {
      if (!getClass().equals(other.getClass())) {
        return getClass().getName().compareTo(other.getClass().getName());
      }

      int lastComparison = 0;

      lastComparison = 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 = Boolean.valueOf(isSetJobSubmissionInterfaceId()).compareTo(other.isSetJobSubmissionInterfaceId());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetJobSubmissionInterfaceId()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.jobSubmissionInterfaceId, other.jobSubmissionInterfaceId);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = Boolean.valueOf(isSetSshJobSubmission()).compareTo(other.isSetSshJobSubmission());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetSshJobSubmission()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.sshJobSubmission, other.sshJobSubmission);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      return 0;
    }

    public _Fields fieldForId(int fieldId) {
      return _Fields.findByThriftId(fieldId);
    }

    public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
      schemes.get(iprot.getScheme()).getScheme().read(iprot, this);
    }

    public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException {
      schemes.get(oprot.getScheme()).getScheme().write(oprot, this);
    }

    @Override
    public String toString() {
      StringBuilder sb = new StringBuilder("updateSSHJobSubmissionDetails_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("jobSubmissionInterfaceId:");
      if (this.jobSubmissionInterfaceId == null) {
        sb.append("null");
      } else {
        sb.append(this.jobSubmissionInterfaceId);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("sshJobSubmission:");
      if (this.sshJobSubmission == null) {
        sb.append("null");
      } else {
        sb.append(this.sshJobSubmission);
      }
      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 (jobSubmissionInterfaceId == null) {
        throw new org.apache.thrift.protocol.TProtocolException("Required field 'jobSubmissionInterfaceId' was not present! Struct: " + toString());
      }
      if (sshJobSubmission == null) {
        throw new org.apache.thrift.protocol.TProtocolException("Required field 'sshJobSubmission' was not present! Struct: " + toString());
      }
      // check for sub-struct validity
      if (authzToken != null) {
        authzToken.validate();
      }
      if (sshJobSubmission != null) {
        sshJobSubmission.validate();
      }
    }

    private void writeObject(java.io.ObjectOutputStream out) throws java.io.IOException {
      try {
        write(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(out)));
      } catch (org.apache.thrift.TException te) {
        throw new java.io.IOException(te);
      }
    }

    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, ClassNotFoundException {
      try {
        read(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(in)));
      } catch (org.apache.thrift.TException te) {
        throw new java.io.IOException(te);
      }
    }

    private static class updateSSHJobSubmissionDetails_argsStandardSchemeFactory implements SchemeFactory {
      public updateSSHJobSubmissionDetails_argsStandardScheme getScheme() {
        return new updateSSHJobSubmissionDetails_argsStandardScheme();
      }
    }

    private static class updateSSHJobSubmissionDetails_argsStandardScheme extends StandardScheme<updateSSHJobSubmissionDetails_args> {

      public void read(org.apache.thrift.protocol.TProtocol iprot, updateSSHJobSubmissionDetails_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: // JOB_SUBMISSION_INTERFACE_ID
              if (schemeField.type == org.apache.thrift.protocol.TType.STRING) {
                struct.jobSubmissionInterfaceId = iprot.readString();
                struct.setJobSubmissionInterfaceIdIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 3: // SSH_JOB_SUBMISSION
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.sshJobSubmission = new org.apache.airavata.model.appcatalog.computeresource.SSHJobSubmission();
                struct.sshJobSubmission.read(iprot);
                struct.setSshJobSubmissionIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            default:
              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
          }
          iprot.readFieldEnd();
        }
        iprot.readStructEnd();

        // check for required fields of primitive type, which can't be checked in the validate method
        struct.validate();
      }

      public void write(org.apache.thrift.protocol.TProtocol oprot, updateSSHJobSubmissionDetails_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.jobSubmissionInterfaceId != null) {
          oprot.writeFieldBegin(JOB_SUBMISSION_INTERFACE_ID_FIELD_DESC);
          oprot.writeString(struct.jobSubmissionInterfaceId);
          oprot.writeFieldEnd();
        }
        if (struct.sshJobSubmission != null) {
          oprot.writeFieldBegin(SSH_JOB_SUBMISSION_FIELD_DESC);
          struct.sshJobSubmission.write(oprot);
          oprot.writeFieldEnd();
        }
        oprot.writeFieldStop();
        oprot.writeStructEnd();
      }

    }

    private static class updateSSHJobSubmissionDetails_argsTupleSchemeFactory implements SchemeFactory {
      public updateSSHJobSubmissionDetails_argsTupleScheme getScheme() {
        return new updateSSHJobSubmissionDetails_argsTupleScheme();
      }
    }

    private static class updateSSHJobSubmissionDetails_argsTupleScheme extends TupleScheme<updateSSHJobSubmissionDetails_args> {

      @Override
      public void write(org.apache.thrift.protocol.TProtocol prot, updateSSHJobSubmissionDetails_args struct) throws org.apache.thrift.TException {
        TTupleProtocol oprot = (TTupleProtocol) prot;
        struct.authzToken.write(oprot);
        oprot.writeString(struct.jobSubmissionInterfaceId);
        struct.sshJobSubmission.write(oprot);
      }

      @Override
      public void read(org.apache.thrift.protocol.TProtocol prot, updateSSHJobSubmissionDetails_args struct) throws org.apache.thrift.TException {
        TTupleProtocol iprot = (TTupleProtocol) prot;
        struct.authzToken = new org.apache.airavata.model.security.AuthzToken();
        struct.authzToken.read(iprot);
        struct.setAuthzTokenIsSet(true);
        struct.jobSubmissionInterfaceId = iprot.readString();
        struct.setJobSubmissionInterfaceIdIsSet(true);
        struct.sshJobSubmission = new org.apache.airavata.model.appcatalog.computeresource.SSHJobSubmission();
        struct.sshJobSubmission.read(iprot);
        struct.setSshJobSubmissionIsSet(true);
      }
    }

  }

  public static class updateSSHJobSubmissionDetails_result implements org.apache.thrift.TBase<updateSSHJobSubmissionDetails_result, updateSSHJobSubmissionDetails_result._Fields>, java.io.Serializable, Cloneable, Comparable<updateSSHJobSubmissionDetails_result>   {
    private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("updateSSHJobSubmissionDetails_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 IRE_FIELD_DESC = new org.apache.thrift.protocol.TField("ire", org.apache.thrift.protocol.TType.STRUCT, (short)1);
    private static final org.apache.thrift.protocol.TField ACE_FIELD_DESC = new org.apache.thrift.protocol.TField("ace", org.apache.thrift.protocol.TType.STRUCT, (short)2);
    private static final org.apache.thrift.protocol.TField ASE_FIELD_DESC = new org.apache.thrift.protocol.TField("ase", org.apache.thrift.protocol.TType.STRUCT, (short)3);
    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)4);

    private static final Map<Class<? extends IScheme>, SchemeFactory> schemes = new HashMap<Class<? extends IScheme>, SchemeFactory>();
    static {
      schemes.put(StandardScheme.class, new updateSSHJobSubmissionDetails_resultStandardSchemeFactory());
      schemes.put(TupleScheme.class, new updateSSHJobSubmissionDetails_resultTupleSchemeFactory());
    }

    public boolean success; // required
    public org.apache.airavata.model.error.InvalidRequestException ire; // required
    public org.apache.airavata.model.error.AiravataClientException ace; // required
    public org.apache.airavata.model.error.AiravataSystemException ase; // 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"),
      IRE((short)1, "ire"),
      ACE((short)2, "ace"),
      ASE((short)3, "ase"),
      AE((short)4, "ae");

      private static final Map<String, _Fields> byName = new HashMap<String, _Fields>();

      static {
        for (_Fields field : EnumSet.allOf(_Fields.class)) {
          byName.put(field.getFieldName(), field);
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, or null if its not found.
       */
      public static _Fields findByThriftId(int fieldId) {
        switch(fieldId) {
          case 0: // SUCCESS
            return SUCCESS;
          case 1: // IRE
            return IRE;
          case 2: // ACE
            return ACE;
          case 3: // ASE
            return ASE;
          case 4: // 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 IllegalArgumentException("Field " + fieldId + " doesn't exist!");
        return fields;
      }

      /**
       * Find the _Fields constant that matches name, or null if its not found.
       */
      public static _Fields findByName(String name) {
        return byName.get(name);
      }

      private final short _thriftId;
      private final String _fieldName;

      _Fields(short thriftId, String fieldName) {
        _thriftId = thriftId;
        _fieldName = fieldName;
      }

      public short getThriftFieldId() {
        return _thriftId;
      }

      public String getFieldName() {
        return _fieldName;
      }
    }

    // isset id assignments
    private static final int __SUCCESS_ISSET_ID = 0;
    private byte __isset_bitfield = 0;
    public static final Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
    static {
      Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new EnumMap<_Fields, org.apache.thrift.meta_data.FieldMetaData>(_Fields.class);
      tmpMap.put(_Fields.SUCCESS, new org.apache.thrift.meta_data.FieldMetaData("success", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.BOOL)));
      tmpMap.put(_Fields.IRE, new org.apache.thrift.meta_data.FieldMetaData("ire", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRUCT)));
      tmpMap.put(_Fields.ACE, new org.apache.thrift.meta_data.FieldMetaData("ace", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRUCT)));
      tmpMap.put(_Fields.ASE, new org.apache.thrift.meta_data.FieldMetaData("ase", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRUCT)));
      tmpMap.put(_Fields.AE, new org.apache.thrift.meta_data.FieldMetaData("ae", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRUCT)));
      metaDataMap = Collections.unmodifiableMap(tmpMap);
      org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(updateSSHJobSubmissionDetails_result.class, metaDataMap);
    }

    public updateSSHJobSubmissionDetails_result() {
    }

    public updateSSHJobSubmissionDetails_result(
      boolean success,
      org.apache.airavata.model.error.InvalidRequestException ire,
      org.apache.airavata.model.error.AiravataClientException ace,
      org.apache.airavata.model.error.AiravataSystemException ase,
      org.apache.airavata.model.error.AuthorizationException ae)
    {
      this();
      this.success = success;
      setSuccessIsSet(true);
      this.ire = ire;
      this.ace = ace;
      this.ase = ase;
      this.ae = ae;
    }

    /**
     * Performs a deep copy on <i>other</i>.
     */
    public updateSSHJobSubmissionDetails_result(updateSSHJobSubmissionDetails_result other) {
      __isset_bitfield = other.__isset_bitfield;
      this.success = other.success;
      if (other.isSetIre()) {
        this.ire = new org.apache.airavata.model.error.InvalidRequestException(other.ire);
      }
      if (other.isSetAce()) {
        this.ace = new org.apache.airavata.model.error.AiravataClientException(other.ace);
      }
      if (other.isSetAse()) {
        this.ase = new org.apache.airavata.model.error.AiravataSystemException(other.ase);
      }
      if (other.isSetAe()) {
        this.ae = new org.apache.airavata.model.error.AuthorizationException(other.ae);
      }
    }

    public updateSSHJobSubmissionDetails_result deepCopy() {
      return new updateSSHJobSubmissionDetails_result(this);
    }

    @Override
    public void clear() {
      setSuccessIsSet(false);
      this.success = false;
      this.ire = null;
      this.ace = null;
      this.ase = null;
      this.ae = null;
    }

    public boolean isSuccess() {
      return this.success;
    }

    public updateSSHJobSubmissionDetails_result setSuccess(boolean success) {
      this.success = success;
      setSuccessIsSet(true);
      return this;
    }

    public void unsetSuccess() {
      __isset_bitfield = EncodingUtils.clearBit(__isset_bitfield, __SUCCESS_ISSET_ID);
    }

    /** Returns true if field success is set (has been assigned a value) and false otherwise */
    public boolean isSetSuccess() {
      return EncodingUtils.testBit(__isset_bitfield, __SUCCESS_ISSET_ID);
    }

    public void setSuccessIsSet(boolean value) {
      __isset_bitfield = EncodingUtils.setBit(__isset_bitfield, __SUCCESS_ISSET_ID, value);
    }

    public org.apache.airavata.model.error.InvalidRequestException getIre() {
      return this.ire;
    }

    public updateSSHJobSubmissionDetails_result setIre(org.apache.airavata.model.error.InvalidRequestException ire) {
      this.ire = ire;
      return this;
    }

    public void unsetIre() {
      this.ire = null;
    }

    /** Returns true if field ire is set (has been assigned a value) and false otherwise */
    public boolean isSetIre() {
      return this.ire != null;
    }

    public void setIreIsSet(boolean value) {
      if (!value) {
        this.ire = null;
      }
    }

    public org.apache.airavata.model.error.AiravataClientException getAce() {
      return this.ace;
    }

    public updateSSHJobSubmissionDetails_result setAce(org.apache.airavata.model.error.AiravataClientException ace) {
      this.ace = ace;
      return this;
    }

    public void unsetAce() {
      this.ace = null;
    }

    /** Returns true if field ace is set (has been assigned a value) and false otherwise */
    public boolean isSetAce() {
      return this.ace != null;
    }

    public void setAceIsSet(boolean value) {
      if (!value) {
        this.ace = null;
      }
    }

    public org.apache.airavata.model.error.AiravataSystemException getAse() {
      return this.ase;
    }

    public updateSSHJobSubmissionDetails_result setAse(org.apache.airavata.model.error.AiravataSystemException ase) {
      this.ase = ase;
      return this;
    }

    public void unsetAse() {
      this.ase = null;
    }

    /** Returns true if field ase is set (has been assigned a value) and false otherwise */
    public boolean isSetAse() {
      return this.ase != null;
    }

    public void setAseIsSet(boolean value) {
      if (!value) {
        this.ase = null;
      }
    }

    public org.apache.airavata.model.error.AuthorizationException getAe() {
      return this.ae;
    }

    public updateSSHJobSubmissionDetails_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, Object value) {
      switch (field) {
      case SUCCESS:
        if (value == null) {
          unsetSuccess();
        } else {
          setSuccess((Boolean)value);
        }
        break;

      case IRE:
        if (value == null) {
          unsetIre();
        } else {
          setIre((org.apache.airavata.model.error.InvalidRequestException)value);
        }
        break;

      case ACE:
        if (value == null) {
          unsetAce();
        } else {
          setAce((org.apache.airavata.model.error.AiravataClientException)value);
        }
        break;

      case ASE:
        if (value == null) {
          unsetAse();
        } else {
          setAse((org.apache.airavata.model.error.AiravataSystemException)value);
        }
        break;

      case AE:
        if (value == null) {
          unsetAe();
        } else {
          setAe((org.apache.airavata.model.error.AuthorizationException)value);
        }
        break;

      }
    }

    public Object getFieldValue(_Fields field) {
      switch (field) {
      case SUCCESS:
        return Boolean.valueOf(isSuccess());

      case IRE:
        return getIre();

      case ACE:
        return getAce();

      case ASE:
        return getAse();

      case AE:
        return getAe();

      }
      throw new IllegalStateException();
    }

    /** Returns true if field corresponding to fieldID is set (has been assigned a value) and false otherwise */
    public boolean isSet(_Fields field) {
      if (field == null) {
        throw new IllegalArgumentException();
      }

      switch (field) {
      case SUCCESS:
        return isSetSuccess();
      case IRE:
        return isSetIre();
      case ACE:
        return isSetAce();
      case ASE:
        return isSetAse();
      case AE:
        return isSetAe();
      }
      throw new IllegalStateException();
    }

    @Override
    public boolean equals(Object that) {
      if (that == null)
        return false;
      if (that instanceof updateSSHJobSubmissionDetails_result)
        return this.equals((updateSSHJobSubmissionDetails_result)that);
      return false;
    }

    public boolean equals(updateSSHJobSubmissionDetails_result that) {
      if (that == null)
        return false;

      boolean this_present_success = true;
      boolean that_present_success = true;
      if (this_present_success || that_present_success) {
        if (!(this_present_success && that_present_success))
          return false;
        if (this.success != that.success)
          return false;
      }

      boolean this_present_ire = true && this.isSetIre();
      boolean that_present_ire = true && that.isSetIre();
      if (this_present_ire || that_present_ire) {
        if (!(this_present_ire && that_present_ire))
          return false;
        if (!this.ire.equals(that.ire))
          return false;
      }

      boolean this_present_ace = true && this.isSetAce();
      boolean that_present_ace = true && that.isSetAce();
      if (this_present_ace || that_present_ace) {
        if (!(this_present_ace && that_present_ace))
          return false;
        if (!this.ace.equals(that.ace))
          return false;
      }

      boolean this_present_ase = true && this.isSetAse();
      boolean that_present_ase = true && that.isSetAse();
      if (this_present_ase || that_present_ase) {
        if (!(this_present_ase && that_present_ase))
          return false;
        if (!this.ase.equals(that.ase))
          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() {
      List<Object> list = new ArrayList<Object>();

      boolean present_success = true;
      list.add(present_success);
      if (present_success)
        list.add(success);

      boolean present_ire = true && (isSetIre());
      list.add(present_ire);
      if (present_ire)
        list.add(ire);

      boolean present_ace = true && (isSetAce());
      list.add(present_ace);
      if (present_ace)
        list.add(ace);

      boolean present_ase = true && (isSetAse());
      list.add(present_ase);
      if (present_ase)
        list.add(ase);

      boolean present_ae = true && (isSetAe());
      list.add(present_ae);
      if (present_ae)
        list.add(ae);

      return list.hashCode();
    }

    @Override
    public int compareTo(updateSSHJobSubmissionDetails_result other) {
      if (!getClass().equals(other.getClass())) {
        return getClass().getName().compareTo(other.getClass().getName());
      }

      int lastComparison = 0;

      lastComparison = Boolean.valueOf(isSetSuccess()).compareTo(other.isSetSuccess());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetSuccess()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.success, other.success);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = Boolean.valueOf(isSetIre()).compareTo(other.isSetIre());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetIre()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.ire, other.ire);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = Boolean.valueOf(isSetAce()).compareTo(other.isSetAce());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetAce()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.ace, other.ace);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = Boolean.valueOf(isSetAse()).compareTo(other.isSetAse());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetAse()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.ase, other.ase);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = 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 {
      schemes.get(iprot.getScheme()).getScheme().read(iprot, this);
    }

    public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException {
      schemes.get(oprot.getScheme()).getScheme().write(oprot, this);
      }

    @Override
    public String toString() {
      StringBuilder sb = new StringBuilder("updateSSHJobSubmissionDetails_result(");
      boolean first = true;

      sb.append("success:");
      sb.append(this.success);
      first = false;
      if (!first) sb.append(", ");
      sb.append("ire:");
      if (this.ire == null) {
        sb.append("null");
      } else {
        sb.append(this.ire);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("ace:");
      if (this.ace == null) {
        sb.append("null");
      } else {
        sb.append(this.ace);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("ase:");
      if (this.ase == null) {
        sb.append("null");
      } else {
        sb.append(this.ase);
      }
      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, 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 updateSSHJobSubmissionDetails_resultStandardSchemeFactory implements SchemeFactory {
      public updateSSHJobSubmissionDetails_resultStandardScheme getScheme() {
        return new updateSSHJobSubmissionDetails_resultStandardScheme();
      }
    }

    private static class updateSSHJobSubmissionDetails_resultStandardScheme extends StandardScheme<updateSSHJobSubmissionDetails_result> {

      public void read(org.apache.thrift.protocol.TProtocol iprot, updateSSHJobSubmissionDetails_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: // IRE
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.ire = new org.apache.airavata.model.error.InvalidRequestException();
                struct.ire.read(iprot);
                struct.setIreIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 2: // ACE
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.ace = new org.apache.airavata.model.error.AiravataClientException();
                struct.ace.read(iprot);
                struct.setAceIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 3: // ASE
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.ase = new org.apache.airavata.model.error.AiravataSystemException();
                struct.ase.read(iprot);
                struct.setAseIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 4: // 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, updateSSHJobSubmissionDetails_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.ire != null) {
          oprot.writeFieldBegin(IRE_FIELD_DESC);
          struct.ire.write(oprot);
          oprot.writeFieldEnd();
        }
        if (struct.ace != null) {
          oprot.writeFieldBegin(ACE_FIELD_DESC);
          struct.ace.write(oprot);
          oprot.writeFieldEnd();
        }
        if (struct.ase != null) {
          oprot.writeFieldBegin(ASE_FIELD_DESC);
          struct.ase.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 updateSSHJobSubmissionDetails_resultTupleSchemeFactory implements SchemeFactory {
      public updateSSHJobSubmissionDetails_resultTupleScheme getScheme() {
        return new updateSSHJobSubmissionDetails_resultTupleScheme();
      }
    }

    private static class updateSSHJobSubmissionDetails_resultTupleScheme extends TupleScheme<updateSSHJobSubmissionDetails_result> {

      @Override
      public void write(org.apache.thrift.protocol.TProtocol prot, updateSSHJobSubmissionDetails_result struct) throws org.apache.thrift.TException {
        TTupleProtocol oprot = (TTupleProtocol) prot;
        BitSet optionals = new BitSet();
        if (struct.isSetSuccess()) {
          optionals.set(0);
        }
        if (struct.isSetIre()) {
          optionals.set(1);
        }
        if (struct.isSetAce()) {
          optionals.set(2);
        }
        if (struct.isSetAse()) {
          optionals.set(3);
        }
        if (struct.isSetAe()) {
          optionals.set(4);
        }
        oprot.writeBitSet(optionals, 5);
        if (struct.isSetSuccess()) {
          oprot.writeBool(struct.success);
        }
        if (struct.isSetIre()) {
          struct.ire.write(oprot);
        }
        if (struct.isSetAce()) {
          struct.ace.write(oprot);
        }
        if (struct.isSetAse()) {
          struct.ase.write(oprot);
        }
        if (struct.isSetAe()) {
          struct.ae.write(oprot);
        }
      }

      @Override
      public void read(org.apache.thrift.protocol.TProtocol prot, updateSSHJobSubmissionDetails_result struct) throws org.apache.thrift.TException {
        TTupleProtocol iprot = (TTupleProtocol) prot;
        BitSet incoming = iprot.readBitSet(5);
        if (incoming.get(0)) {
          struct.success = iprot.readBool();
          struct.setSuccessIsSet(true);
        }
        if (incoming.get(1)) {
          struct.ire = new org.apache.airavata.model.error.InvalidRequestException();
          struct.ire.read(iprot);
          struct.setIreIsSet(true);
        }
        if (incoming.get(2)) {
          struct.ace = new org.apache.airavata.model.error.AiravataClientException();
          struct.ace.read(iprot);
          struct.setAceIsSet(true);
        }
        if (incoming.get(3)) {
          struct.ase = new org.apache.airavata.model.error.AiravataSystemException();
          struct.ase.read(iprot);
          struct.setAseIsSet(true);
        }
        if (incoming.get(4)) {
          struct.ae = new org.apache.airavata.model.error.AuthorizationException();
          struct.ae.read(iprot);
          struct.setAeIsSet(true);
        }
      }
    }

  }

  public static class updateCloudJobSubmissionDetails_args implements org.apache.thrift.TBase<updateCloudJobSubmissionDetails_args, updateCloudJobSubmissionDetails_args._Fields>, java.io.Serializable, Cloneable, Comparable<updateCloudJobSubmissionDetails_args>   {
    private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("updateCloudJobSubmissionDetails_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 JOB_SUBMISSION_INTERFACE_ID_FIELD_DESC = new org.apache.thrift.protocol.TField("jobSubmissionInterfaceId", org.apache.thrift.protocol.TType.STRING, (short)2);
    private static final org.apache.thrift.protocol.TField SSH_JOB_SUBMISSION_FIELD_DESC = new org.apache.thrift.protocol.TField("sshJobSubmission", org.apache.thrift.protocol.TType.STRUCT, (short)3);

    private static final Map<Class<? extends IScheme>, SchemeFactory> schemes = new HashMap<Class<? extends IScheme>, SchemeFactory>();
    static {
      schemes.put(StandardScheme.class, new updateCloudJobSubmissionDetails_argsStandardSchemeFactory());
      schemes.put(TupleScheme.class, new updateCloudJobSubmissionDetails_argsTupleSchemeFactory());
    }

    public org.apache.airavata.model.security.AuthzToken authzToken; // required
    public String jobSubmissionInterfaceId; // required
    public org.apache.airavata.model.appcatalog.computeresource.CloudJobSubmission sshJobSubmission; // required

    /** 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"),
      JOB_SUBMISSION_INTERFACE_ID((short)2, "jobSubmissionInterfaceId"),
      SSH_JOB_SUBMISSION((short)3, "sshJobSubmission");

      private static final Map<String, _Fields> byName = new HashMap<String, _Fields>();

      static {
        for (_Fields field : EnumSet.allOf(_Fields.class)) {
          byName.put(field.getFieldName(), field);
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, or null if its not found.
       */
      public static _Fields findByThriftId(int fieldId) {
        switch(fieldId) {
          case 1: // AUTHZ_TOKEN
            return AUTHZ_TOKEN;
          case 2: // JOB_SUBMISSION_INTERFACE_ID
            return JOB_SUBMISSION_INTERFACE_ID;
          case 3: // SSH_JOB_SUBMISSION
            return SSH_JOB_SUBMISSION;
          default:
            return null;
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, throwing an exception
       * if it is not found.
       */
      public static _Fields findByThriftIdOrThrow(int fieldId) {
        _Fields fields = findByThriftId(fieldId);
        if (fields == null) throw new IllegalArgumentException("Field " + fieldId + " doesn't exist!");
        return fields;
      }

      /**
       * Find the _Fields constant that matches name, or null if its not found.
       */
      public static _Fields findByName(String name) {
        return byName.get(name);
      }

      private final short _thriftId;
      private final String _fieldName;

      _Fields(short thriftId, String fieldName) {
        _thriftId = thriftId;
        _fieldName = fieldName;
      }

      public short getThriftFieldId() {
        return _thriftId;
      }

      public String getFieldName() {
        return _fieldName;
      }
    }

    // isset id assignments
    public static final Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
    static {
      Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new EnumMap<_Fields, org.apache.thrift.meta_data.FieldMetaData>(_Fields.class);
      tmpMap.put(_Fields.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.JOB_SUBMISSION_INTERFACE_ID, new org.apache.thrift.meta_data.FieldMetaData("jobSubmissionInterfaceId", org.apache.thrift.TFieldRequirementType.REQUIRED, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING)));
      tmpMap.put(_Fields.SSH_JOB_SUBMISSION, new org.apache.thrift.meta_data.FieldMetaData("sshJobSubmission", org.apache.thrift.TFieldRequirementType.REQUIRED, 
          new org.apache.thrift.meta_data.StructMetaData(org.apache.thrift.protocol.TType.STRUCT, org.apache.airavata.model.appcatalog.computeresource.CloudJobSubmission.class)));
      metaDataMap = Collections.unmodifiableMap(tmpMap);
      org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(updateCloudJobSubmissionDetails_args.class, metaDataMap);
    }

    public updateCloudJobSubmissionDetails_args() {
    }

    public updateCloudJobSubmissionDetails_args(
      org.apache.airavata.model.security.AuthzToken authzToken,
      String jobSubmissionInterfaceId,
      org.apache.airavata.model.appcatalog.computeresource.CloudJobSubmission sshJobSubmission)
    {
      this();
      this.authzToken = authzToken;
      this.jobSubmissionInterfaceId = jobSubmissionInterfaceId;
      this.sshJobSubmission = sshJobSubmission;
    }

    /**
     * Performs a deep copy on <i>other</i>.
     */
    public updateCloudJobSubmissionDetails_args(updateCloudJobSubmissionDetails_args other) {
      if (other.isSetAuthzToken()) {
        this.authzToken = new org.apache.airavata.model.security.AuthzToken(other.authzToken);
      }
      if (other.isSetJobSubmissionInterfaceId()) {
        this.jobSubmissionInterfaceId = other.jobSubmissionInterfaceId;
      }
      if (other.isSetSshJobSubmission()) {
        this.sshJobSubmission = new org.apache.airavata.model.appcatalog.computeresource.CloudJobSubmission(other.sshJobSubmission);
      }
    }

    public updateCloudJobSubmissionDetails_args deepCopy() {
      return new updateCloudJobSubmissionDetails_args(this);
    }

    @Override
    public void clear() {
      this.authzToken = null;
      this.jobSubmissionInterfaceId = null;
      this.sshJobSubmission = null;
    }

    public org.apache.airavata.model.security.AuthzToken getAuthzToken() {
      return this.authzToken;
    }

    public updateCloudJobSubmissionDetails_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 String getJobSubmissionInterfaceId() {
      return this.jobSubmissionInterfaceId;
    }

    public updateCloudJobSubmissionDetails_args setJobSubmissionInterfaceId(String jobSubmissionInterfaceId) {
      this.jobSubmissionInterfaceId = jobSubmissionInterfaceId;
      return this;
    }

    public void unsetJobSubmissionInterfaceId() {
      this.jobSubmissionInterfaceId = null;
    }

    /** Returns true if field jobSubmissionInterfaceId is set (has been assigned a value) and false otherwise */
    public boolean isSetJobSubmissionInterfaceId() {
      return this.jobSubmissionInterfaceId != null;
    }

    public void setJobSubmissionInterfaceIdIsSet(boolean value) {
      if (!value) {
        this.jobSubmissionInterfaceId = null;
      }
    }

    public org.apache.airavata.model.appcatalog.computeresource.CloudJobSubmission getSshJobSubmission() {
      return this.sshJobSubmission;
    }

    public updateCloudJobSubmissionDetails_args setSshJobSubmission(org.apache.airavata.model.appcatalog.computeresource.CloudJobSubmission sshJobSubmission) {
      this.sshJobSubmission = sshJobSubmission;
      return this;
    }

    public void unsetSshJobSubmission() {
      this.sshJobSubmission = null;
    }

    /** Returns true if field sshJobSubmission is set (has been assigned a value) and false otherwise */
    public boolean isSetSshJobSubmission() {
      return this.sshJobSubmission != null;
    }

    public void setSshJobSubmissionIsSet(boolean value) {
      if (!value) {
        this.sshJobSubmission = null;
      }
    }

    public void setFieldValue(_Fields field, Object value) {
      switch (field) {
      case AUTHZ_TOKEN:
        if (value == null) {
          unsetAuthzToken();
        } else {
          setAuthzToken((org.apache.airavata.model.security.AuthzToken)value);
        }
        break;

      case JOB_SUBMISSION_INTERFACE_ID:
        if (value == null) {
          unsetJobSubmissionInterfaceId();
        } else {
          setJobSubmissionInterfaceId((String)value);
        }
        break;

      case SSH_JOB_SUBMISSION:
        if (value == null) {
          unsetSshJobSubmission();
        } else {
          setSshJobSubmission((org.apache.airavata.model.appcatalog.computeresource.CloudJobSubmission)value);
        }
        break;

      }
    }

    public Object getFieldValue(_Fields field) {
      switch (field) {
      case AUTHZ_TOKEN:
        return getAuthzToken();

      case JOB_SUBMISSION_INTERFACE_ID:
        return getJobSubmissionInterfaceId();

      case SSH_JOB_SUBMISSION:
        return getSshJobSubmission();

      }
      throw new IllegalStateException();
    }

    /** Returns true if field corresponding to fieldID is set (has been assigned a value) and false otherwise */
    public boolean isSet(_Fields field) {
      if (field == null) {
        throw new IllegalArgumentException();
      }

      switch (field) {
      case AUTHZ_TOKEN:
        return isSetAuthzToken();
      case JOB_SUBMISSION_INTERFACE_ID:
        return isSetJobSubmissionInterfaceId();
      case SSH_JOB_SUBMISSION:
        return isSetSshJobSubmission();
      }
      throw new IllegalStateException();
    }

    @Override
    public boolean equals(Object that) {
      if (that == null)
        return false;
      if (that instanceof updateCloudJobSubmissionDetails_args)
        return this.equals((updateCloudJobSubmissionDetails_args)that);
      return false;
    }

    public boolean equals(updateCloudJobSubmissionDetails_args that) {
      if (that == null)
        return false;

      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_jobSubmissionInterfaceId = true && this.isSetJobSubmissionInterfaceId();
      boolean that_present_jobSubmissionInterfaceId = true && that.isSetJobSubmissionInterfaceId();
      if (this_present_jobSubmissionInterfaceId || that_present_jobSubmissionInterfaceId) {
        if (!(this_present_jobSubmissionInterfaceId && that_present_jobSubmissionInterfaceId))
          return false;
        if (!this.jobSubmissionInterfaceId.equals(that.jobSubmissionInterfaceId))
          return false;
      }

      boolean this_present_sshJobSubmission = true && this.isSetSshJobSubmission();
      boolean that_present_sshJobSubmission = true && that.isSetSshJobSubmission();
      if (this_present_sshJobSubmission || that_present_sshJobSubmission) {
        if (!(this_present_sshJobSubmission && that_present_sshJobSubmission))
          return false;
        if (!this.sshJobSubmission.equals(that.sshJobSubmission))
          return false;
      }

      return true;
    }

    @Override
    public int hashCode() {
      List<Object> list = new ArrayList<Object>();

      boolean present_authzToken = true && (isSetAuthzToken());
      list.add(present_authzToken);
      if (present_authzToken)
        list.add(authzToken);

      boolean present_jobSubmissionInterfaceId = true && (isSetJobSubmissionInterfaceId());
      list.add(present_jobSubmissionInterfaceId);
      if (present_jobSubmissionInterfaceId)
        list.add(jobSubmissionInterfaceId);

      boolean present_sshJobSubmission = true && (isSetSshJobSubmission());
      list.add(present_sshJobSubmission);
      if (present_sshJobSubmission)
        list.add(sshJobSubmission);

      return list.hashCode();
    }

    @Override
    public int compareTo(updateCloudJobSubmissionDetails_args other) {
      if (!getClass().equals(other.getClass())) {
        return getClass().getName().compareTo(other.getClass().getName());
      }

      int lastComparison = 0;

      lastComparison = 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 = Boolean.valueOf(isSetJobSubmissionInterfaceId()).compareTo(other.isSetJobSubmissionInterfaceId());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetJobSubmissionInterfaceId()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.jobSubmissionInterfaceId, other.jobSubmissionInterfaceId);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = Boolean.valueOf(isSetSshJobSubmission()).compareTo(other.isSetSshJobSubmission());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetSshJobSubmission()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.sshJobSubmission, other.sshJobSubmission);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      return 0;
    }

    public _Fields fieldForId(int fieldId) {
      return _Fields.findByThriftId(fieldId);
    }

    public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
      schemes.get(iprot.getScheme()).getScheme().read(iprot, this);
    }

    public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException {
      schemes.get(oprot.getScheme()).getScheme().write(oprot, this);
    }

    @Override
    public String toString() {
      StringBuilder sb = new StringBuilder("updateCloudJobSubmissionDetails_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("jobSubmissionInterfaceId:");
      if (this.jobSubmissionInterfaceId == null) {
        sb.append("null");
      } else {
        sb.append(this.jobSubmissionInterfaceId);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("sshJobSubmission:");
      if (this.sshJobSubmission == null) {
        sb.append("null");
      } else {
        sb.append(this.sshJobSubmission);
      }
      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 (jobSubmissionInterfaceId == null) {
        throw new org.apache.thrift.protocol.TProtocolException("Required field 'jobSubmissionInterfaceId' was not present! Struct: " + toString());
      }
      if (sshJobSubmission == null) {
        throw new org.apache.thrift.protocol.TProtocolException("Required field 'sshJobSubmission' was not present! Struct: " + toString());
      }
      // check for sub-struct validity
      if (authzToken != null) {
        authzToken.validate();
      }
      if (sshJobSubmission != null) {
        sshJobSubmission.validate();
      }
    }

    private void writeObject(java.io.ObjectOutputStream out) throws java.io.IOException {
      try {
        write(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(out)));
      } catch (org.apache.thrift.TException te) {
        throw new java.io.IOException(te);
      }
    }

    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, ClassNotFoundException {
      try {
        read(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(in)));
      } catch (org.apache.thrift.TException te) {
        throw new java.io.IOException(te);
      }
    }

    private static class updateCloudJobSubmissionDetails_argsStandardSchemeFactory implements SchemeFactory {
      public updateCloudJobSubmissionDetails_argsStandardScheme getScheme() {
        return new updateCloudJobSubmissionDetails_argsStandardScheme();
      }
    }

    private static class updateCloudJobSubmissionDetails_argsStandardScheme extends StandardScheme<updateCloudJobSubmissionDetails_args> {

      public void read(org.apache.thrift.protocol.TProtocol iprot, updateCloudJobSubmissionDetails_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: // JOB_SUBMISSION_INTERFACE_ID
              if (schemeField.type == org.apache.thrift.protocol.TType.STRING) {
                struct.jobSubmissionInterfaceId = iprot.readString();
                struct.setJobSubmissionInterfaceIdIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 3: // SSH_JOB_SUBMISSION
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.sshJobSubmission = new org.apache.airavata.model.appcatalog.computeresource.CloudJobSubmission();
                struct.sshJobSubmission.read(iprot);
                struct.setSshJobSubmissionIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            default:
              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
          }
          iprot.readFieldEnd();
        }
        iprot.readStructEnd();

        // check for required fields of primitive type, which can't be checked in the validate method
        struct.validate();
      }

      public void write(org.apache.thrift.protocol.TProtocol oprot, updateCloudJobSubmissionDetails_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.jobSubmissionInterfaceId != null) {
          oprot.writeFieldBegin(JOB_SUBMISSION_INTERFACE_ID_FIELD_DESC);
          oprot.writeString(struct.jobSubmissionInterfaceId);
          oprot.writeFieldEnd();
        }
        if (struct.sshJobSubmission != null) {
          oprot.writeFieldBegin(SSH_JOB_SUBMISSION_FIELD_DESC);
          struct.sshJobSubmission.write(oprot);
          oprot.writeFieldEnd();
        }
        oprot.writeFieldStop();
        oprot.writeStructEnd();
      }

    }

    private static class updateCloudJobSubmissionDetails_argsTupleSchemeFactory implements SchemeFactory {
      public updateCloudJobSubmissionDetails_argsTupleScheme getScheme() {
        return new updateCloudJobSubmissionDetails_argsTupleScheme();
      }
    }

    private static class updateCloudJobSubmissionDetails_argsTupleScheme extends TupleScheme<updateCloudJobSubmissionDetails_args> {

      @Override
      public void write(org.apache.thrift.protocol.TProtocol prot, updateCloudJobSubmissionDetails_args struct) throws org.apache.thrift.TException {
        TTupleProtocol oprot = (TTupleProtocol) prot;
        struct.authzToken.write(oprot);
        oprot.writeString(struct.jobSubmissionInterfaceId);
        struct.sshJobSubmission.write(oprot);
      }

      @Override
      public void read(org.apache.thrift.protocol.TProtocol prot, updateCloudJobSubmissionDetails_args struct) throws org.apache.thrift.TException {
        TTupleProtocol iprot = (TTupleProtocol) prot;
        struct.authzToken = new org.apache.airavata.model.security.AuthzToken();
        struct.authzToken.read(iprot);
        struct.setAuthzTokenIsSet(true);
        struct.jobSubmissionInterfaceId = iprot.readString();
        struct.setJobSubmissionInterfaceIdIsSet(true);
        struct.sshJobSubmission = new org.apache.airavata.model.appcatalog.computeresource.CloudJobSubmission();
        struct.sshJobSubmission.read(iprot);
        struct.setSshJobSubmissionIsSet(true);
      }
    }

  }

  public static class updateCloudJobSubmissionDetails_result implements org.apache.thrift.TBase<updateCloudJobSubmissionDetails_result, updateCloudJobSubmissionDetails_result._Fields>, java.io.Serializable, Cloneable, Comparable<updateCloudJobSubmissionDetails_result>   {
    private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("updateCloudJobSubmissionDetails_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 IRE_FIELD_DESC = new org.apache.thrift.protocol.TField("ire", org.apache.thrift.protocol.TType.STRUCT, (short)1);
    private static final org.apache.thrift.protocol.TField ACE_FIELD_DESC = new org.apache.thrift.protocol.TField("ace", org.apache.thrift.protocol.TType.STRUCT, (short)2);
    private static final org.apache.thrift.protocol.TField ASE_FIELD_DESC = new org.apache.thrift.protocol.TField("ase", org.apache.thrift.protocol.TType.STRUCT, (short)3);
    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)4);

    private static final Map<Class<? extends IScheme>, SchemeFactory> schemes = new HashMap<Class<? extends IScheme>, SchemeFactory>();
    static {
      schemes.put(StandardScheme.class, new updateCloudJobSubmissionDetails_resultStandardSchemeFactory());
      schemes.put(TupleScheme.class, new updateCloudJobSubmissionDetails_resultTupleSchemeFactory());
    }

    public boolean success; // required
    public org.apache.airavata.model.error.InvalidRequestException ire; // required
    public org.apache.airavata.model.error.AiravataClientException ace; // required
    public org.apache.airavata.model.error.AiravataSystemException ase; // 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"),
      IRE((short)1, "ire"),
      ACE((short)2, "ace"),
      ASE((short)3, "ase"),
      AE((short)4, "ae");

      private static final Map<String, _Fields> byName = new HashMap<String, _Fields>();

      static {
        for (_Fields field : EnumSet.allOf(_Fields.class)) {
          byName.put(field.getFieldName(), field);
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, or null if its not found.
       */
      public static _Fields findByThriftId(int fieldId) {
        switch(fieldId) {
          case 0: // SUCCESS
            return SUCCESS;
          case 1: // IRE
            return IRE;
          case 2: // ACE
            return ACE;
          case 3: // ASE
            return ASE;
          case 4: // 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 IllegalArgumentException("Field " + fieldId + " doesn't exist!");
        return fields;
      }

      /**
       * Find the _Fields constant that matches name, or null if its not found.
       */
      public static _Fields findByName(String name) {
        return byName.get(name);
      }

      private final short _thriftId;
      private final String _fieldName;

      _Fields(short thriftId, String fieldName) {
        _thriftId = thriftId;
        _fieldName = fieldName;
      }

      public short getThriftFieldId() {
        return _thriftId;
      }

      public String getFieldName() {
        return _fieldName;
      }
    }

    // isset id assignments
    private static final int __SUCCESS_ISSET_ID = 0;
    private byte __isset_bitfield = 0;
    public static final Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
    static {
      Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new EnumMap<_Fields, org.apache.thrift.meta_data.FieldMetaData>(_Fields.class);
      tmpMap.put(_Fields.SUCCESS, new org.apache.thrift.meta_data.FieldMetaData("success", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.BOOL)));
      tmpMap.put(_Fields.IRE, new org.apache.thrift.meta_data.FieldMetaData("ire", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRUCT)));
      tmpMap.put(_Fields.ACE, new org.apache.thrift.meta_data.FieldMetaData("ace", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRUCT)));
      tmpMap.put(_Fields.ASE, new org.apache.thrift.meta_data.FieldMetaData("ase", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRUCT)));
      tmpMap.put(_Fields.AE, new org.apache.thrift.meta_data.FieldMetaData("ae", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRUCT)));
      metaDataMap = Collections.unmodifiableMap(tmpMap);
      org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(updateCloudJobSubmissionDetails_result.class, metaDataMap);
    }

    public updateCloudJobSubmissionDetails_result() {
    }

    public updateCloudJobSubmissionDetails_result(
      boolean success,
      org.apache.airavata.model.error.InvalidRequestException ire,
      org.apache.airavata.model.error.AiravataClientException ace,
      org.apache.airavata.model.error.AiravataSystemException ase,
      org.apache.airavata.model.error.AuthorizationException ae)
    {
      this();
      this.success = success;
      setSuccessIsSet(true);
      this.ire = ire;
      this.ace = ace;
      this.ase = ase;
      this.ae = ae;
    }

    /**
     * Performs a deep copy on <i>other</i>.
     */
    public updateCloudJobSubmissionDetails_result(updateCloudJobSubmissionDetails_result other) {
      __isset_bitfield = other.__isset_bitfield;
      this.success = other.success;
      if (other.isSetIre()) {
        this.ire = new org.apache.airavata.model.error.InvalidRequestException(other.ire);
      }
      if (other.isSetAce()) {
        this.ace = new org.apache.airavata.model.error.AiravataClientException(other.ace);
      }
      if (other.isSetAse()) {
        this.ase = new org.apache.airavata.model.error.AiravataSystemException(other.ase);
      }
      if (other.isSetAe()) {
        this.ae = new org.apache.airavata.model.error.AuthorizationException(other.ae);
      }
    }

    public updateCloudJobSubmissionDetails_result deepCopy() {
      return new updateCloudJobSubmissionDetails_result(this);
    }

    @Override
    public void clear() {
      setSuccessIsSet(false);
      this.success = false;
      this.ire = null;
      this.ace = null;
      this.ase = null;
      this.ae = null;
    }

    public boolean isSuccess() {
      return this.success;
    }

    public updateCloudJobSubmissionDetails_result setSuccess(boolean success) {
      this.success = success;
      setSuccessIsSet(true);
      return this;
    }

    public void unsetSuccess() {
      __isset_bitfield = EncodingUtils.clearBit(__isset_bitfield, __SUCCESS_ISSET_ID);
    }

    /** Returns true if field success is set (has been assigned a value) and false otherwise */
    public boolean isSetSuccess() {
      return EncodingUtils.testBit(__isset_bitfield, __SUCCESS_ISSET_ID);
    }

    public void setSuccessIsSet(boolean value) {
      __isset_bitfield = EncodingUtils.setBit(__isset_bitfield, __SUCCESS_ISSET_ID, value);
    }

    public org.apache.airavata.model.error.InvalidRequestException getIre() {
      return this.ire;
    }

    public updateCloudJobSubmissionDetails_result setIre(org.apache.airavata.model.error.InvalidRequestException ire) {
      this.ire = ire;
      return this;
    }

    public void unsetIre() {
      this.ire = null;
    }

    /** Returns true if field ire is set (has been assigned a value) and false otherwise */
    public boolean isSetIre() {
      return this.ire != null;
    }

    public void setIreIsSet(boolean value) {
      if (!value) {
        this.ire = null;
      }
    }

    public org.apache.airavata.model.error.AiravataClientException getAce() {
      return this.ace;
    }

    public updateCloudJobSubmissionDetails_result setAce(org.apache.airavata.model.error.AiravataClientException ace) {
      this.ace = ace;
      return this;
    }

    public void unsetAce() {
      this.ace = null;
    }

    /** Returns true if field ace is set (has been assigned a value) and false otherwise */
    public boolean isSetAce() {
      return this.ace != null;
    }

    public void setAceIsSet(boolean value) {
      if (!value) {
        this.ace = null;
      }
    }

    public org.apache.airavata.model.error.AiravataSystemException getAse() {
      return this.ase;
    }

    public updateCloudJobSubmissionDetails_result setAse(org.apache.airavata.model.error.AiravataSystemException ase) {
      this.ase = ase;
      return this;
    }

    public void unsetAse() {
      this.ase = null;
    }

    /** Returns true if field ase is set (has been assigned a value) and false otherwise */
    public boolean isSetAse() {
      return this.ase != null;
    }

    public void setAseIsSet(boolean value) {
      if (!value) {
        this.ase = null;
      }
    }

    public org.apache.airavata.model.error.AuthorizationException getAe() {
      return this.ae;
    }

    public updateCloudJobSubmissionDetails_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, Object value) {
      switch (field) {
      case SUCCESS:
        if (value == null) {
          unsetSuccess();
        } else {
          setSuccess((Boolean)value);
        }
        break;

      case IRE:
        if (value == null) {
          unsetIre();
        } else {
          setIre((org.apache.airavata.model.error.InvalidRequestException)value);
        }
        break;

      case ACE:
        if (value == null) {
          unsetAce();
        } else {
          setAce((org.apache.airavata.model.error.AiravataClientException)value);
        }
        break;

      case ASE:
        if (value == null) {
          unsetAse();
        } else {
          setAse((org.apache.airavata.model.error.AiravataSystemException)value);
        }
        break;

      case AE:
        if (value == null) {
          unsetAe();
        } else {
          setAe((org.apache.airavata.model.error.AuthorizationException)value);
        }
        break;

      }
    }

    public Object getFieldValue(_Fields field) {
      switch (field) {
      case SUCCESS:
        return Boolean.valueOf(isSuccess());

      case IRE:
        return getIre();

      case ACE:
        return getAce();

      case ASE:
        return getAse();

      case AE:
        return getAe();

      }
      throw new IllegalStateException();
    }

    /** Returns true if field corresponding to fieldID is set (has been assigned a value) and false otherwise */
    public boolean isSet(_Fields field) {
      if (field == null) {
        throw new IllegalArgumentException();
      }

      switch (field) {
      case SUCCESS:
        return isSetSuccess();
      case IRE:
        return isSetIre();
      case ACE:
        return isSetAce();
      case ASE:
        return isSetAse();
      case AE:
        return isSetAe();
      }
      throw new IllegalStateException();
    }

    @Override
    public boolean equals(Object that) {
      if (that == null)
        return false;
      if (that instanceof updateCloudJobSubmissionDetails_result)
        return this.equals((updateCloudJobSubmissionDetails_result)that);
      return false;
    }

    public boolean equals(updateCloudJobSubmissionDetails_result that) {
      if (that == null)
        return false;

      boolean this_present_success = true;
      boolean that_present_success = true;
      if (this_present_success || that_present_success) {
        if (!(this_present_success && that_present_success))
          return false;
        if (this.success != that.success)
          return false;
      }

      boolean this_present_ire = true && this.isSetIre();
      boolean that_present_ire = true && that.isSetIre();
      if (this_present_ire || that_present_ire) {
        if (!(this_present_ire && that_present_ire))
          return false;
        if (!this.ire.equals(that.ire))
          return false;
      }

      boolean this_present_ace = true && this.isSetAce();
      boolean that_present_ace = true && that.isSetAce();
      if (this_present_ace || that_present_ace) {
        if (!(this_present_ace && that_present_ace))
          return false;
        if (!this.ace.equals(that.ace))
          return false;
      }

      boolean this_present_ase = true && this.isSetAse();
      boolean that_present_ase = true && that.isSetAse();
      if (this_present_ase || that_present_ase) {
        if (!(this_present_ase && that_present_ase))
          return false;
        if (!this.ase.equals(that.ase))
          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() {
      List<Object> list = new ArrayList<Object>();

      boolean present_success = true;
      list.add(present_success);
      if (present_success)
        list.add(success);

      boolean present_ire = true && (isSetIre());
      list.add(present_ire);
      if (present_ire)
        list.add(ire);

      boolean present_ace = true && (isSetAce());
      list.add(present_ace);
      if (present_ace)
        list.add(ace);

      boolean present_ase = true && (isSetAse());
      list.add(present_ase);
      if (present_ase)
        list.add(ase);

      boolean present_ae = true && (isSetAe());
      list.add(present_ae);
      if (present_ae)
        list.add(ae);

      return list.hashCode();
    }

    @Override
    public int compareTo(updateCloudJobSubmissionDetails_result other) {
      if (!getClass().equals(other.getClass())) {
        return getClass().getName().compareTo(other.getClass().getName());
      }

      int lastComparison = 0;

      lastComparison = Boolean.valueOf(isSetSuccess()).compareTo(other.isSetSuccess());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetSuccess()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.success, other.success);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = Boolean.valueOf(isSetIre()).compareTo(other.isSetIre());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetIre()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.ire, other.ire);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = Boolean.valueOf(isSetAce()).compareTo(other.isSetAce());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetAce()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.ace, other.ace);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = Boolean.valueOf(isSetAse()).compareTo(other.isSetAse());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetAse()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.ase, other.ase);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = 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 {
      schemes.get(iprot.getScheme()).getScheme().read(iprot, this);
    }

    public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException {
      schemes.get(oprot.getScheme()).getScheme().write(oprot, this);
      }

    @Override
    public String toString() {
      StringBuilder sb = new StringBuilder("updateCloudJobSubmissionDetails_result(");
      boolean first = true;

      sb.append("success:");
      sb.append(this.success);
      first = false;
      if (!first) sb.append(", ");
      sb.append("ire:");
      if (this.ire == null) {
        sb.append("null");
      } else {
        sb.append(this.ire);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("ace:");
      if (this.ace == null) {
        sb.append("null");
      } else {
        sb.append(this.ace);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("ase:");
      if (this.ase == null) {
        sb.append("null");
      } else {
        sb.append(this.ase);
      }
      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, 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 updateCloudJobSubmissionDetails_resultStandardSchemeFactory implements SchemeFactory {
      public updateCloudJobSubmissionDetails_resultStandardScheme getScheme() {
        return new updateCloudJobSubmissionDetails_resultStandardScheme();
      }
    }

    private static class updateCloudJobSubmissionDetails_resultStandardScheme extends StandardScheme<updateCloudJobSubmissionDetails_result> {

      public void read(org.apache.thrift.protocol.TProtocol iprot, updateCloudJobSubmissionDetails_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: // IRE
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.ire = new org.apache.airavata.model.error.InvalidRequestException();
                struct.ire.read(iprot);
                struct.setIreIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 2: // ACE
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.ace = new org.apache.airavata.model.error.AiravataClientException();
                struct.ace.read(iprot);
                struct.setAceIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 3: // ASE
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.ase = new org.apache.airavata.model.error.AiravataSystemException();
                struct.ase.read(iprot);
                struct.setAseIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 4: // 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, updateCloudJobSubmissionDetails_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.ire != null) {
          oprot.writeFieldBegin(IRE_FIELD_DESC);
          struct.ire.write(oprot);
          oprot.writeFieldEnd();
        }
        if (struct.ace != null) {
          oprot.writeFieldBegin(ACE_FIELD_DESC);
          struct.ace.write(oprot);
          oprot.writeFieldEnd();
        }
        if (struct.ase != null) {
          oprot.writeFieldBegin(ASE_FIELD_DESC);
          struct.ase.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 updateCloudJobSubmissionDetails_resultTupleSchemeFactory implements SchemeFactory {
      public updateCloudJobSubmissionDetails_resultTupleScheme getScheme() {
        return new updateCloudJobSubmissionDetails_resultTupleScheme();
      }
    }

    private static class updateCloudJobSubmissionDetails_resultTupleScheme extends TupleScheme<updateCloudJobSubmissionDetails_result> {

      @Override
      public void write(org.apache.thrift.protocol.TProtocol prot, updateCloudJobSubmissionDetails_result struct) throws org.apache.thrift.TException {
        TTupleProtocol oprot = (TTupleProtocol) prot;
        BitSet optionals = new BitSet();
        if (struct.isSetSuccess()) {
          optionals.set(0);
        }
        if (struct.isSetIre()) {
          optionals.set(1);
        }
        if (struct.isSetAce()) {
          optionals.set(2);
        }
        if (struct.isSetAse()) {
          optionals.set(3);
        }
        if (struct.isSetAe()) {
          optionals.set(4);
        }
        oprot.writeBitSet(optionals, 5);
        if (struct.isSetSuccess()) {
          oprot.writeBool(struct.success);
        }
        if (struct.isSetIre()) {
          struct.ire.write(oprot);
        }
        if (struct.isSetAce()) {
          struct.ace.write(oprot);
        }
        if (struct.isSetAse()) {
          struct.ase.write(oprot);
        }
        if (struct.isSetAe()) {
          struct.ae.write(oprot);
        }
      }

      @Override
      public void read(org.apache.thrift.protocol.TProtocol prot, updateCloudJobSubmissionDetails_result struct) throws org.apache.thrift.TException {
        TTupleProtocol iprot = (TTupleProtocol) prot;
        BitSet incoming = iprot.readBitSet(5);
        if (incoming.get(0)) {
          struct.success = iprot.readBool();
          struct.setSuccessIsSet(true);
        }
        if (incoming.get(1)) {
          struct.ire = new org.apache.airavata.model.error.InvalidRequestException();
          struct.ire.read(iprot);
          struct.setIreIsSet(true);
        }
        if (incoming.get(2)) {
          struct.ace = new org.apache.airavata.model.error.AiravataClientException();
          struct.ace.read(iprot);
          struct.setAceIsSet(true);
        }
        if (incoming.get(3)) {
          struct.ase = new org.apache.airavata.model.error.AiravataSystemException();
          struct.ase.read(iprot);
          struct.setAseIsSet(true);
        }
        if (incoming.get(4)) {
          struct.ae = new org.apache.airavata.model.error.AuthorizationException();
          struct.ae.read(iprot);
          struct.setAeIsSet(true);
        }
      }
    }

  }

  public static class updateUnicoreJobSubmissionDetails_args implements org.apache.thrift.TBase<updateUnicoreJobSubmissionDetails_args, updateUnicoreJobSubmissionDetails_args._Fields>, java.io.Serializable, Cloneable, Comparable<updateUnicoreJobSubmissionDetails_args>   {
    private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("updateUnicoreJobSubmissionDetails_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 JOB_SUBMISSION_INTERFACE_ID_FIELD_DESC = new org.apache.thrift.protocol.TField("jobSubmissionInterfaceId", org.apache.thrift.protocol.TType.STRING, (short)2);
    private static final org.apache.thrift.protocol.TField UNICORE_JOB_SUBMISSION_FIELD_DESC = new org.apache.thrift.protocol.TField("unicoreJobSubmission", org.apache.thrift.protocol.TType.STRUCT, (short)3);

    private static final Map<Class<? extends IScheme>, SchemeFactory> schemes = new HashMap<Class<? extends IScheme>, SchemeFactory>();
    static {
      schemes.put(StandardScheme.class, new updateUnicoreJobSubmissionDetails_argsStandardSchemeFactory());
      schemes.put(TupleScheme.class, new updateUnicoreJobSubmissionDetails_argsTupleSchemeFactory());
    }

    public org.apache.airavata.model.security.AuthzToken authzToken; // required
    public String jobSubmissionInterfaceId; // required
    public org.apache.airavata.model.appcatalog.computeresource.UnicoreJobSubmission unicoreJobSubmission; // required

    /** 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"),
      JOB_SUBMISSION_INTERFACE_ID((short)2, "jobSubmissionInterfaceId"),
      UNICORE_JOB_SUBMISSION((short)3, "unicoreJobSubmission");

      private static final Map<String, _Fields> byName = new HashMap<String, _Fields>();

      static {
        for (_Fields field : EnumSet.allOf(_Fields.class)) {
          byName.put(field.getFieldName(), field);
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, or null if its not found.
       */
      public static _Fields findByThriftId(int fieldId) {
        switch(fieldId) {
          case 1: // AUTHZ_TOKEN
            return AUTHZ_TOKEN;
          case 2: // JOB_SUBMISSION_INTERFACE_ID
            return JOB_SUBMISSION_INTERFACE_ID;
          case 3: // UNICORE_JOB_SUBMISSION
            return UNICORE_JOB_SUBMISSION;
          default:
            return null;
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, throwing an exception
       * if it is not found.
       */
      public static _Fields findByThriftIdOrThrow(int fieldId) {
        _Fields fields = findByThriftId(fieldId);
        if (fields == null) throw new IllegalArgumentException("Field " + fieldId + " doesn't exist!");
        return fields;
      }

      /**
       * Find the _Fields constant that matches name, or null if its not found.
       */
      public static _Fields findByName(String name) {
        return byName.get(name);
      }

      private final short _thriftId;
      private final String _fieldName;

      _Fields(short thriftId, String fieldName) {
        _thriftId = thriftId;
        _fieldName = fieldName;
      }

      public short getThriftFieldId() {
        return _thriftId;
      }

      public String getFieldName() {
        return _fieldName;
      }
    }

    // isset id assignments
    public static final Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
    static {
      Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new EnumMap<_Fields, org.apache.thrift.meta_data.FieldMetaData>(_Fields.class);
      tmpMap.put(_Fields.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.JOB_SUBMISSION_INTERFACE_ID, new org.apache.thrift.meta_data.FieldMetaData("jobSubmissionInterfaceId", org.apache.thrift.TFieldRequirementType.REQUIRED, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING)));
      tmpMap.put(_Fields.UNICORE_JOB_SUBMISSION, new org.apache.thrift.meta_data.FieldMetaData("unicoreJobSubmission", org.apache.thrift.TFieldRequirementType.REQUIRED, 
          new org.apache.thrift.meta_data.StructMetaData(org.apache.thrift.protocol.TType.STRUCT, org.apache.airavata.model.appcatalog.computeresource.UnicoreJobSubmission.class)));
      metaDataMap = Collections.unmodifiableMap(tmpMap);
      org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(updateUnicoreJobSubmissionDetails_args.class, metaDataMap);
    }

    public updateUnicoreJobSubmissionDetails_args() {
    }

    public updateUnicoreJobSubmissionDetails_args(
      org.apache.airavata.model.security.AuthzToken authzToken,
      String jobSubmissionInterfaceId,
      org.apache.airavata.model.appcatalog.computeresource.UnicoreJobSubmission unicoreJobSubmission)
    {
      this();
      this.authzToken = authzToken;
      this.jobSubmissionInterfaceId = jobSubmissionInterfaceId;
      this.unicoreJobSubmission = unicoreJobSubmission;
    }

    /**
     * Performs a deep copy on <i>other</i>.
     */
    public updateUnicoreJobSubmissionDetails_args(updateUnicoreJobSubmissionDetails_args other) {
      if (other.isSetAuthzToken()) {
        this.authzToken = new org.apache.airavata.model.security.AuthzToken(other.authzToken);
      }
      if (other.isSetJobSubmissionInterfaceId()) {
        this.jobSubmissionInterfaceId = other.jobSubmissionInterfaceId;
      }
      if (other.isSetUnicoreJobSubmission()) {
        this.unicoreJobSubmission = new org.apache.airavata.model.appcatalog.computeresource.UnicoreJobSubmission(other.unicoreJobSubmission);
      }
    }

    public updateUnicoreJobSubmissionDetails_args deepCopy() {
      return new updateUnicoreJobSubmissionDetails_args(this);
    }

    @Override
    public void clear() {
      this.authzToken = null;
      this.jobSubmissionInterfaceId = null;
      this.unicoreJobSubmission = null;
    }

    public org.apache.airavata.model.security.AuthzToken getAuthzToken() {
      return this.authzToken;
    }

    public updateUnicoreJobSubmissionDetails_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 String getJobSubmissionInterfaceId() {
      return this.jobSubmissionInterfaceId;
    }

    public updateUnicoreJobSubmissionDetails_args setJobSubmissionInterfaceId(String jobSubmissionInterfaceId) {
      this.jobSubmissionInterfaceId = jobSubmissionInterfaceId;
      return this;
    }

    public void unsetJobSubmissionInterfaceId() {
      this.jobSubmissionInterfaceId = null;
    }

    /** Returns true if field jobSubmissionInterfaceId is set (has been assigned a value) and false otherwise */
    public boolean isSetJobSubmissionInterfaceId() {
      return this.jobSubmissionInterfaceId != null;
    }

    public void setJobSubmissionInterfaceIdIsSet(boolean value) {
      if (!value) {
        this.jobSubmissionInterfaceId = null;
      }
    }

    public org.apache.airavata.model.appcatalog.computeresource.UnicoreJobSubmission getUnicoreJobSubmission() {
      return this.unicoreJobSubmission;
    }

    public updateUnicoreJobSubmissionDetails_args setUnicoreJobSubmission(org.apache.airavata.model.appcatalog.computeresource.UnicoreJobSubmission unicoreJobSubmission) {
      this.unicoreJobSubmission = unicoreJobSubmission;
      return this;
    }

    public void unsetUnicoreJobSubmission() {
      this.unicoreJobSubmission = null;
    }

    /** Returns true if field unicoreJobSubmission is set (has been assigned a value) and false otherwise */
    public boolean isSetUnicoreJobSubmission() {
      return this.unicoreJobSubmission != null;
    }

    public void setUnicoreJobSubmissionIsSet(boolean value) {
      if (!value) {
        this.unicoreJobSubmission = null;
      }
    }

    public void setFieldValue(_Fields field, Object value) {
      switch (field) {
      case AUTHZ_TOKEN:
        if (value == null) {
          unsetAuthzToken();
        } else {
          setAuthzToken((org.apache.airavata.model.security.AuthzToken)value);
        }
        break;

      case JOB_SUBMISSION_INTERFACE_ID:
        if (value == null) {
          unsetJobSubmissionInterfaceId();
        } else {
          setJobSubmissionInterfaceId((String)value);
        }
        break;

      case UNICORE_JOB_SUBMISSION:
        if (value == null) {
          unsetUnicoreJobSubmission();
        } else {
          setUnicoreJobSubmission((org.apache.airavata.model.appcatalog.computeresource.UnicoreJobSubmission)value);
        }
        break;

      }
    }

    public Object getFieldValue(_Fields field) {
      switch (field) {
      case AUTHZ_TOKEN:
        return getAuthzToken();

      case JOB_SUBMISSION_INTERFACE_ID:
        return getJobSubmissionInterfaceId();

      case UNICORE_JOB_SUBMISSION:
        return getUnicoreJobSubmission();

      }
      throw new IllegalStateException();
    }

    /** Returns true if field corresponding to fieldID is set (has been assigned a value) and false otherwise */
    public boolean isSet(_Fields field) {
      if (field == null) {
        throw new IllegalArgumentException();
      }

      switch (field) {
      case AUTHZ_TOKEN:
        return isSetAuthzToken();
      case JOB_SUBMISSION_INTERFACE_ID:
        return isSetJobSubmissionInterfaceId();
      case UNICORE_JOB_SUBMISSION:
        return isSetUnicoreJobSubmission();
      }
      throw new IllegalStateException();
    }

    @Override
    public boolean equals(Object that) {
      if (that == null)
        return false;
      if (that instanceof updateUnicoreJobSubmissionDetails_args)
        return this.equals((updateUnicoreJobSubmissionDetails_args)that);
      return false;
    }

    public boolean equals(updateUnicoreJobSubmissionDetails_args that) {
      if (that == null)
        return false;

      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_jobSubmissionInterfaceId = true && this.isSetJobSubmissionInterfaceId();
      boolean that_present_jobSubmissionInterfaceId = true && that.isSetJobSubmissionInterfaceId();
      if (this_present_jobSubmissionInterfaceId || that_present_jobSubmissionInterfaceId) {
        if (!(this_present_jobSubmissionInterfaceId && that_present_jobSubmissionInterfaceId))
          return false;
        if (!this.jobSubmissionInterfaceId.equals(that.jobSubmissionInterfaceId))
          return false;
      }

      boolean this_present_unicoreJobSubmission = true && this.isSetUnicoreJobSubmission();
      boolean that_present_unicoreJobSubmission = true && that.isSetUnicoreJobSubmission();
      if (this_present_unicoreJobSubmission || that_present_unicoreJobSubmission) {
        if (!(this_present_unicoreJobSubmission && that_present_unicoreJobSubmission))
          return false;
        if (!this.unicoreJobSubmission.equals(that.unicoreJobSubmission))
          return false;
      }

      return true;
    }

    @Override
    public int hashCode() {
      List<Object> list = new ArrayList<Object>();

      boolean present_authzToken = true && (isSetAuthzToken());
      list.add(present_authzToken);
      if (present_authzToken)
        list.add(authzToken);

      boolean present_jobSubmissionInterfaceId = true && (isSetJobSubmissionInterfaceId());
      list.add(present_jobSubmissionInterfaceId);
      if (present_jobSubmissionInterfaceId)
        list.add(jobSubmissionInterfaceId);

      boolean present_unicoreJobSubmission = true && (isSetUnicoreJobSubmission());
      list.add(present_unicoreJobSubmission);
      if (present_unicoreJobSubmission)
        list.add(unicoreJobSubmission);

      return list.hashCode();
    }

    @Override
    public int compareTo(updateUnicoreJobSubmissionDetails_args other) {
      if (!getClass().equals(other.getClass())) {
        return getClass().getName().compareTo(other.getClass().getName());
      }

      int lastComparison = 0;

      lastComparison = 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 = Boolean.valueOf(isSetJobSubmissionInterfaceId()).compareTo(other.isSetJobSubmissionInterfaceId());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetJobSubmissionInterfaceId()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.jobSubmissionInterfaceId, other.jobSubmissionInterfaceId);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = Boolean.valueOf(isSetUnicoreJobSubmission()).compareTo(other.isSetUnicoreJobSubmission());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetUnicoreJobSubmission()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.unicoreJobSubmission, other.unicoreJobSubmission);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      return 0;
    }

    public _Fields fieldForId(int fieldId) {
      return _Fields.findByThriftId(fieldId);
    }

    public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
      schemes.get(iprot.getScheme()).getScheme().read(iprot, this);
    }

    public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException {
      schemes.get(oprot.getScheme()).getScheme().write(oprot, this);
    }

    @Override
    public String toString() {
      StringBuilder sb = new StringBuilder("updateUnicoreJobSubmissionDetails_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("jobSubmissionInterfaceId:");
      if (this.jobSubmissionInterfaceId == null) {
        sb.append("null");
      } else {
        sb.append(this.jobSubmissionInterfaceId);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("unicoreJobSubmission:");
      if (this.unicoreJobSubmission == null) {
        sb.append("null");
      } else {
        sb.append(this.unicoreJobSubmission);
      }
      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 (jobSubmissionInterfaceId == null) {
        throw new org.apache.thrift.protocol.TProtocolException("Required field 'jobSubmissionInterfaceId' was not present! Struct: " + toString());
      }
      if (unicoreJobSubmission == null) {
        throw new org.apache.thrift.protocol.TProtocolException("Required field 'unicoreJobSubmission' was not present! Struct: " + toString());
      }
      // check for sub-struct validity
      if (authzToken != null) {
        authzToken.validate();
      }
      if (unicoreJobSubmission != null) {
        unicoreJobSubmission.validate();
      }
    }

    private void writeObject(java.io.ObjectOutputStream out) throws java.io.IOException {
      try {
        write(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(out)));
      } catch (org.apache.thrift.TException te) {
        throw new java.io.IOException(te);
      }
    }

    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, ClassNotFoundException {
      try {
        read(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(in)));
      } catch (org.apache.thrift.TException te) {
        throw new java.io.IOException(te);
      }
    }

    private static class updateUnicoreJobSubmissionDetails_argsStandardSchemeFactory implements SchemeFactory {
      public updateUnicoreJobSubmissionDetails_argsStandardScheme getScheme() {
        return new updateUnicoreJobSubmissionDetails_argsStandardScheme();
      }
    }

    private static class updateUnicoreJobSubmissionDetails_argsStandardScheme extends StandardScheme<updateUnicoreJobSubmissionDetails_args> {

      public void read(org.apache.thrift.protocol.TProtocol iprot, updateUnicoreJobSubmissionDetails_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: // JOB_SUBMISSION_INTERFACE_ID
              if (schemeField.type == org.apache.thrift.protocol.TType.STRING) {
                struct.jobSubmissionInterfaceId = iprot.readString();
                struct.setJobSubmissionInterfaceIdIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 3: // UNICORE_JOB_SUBMISSION
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.unicoreJobSubmission = new org.apache.airavata.model.appcatalog.computeresource.UnicoreJobSubmission();
                struct.unicoreJobSubmission.read(iprot);
                struct.setUnicoreJobSubmissionIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            default:
              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
          }
          iprot.readFieldEnd();
        }
        iprot.readStructEnd();

        // check for required fields of primitive type, which can't be checked in the validate method
        struct.validate();
      }

      public void write(org.apache.thrift.protocol.TProtocol oprot, updateUnicoreJobSubmissionDetails_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.jobSubmissionInterfaceId != null) {
          oprot.writeFieldBegin(JOB_SUBMISSION_INTERFACE_ID_FIELD_DESC);
          oprot.writeString(struct.jobSubmissionInterfaceId);
          oprot.writeFieldEnd();
        }
        if (struct.unicoreJobSubmission != null) {
          oprot.writeFieldBegin(UNICORE_JOB_SUBMISSION_FIELD_DESC);
          struct.unicoreJobSubmission.write(oprot);
          oprot.writeFieldEnd();
        }
        oprot.writeFieldStop();
        oprot.writeStructEnd();
      }

    }

    private static class updateUnicoreJobSubmissionDetails_argsTupleSchemeFactory implements SchemeFactory {
      public updateUnicoreJobSubmissionDetails_argsTupleScheme getScheme() {
        return new updateUnicoreJobSubmissionDetails_argsTupleScheme();
      }
    }

    private static class updateUnicoreJobSubmissionDetails_argsTupleScheme extends TupleScheme<updateUnicoreJobSubmissionDetails_args> {

      @Override
      public void write(org.apache.thrift.protocol.TProtocol prot, updateUnicoreJobSubmissionDetails_args struct) throws org.apache.thrift.TException {
        TTupleProtocol oprot = (TTupleProtocol) prot;
        struct.authzToken.write(oprot);
        oprot.writeString(struct.jobSubmissionInterfaceId);
        struct.unicoreJobSubmission.write(oprot);
      }

      @Override
      public void read(org.apache.thrift.protocol.TProtocol prot, updateUnicoreJobSubmissionDetails_args struct) throws org.apache.thrift.TException {
        TTupleProtocol iprot = (TTupleProtocol) prot;
        struct.authzToken = new org.apache.airavata.model.security.AuthzToken();
        struct.authzToken.read(iprot);
        struct.setAuthzTokenIsSet(true);
        struct.jobSubmissionInterfaceId = iprot.readString();
        struct.setJobSubmissionInterfaceIdIsSet(true);
        struct.unicoreJobSubmission = new org.apache.airavata.model.appcatalog.computeresource.UnicoreJobSubmission();
        struct.unicoreJobSubmission.read(iprot);
        struct.setUnicoreJobSubmissionIsSet(true);
      }
    }

  }

  public static class updateUnicoreJobSubmissionDetails_result implements org.apache.thrift.TBase<updateUnicoreJobSubmissionDetails_result, updateUnicoreJobSubmissionDetails_result._Fields>, java.io.Serializable, Cloneable, Comparable<updateUnicoreJobSubmissionDetails_result>   {
    private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("updateUnicoreJobSubmissionDetails_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 IRE_FIELD_DESC = new org.apache.thrift.protocol.TField("ire", org.apache.thrift.protocol.TType.STRUCT, (short)1);
    private static final org.apache.thrift.protocol.TField ACE_FIELD_DESC = new org.apache.thrift.protocol.TField("ace", org.apache.thrift.protocol.TType.STRUCT, (short)2);
    private static final org.apache.thrift.protocol.TField ASE_FIELD_DESC = new org.apache.thrift.protocol.TField("ase", org.apache.thrift.protocol.TType.STRUCT, (short)3);
    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)4);

    private static final Map<Class<? extends IScheme>, SchemeFactory> schemes = new HashMap<Class<? extends IScheme>, SchemeFactory>();
    static {
      schemes.put(StandardScheme.class, new updateUnicoreJobSubmissionDetails_resultStandardSchemeFactory());
      schemes.put(TupleScheme.class, new updateUnicoreJobSubmissionDetails_resultTupleSchemeFactory());
    }

    public boolean success; // required
    public org.apache.airavata.model.error.InvalidRequestException ire; // required
    public org.apache.airavata.model.error.AiravataClientException ace; // required
    public org.apache.airavata.model.error.AiravataSystemException ase; // 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"),
      IRE((short)1, "ire"),
      ACE((short)2, "ace"),
      ASE((short)3, "ase"),
      AE((short)4, "ae");

      private static final Map<String, _Fields> byName = new HashMap<String, _Fields>();

      static {
        for (_Fields field : EnumSet.allOf(_Fields.class)) {
          byName.put(field.getFieldName(), field);
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, or null if its not found.
       */
      public static _Fields findByThriftId(int fieldId) {
        switch(fieldId) {
          case 0: // SUCCESS
            return SUCCESS;
          case 1: // IRE
            return IRE;
          case 2: // ACE
            return ACE;
          case 3: // ASE
            return ASE;
          case 4: // 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 IllegalArgumentException("Field " + fieldId + " doesn't exist!");
        return fields;
      }

      /**
       * Find the _Fields constant that matches name, or null if its not found.
       */
      public static _Fields findByName(String name) {
        return byName.get(name);
      }

      private final short _thriftId;
      private final String _fieldName;

      _Fields(short thriftId, String fieldName) {
        _thriftId = thriftId;
        _fieldName = fieldName;
      }

      public short getThriftFieldId() {
        return _thriftId;
      }

      public String getFieldName() {
        return _fieldName;
      }
    }

    // isset id assignments
    private static final int __SUCCESS_ISSET_ID = 0;
    private byte __isset_bitfield = 0;
    public static final Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
    static {
      Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new EnumMap<_Fields, org.apache.thrift.meta_data.FieldMetaData>(_Fields.class);
      tmpMap.put(_Fields.SUCCESS, new org.apache.thrift.meta_data.FieldMetaData("success", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.BOOL)));
      tmpMap.put(_Fields.IRE, new org.apache.thrift.meta_data.FieldMetaData("ire", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRUCT)));
      tmpMap.put(_Fields.ACE, new org.apache.thrift.meta_data.FieldMetaData("ace", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRUCT)));
      tmpMap.put(_Fields.ASE, new org.apache.thrift.meta_data.FieldMetaData("ase", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRUCT)));
      tmpMap.put(_Fields.AE, new org.apache.thrift.meta_data.FieldMetaData("ae", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRUCT)));
      metaDataMap = Collections.unmodifiableMap(tmpMap);
      org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(updateUnicoreJobSubmissionDetails_result.class, metaDataMap);
    }

    public updateUnicoreJobSubmissionDetails_result() {
    }

    public updateUnicoreJobSubmissionDetails_result(
      boolean success,
      org.apache.airavata.model.error.InvalidRequestException ire,
      org.apache.airavata.model.error.AiravataClientException ace,
      org.apache.airavata.model.error.AiravataSystemException ase,
      org.apache.airavata.model.error.AuthorizationException ae)
    {
      this();
      this.success = success;
      setSuccessIsSet(true);
      this.ire = ire;
      this.ace = ace;
      this.ase = ase;
      this.ae = ae;
    }

    /**
     * Performs a deep copy on <i>other</i>.
     */
    public updateUnicoreJobSubmissionDetails_result(updateUnicoreJobSubmissionDetails_result other) {
      __isset_bitfield = other.__isset_bitfield;
      this.success = other.success;
      if (other.isSetIre()) {
        this.ire = new org.apache.airavata.model.error.InvalidRequestException(other.ire);
      }
      if (other.isSetAce()) {
        this.ace = new org.apache.airavata.model.error.AiravataClientException(other.ace);
      }
      if (other.isSetAse()) {
        this.ase = new org.apache.airavata.model.error.AiravataSystemException(other.ase);
      }
      if (other.isSetAe()) {
        this.ae = new org.apache.airavata.model.error.AuthorizationException(other.ae);
      }
    }

    public updateUnicoreJobSubmissionDetails_result deepCopy() {
      return new updateUnicoreJobSubmissionDetails_result(this);
    }

    @Override
    public void clear() {
      setSuccessIsSet(false);
      this.success = false;
      this.ire = null;
      this.ace = null;
      this.ase = null;
      this.ae = null;
    }

    public boolean isSuccess() {
      return this.success;
    }

    public updateUnicoreJobSubmissionDetails_result setSuccess(boolean success) {
      this.success = success;
      setSuccessIsSet(true);
      return this;
    }

    public void unsetSuccess() {
      __isset_bitfield = EncodingUtils.clearBit(__isset_bitfield, __SUCCESS_ISSET_ID);
    }

    /** Returns true if field success is set (has been assigned a value) and false otherwise */
    public boolean isSetSuccess() {
      return EncodingUtils.testBit(__isset_bitfield, __SUCCESS_ISSET_ID);
    }

    public void setSuccessIsSet(boolean value) {
      __isset_bitfield = EncodingUtils.setBit(__isset_bitfield, __SUCCESS_ISSET_ID, value);
    }

    public org.apache.airavata.model.error.InvalidRequestException getIre() {
      return this.ire;
    }

    public updateUnicoreJobSubmissionDetails_result setIre(org.apache.airavata.model.error.InvalidRequestException ire) {
      this.ire = ire;
      return this;
    }

    public void unsetIre() {
      this.ire = null;
    }

    /** Returns true if field ire is set (has been assigned a value) and false otherwise */
    public boolean isSetIre() {
      return this.ire != null;
    }

    public void setIreIsSet(boolean value) {
      if (!value) {
        this.ire = null;
      }
    }

    public org.apache.airavata.model.error.AiravataClientException getAce() {
      return this.ace;
    }

    public updateUnicoreJobSubmissionDetails_result setAce(org.apache.airavata.model.error.AiravataClientException ace) {
      this.ace = ace;
      return this;
    }

    public void unsetAce() {
      this.ace = null;
    }

    /** Returns true if field ace is set (has been assigned a value) and false otherwise */
    public boolean isSetAce() {
      return this.ace != null;
    }

    public void setAceIsSet(boolean value) {
      if (!value) {
        this.ace = null;
      }
    }

    public org.apache.airavata.model.error.AiravataSystemException getAse() {
      return this.ase;
    }

    public updateUnicoreJobSubmissionDetails_result setAse(org.apache.airavata.model.error.AiravataSystemException ase) {
      this.ase = ase;
      return this;
    }

    public void unsetAse() {
      this.ase = null;
    }

    /** Returns true if field ase is set (has been assigned a value) and false otherwise */
    public boolean isSetAse() {
      return this.ase != null;
    }

    public void setAseIsSet(boolean value) {
      if (!value) {
        this.ase = null;
      }
    }

    public org.apache.airavata.model.error.AuthorizationException getAe() {
      return this.ae;
    }

    public updateUnicoreJobSubmissionDetails_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, Object value) {
      switch (field) {
      case SUCCESS:
        if (value == null) {
          unsetSuccess();
        } else {
          setSuccess((Boolean)value);
        }
        break;

      case IRE:
        if (value == null) {
          unsetIre();
        } else {
          setIre((org.apache.airavata.model.error.InvalidRequestException)value);
        }
        break;

      case ACE:
        if (value == null) {
          unsetAce();
        } else {
          setAce((org.apache.airavata.model.error.AiravataClientException)value);
        }
        break;

      case ASE:
        if (value == null) {
          unsetAse();
        } else {
          setAse((org.apache.airavata.model.error.AiravataSystemException)value);
        }
        break;

      case AE:
        if (value == null) {
          unsetAe();
        } else {
          setAe((org.apache.airavata.model.error.AuthorizationException)value);
        }
        break;

      }
    }

    public Object getFieldValue(_Fields field) {
      switch (field) {
      case SUCCESS:
        return Boolean.valueOf(isSuccess());

      case IRE:
        return getIre();

      case ACE:
        return getAce();

      case ASE:
        return getAse();

      case AE:
        return getAe();

      }
      throw new IllegalStateException();
    }

    /** Returns true if field corresponding to fieldID is set (has been assigned a value) and false otherwise */
    public boolean isSet(_Fields field) {
      if (field == null) {
        throw new IllegalArgumentException();
      }

      switch (field) {
      case SUCCESS:
        return isSetSuccess();
      case IRE:
        return isSetIre();
      case ACE:
        return isSetAce();
      case ASE:
        return isSetAse();
      case AE:
        return isSetAe();
      }
      throw new IllegalStateException();
    }

    @Override
    public boolean equals(Object that) {
      if (that == null)
        return false;
      if (that instanceof updateUnicoreJobSubmissionDetails_result)
        return this.equals((updateUnicoreJobSubmissionDetails_result)that);
      return false;
    }

    public boolean equals(updateUnicoreJobSubmissionDetails_result that) {
      if (that == null)
        return false;

      boolean this_present_success = true;
      boolean that_present_success = true;
      if (this_present_success || that_present_success) {
        if (!(this_present_success && that_present_success))
          return false;
        if (this.success != that.success)
          return false;
      }

      boolean this_present_ire = true && this.isSetIre();
      boolean that_present_ire = true && that.isSetIre();
      if (this_present_ire || that_present_ire) {
        if (!(this_present_ire && that_present_ire))
          return false;
        if (!this.ire.equals(that.ire))
          return false;
      }

      boolean this_present_ace = true && this.isSetAce();
      boolean that_present_ace = true && that.isSetAce();
      if (this_present_ace || that_present_ace) {
        if (!(this_present_ace && that_present_ace))
          return false;
        if (!this.ace.equals(that.ace))
          return false;
      }

      boolean this_present_ase = true && this.isSetAse();
      boolean that_present_ase = true && that.isSetAse();
      if (this_present_ase || that_present_ase) {
        if (!(this_present_ase && that_present_ase))
          return false;
        if (!this.ase.equals(that.ase))
          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() {
      List<Object> list = new ArrayList<Object>();

      boolean present_success = true;
      list.add(present_success);
      if (present_success)
        list.add(success);

      boolean present_ire = true && (isSetIre());
      list.add(present_ire);
      if (present_ire)
        list.add(ire);

      boolean present_ace = true && (isSetAce());
      list.add(present_ace);
      if (present_ace)
        list.add(ace);

      boolean present_ase = true && (isSetAse());
      list.add(present_ase);
      if (present_ase)
        list.add(ase);

      boolean present_ae = true && (isSetAe());
      list.add(present_ae);
      if (present_ae)
        list.add(ae);

      return list.hashCode();
    }

    @Override
    public int compareTo(updateUnicoreJobSubmissionDetails_result other) {
      if (!getClass().equals(other.getClass())) {
        return getClass().getName().compareTo(other.getClass().getName());
      }

      int lastComparison = 0;

      lastComparison = Boolean.valueOf(isSetSuccess()).compareTo(other.isSetSuccess());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetSuccess()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.success, other.success);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = Boolean.valueOf(isSetIre()).compareTo(other.isSetIre());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetIre()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.ire, other.ire);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = Boolean.valueOf(isSetAce()).compareTo(other.isSetAce());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetAce()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.ace, other.ace);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = Boolean.valueOf(isSetAse()).compareTo(other.isSetAse());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetAse()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.ase, other.ase);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = 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 {
      schemes.get(iprot.getScheme()).getScheme().read(iprot, this);
    }

    public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException {
      schemes.get(oprot.getScheme()).getScheme().write(oprot, this);
      }

    @Override
    public String toString() {
      StringBuilder sb = new StringBuilder("updateUnicoreJobSubmissionDetails_result(");
      boolean first = true;

      sb.append("success:");
      sb.append(this.success);
      first = false;
      if (!first) sb.append(", ");
      sb.append("ire:");
      if (this.ire == null) {
        sb.append("null");
      } else {
        sb.append(this.ire);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("ace:");
      if (this.ace == null) {
        sb.append("null");
      } else {
        sb.append(this.ace);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("ase:");
      if (this.ase == null) {
        sb.append("null");
      } else {
        sb.append(this.ase);
      }
      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, 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 updateUnicoreJobSubmissionDetails_resultStandardSchemeFactory implements SchemeFactory {
      public updateUnicoreJobSubmissionDetails_resultStandardScheme getScheme() {
        return new updateUnicoreJobSubmissionDetails_resultStandardScheme();
      }
    }

    private static class updateUnicoreJobSubmissionDetails_resultStandardScheme extends StandardScheme<updateUnicoreJobSubmissionDetails_result> {

      public void read(org.apache.thrift.protocol.TProtocol iprot, updateUnicoreJobSubmissionDetails_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: // IRE
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.ire = new org.apache.airavata.model.error.InvalidRequestException();
                struct.ire.read(iprot);
                struct.setIreIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 2: // ACE
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.ace = new org.apache.airavata.model.error.AiravataClientException();
                struct.ace.read(iprot);
                struct.setAceIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 3: // ASE
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.ase = new org.apache.airavata.model.error.AiravataSystemException();
                struct.ase.read(iprot);
                struct.setAseIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 4: // 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, updateUnicoreJobSubmissionDetails_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.ire != null) {
          oprot.writeFieldBegin(IRE_FIELD_DESC);
          struct.ire.write(oprot);
          oprot.writeFieldEnd();
        }
        if (struct.ace != null) {
          oprot.writeFieldBegin(ACE_FIELD_DESC);
          struct.ace.write(oprot);
          oprot.writeFieldEnd();
        }
        if (struct.ase != null) {
          oprot.writeFieldBegin(ASE_FIELD_DESC);
          struct.ase.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 updateUnicoreJobSubmissionDetails_resultTupleSchemeFactory implements SchemeFactory {
      public updateUnicoreJobSubmissionDetails_resultTupleScheme getScheme() {
        return new updateUnicoreJobSubmissionDetails_resultTupleScheme();
      }
    }

    private static class updateUnicoreJobSubmissionDetails_resultTupleScheme extends TupleScheme<updateUnicoreJobSubmissionDetails_result> {

      @Override
      public void write(org.apache.thrift.protocol.TProtocol prot, updateUnicoreJobSubmissionDetails_result struct) throws org.apache.thrift.TException {
        TTupleProtocol oprot = (TTupleProtocol) prot;
        BitSet optionals = new BitSet();
        if (struct.isSetSuccess()) {
          optionals.set(0);
        }
        if (struct.isSetIre()) {
          optionals.set(1);
        }
        if (struct.isSetAce()) {
          optionals.set(2);
        }
        if (struct.isSetAse()) {
          optionals.set(3);
        }
        if (struct.isSetAe()) {
          optionals.set(4);
        }
        oprot.writeBitSet(optionals, 5);
        if (struct.isSetSuccess()) {
          oprot.writeBool(struct.success);
        }
        if (struct.isSetIre()) {
          struct.ire.write(oprot);
        }
        if (struct.isSetAce()) {
          struct.ace.write(oprot);
        }
        if (struct.isSetAse()) {
          struct.ase.write(oprot);
        }
        if (struct.isSetAe()) {
          struct.ae.write(oprot);
        }
      }

      @Override
      public void read(org.apache.thrift.protocol.TProtocol prot, updateUnicoreJobSubmissionDetails_result struct) throws org.apache.thrift.TException {
        TTupleProtocol iprot = (TTupleProtocol) prot;
        BitSet incoming = iprot.readBitSet(5);
        if (incoming.get(0)) {
          struct.success = iprot.readBool();
          struct.setSuccessIsSet(true);
        }
        if (incoming.get(1)) {
          struct.ire = new org.apache.airavata.model.error.InvalidRequestException();
          struct.ire.read(iprot);
          struct.setIreIsSet(true);
        }
        if (incoming.get(2)) {
          struct.ace = new org.apache.airavata.model.error.AiravataClientException();
          struct.ace.read(iprot);
          struct.setAceIsSet(true);
        }
        if (incoming.get(3)) {
          struct.ase = new org.apache.airavata.model.error.AiravataSystemException();
          struct.ase.read(iprot);
          struct.setAseIsSet(true);
        }
        if (incoming.get(4)) {
          struct.ae = new org.apache.airavata.model.error.AuthorizationException();
          struct.ae.read(iprot);
          struct.setAeIsSet(true);
        }
      }
    }

  }

  public static class addLocalDataMovementDetails_args implements org.apache.thrift.TBase<addLocalDataMovementDetails_args, addLocalDataMovementDetails_args._Fields>, java.io.Serializable, Cloneable, Comparable<addLocalDataMovementDetails_args>   {
    private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("addLocalDataMovementDetails_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 COMPUTE_RESOURCE_ID_FIELD_DESC = new org.apache.thrift.protocol.TField("computeResourceId", org.apache.thrift.protocol.TType.STRING, (short)2);
    private static final org.apache.thrift.protocol.TField PRIORITY_ORDER_FIELD_DESC = new org.apache.thrift.protocol.TField("priorityOrder", org.apache.thrift.protocol.TType.I32, (short)3);
    private static final org.apache.thrift.protocol.TField LOCAL_DATA_MOVEMENT_FIELD_DESC = new org.apache.thrift.protocol.TField("localDataMovement", org.apache.thrift.protocol.TType.STRUCT, (short)4);

    private static final Map<Class<? extends IScheme>, SchemeFactory> schemes = new HashMap<Class<? extends IScheme>, SchemeFactory>();
    static {
      schemes.put(StandardScheme.class, new addLocalDataMovementDetails_argsStandardSchemeFactory());
      schemes.put(TupleScheme.class, new addLocalDataMovementDetails_argsTupleSchemeFactory());
    }

    public org.apache.airavata.model.security.AuthzToken authzToken; // required
    public String computeResourceId; // required
    public int priorityOrder; // required
    public org.apache.airavata.model.appcatalog.computeresource.LOCALDataMovement localDataMovement; // required

    /** 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"),
      COMPUTE_RESOURCE_ID((short)2, "computeResourceId"),
      PRIORITY_ORDER((short)3, "priorityOrder"),
      LOCAL_DATA_MOVEMENT((short)4, "localDataMovement");

      private static final Map<String, _Fields> byName = new HashMap<String, _Fields>();

      static {
        for (_Fields field : EnumSet.allOf(_Fields.class)) {
          byName.put(field.getFieldName(), field);
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, or null if its not found.
       */
      public static _Fields findByThriftId(int fieldId) {
        switch(fieldId) {
          case 1: // AUTHZ_TOKEN
            return AUTHZ_TOKEN;
          case 2: // COMPUTE_RESOURCE_ID
            return COMPUTE_RESOURCE_ID;
          case 3: // PRIORITY_ORDER
            return PRIORITY_ORDER;
          case 4: // LOCAL_DATA_MOVEMENT
            return LOCAL_DATA_MOVEMENT;
          default:
            return null;
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, throwing an exception
       * if it is not found.
       */
      public static _Fields findByThriftIdOrThrow(int fieldId) {
        _Fields fields = findByThriftId(fieldId);
        if (fields == null) throw new IllegalArgumentException("Field " + fieldId + " doesn't exist!");
        return fields;
      }

      /**
       * Find the _Fields constant that matches name, or null if its not found.
       */
      public static _Fields findByName(String name) {
        return byName.get(name);
      }

      private final short _thriftId;
      private final String _fieldName;

      _Fields(short thriftId, String fieldName) {
        _thriftId = thriftId;
        _fieldName = fieldName;
      }

      public short getThriftFieldId() {
        return _thriftId;
      }

      public String getFieldName() {
        return _fieldName;
      }
    }

    // isset id assignments
    private static final int __PRIORITYORDER_ISSET_ID = 0;
    private byte __isset_bitfield = 0;
    public static final Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
    static {
      Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new EnumMap<_Fields, org.apache.thrift.meta_data.FieldMetaData>(_Fields.class);
      tmpMap.put(_Fields.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.COMPUTE_RESOURCE_ID, new org.apache.thrift.meta_data.FieldMetaData("computeResourceId", org.apache.thrift.TFieldRequirementType.REQUIRED, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING)));
      tmpMap.put(_Fields.PRIORITY_ORDER, new org.apache.thrift.meta_data.FieldMetaData("priorityOrder", org.apache.thrift.TFieldRequirementType.REQUIRED, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.I32)));
      tmpMap.put(_Fields.LOCAL_DATA_MOVEMENT, new org.apache.thrift.meta_data.FieldMetaData("localDataMovement", org.apache.thrift.TFieldRequirementType.REQUIRED, 
          new org.apache.thrift.meta_data.StructMetaData(org.apache.thrift.protocol.TType.STRUCT, org.apache.airavata.model.appcatalog.computeresource.LOCALDataMovement.class)));
      metaDataMap = Collections.unmodifiableMap(tmpMap);
      org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(addLocalDataMovementDetails_args.class, metaDataMap);
    }

    public addLocalDataMovementDetails_args() {
    }

    public addLocalDataMovementDetails_args(
      org.apache.airavata.model.security.AuthzToken authzToken,
      String computeResourceId,
      int priorityOrder,
      org.apache.airavata.model.appcatalog.computeresource.LOCALDataMovement localDataMovement)
    {
      this();
      this.authzToken = authzToken;
      this.computeResourceId = computeResourceId;
      this.priorityOrder = priorityOrder;
      setPriorityOrderIsSet(true);
      this.localDataMovement = localDataMovement;
    }

    /**
     * Performs a deep copy on <i>other</i>.
     */
    public addLocalDataMovementDetails_args(addLocalDataMovementDetails_args other) {
      __isset_bitfield = other.__isset_bitfield;
      if (other.isSetAuthzToken()) {
        this.authzToken = new org.apache.airavata.model.security.AuthzToken(other.authzToken);
      }
      if (other.isSetComputeResourceId()) {
        this.computeResourceId = other.computeResourceId;
      }
      this.priorityOrder = other.priorityOrder;
      if (other.isSetLocalDataMovement()) {
        this.localDataMovement = new org.apache.airavata.model.appcatalog.computeresource.LOCALDataMovement(other.localDataMovement);
      }
    }

    public addLocalDataMovementDetails_args deepCopy() {
      return new addLocalDataMovementDetails_args(this);
    }

    @Override
    public void clear() {
      this.authzToken = null;
      this.computeResourceId = null;
      setPriorityOrderIsSet(false);
      this.priorityOrder = 0;
      this.localDataMovement = null;
    }

    public org.apache.airavata.model.security.AuthzToken getAuthzToken() {
      return this.authzToken;
    }

    public addLocalDataMovementDetails_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 String getComputeResourceId() {
      return this.computeResourceId;
    }

    public addLocalDataMovementDetails_args setComputeResourceId(String computeResourceId) {
      this.computeResourceId = computeResourceId;
      return this;
    }

    public void unsetComputeResourceId() {
      this.computeResourceId = null;
    }

    /** Returns true if field computeResourceId is set (has been assigned a value) and false otherwise */
    public boolean isSetComputeResourceId() {
      return this.computeResourceId != null;
    }

    public void setComputeResourceIdIsSet(boolean value) {
      if (!value) {
        this.computeResourceId = null;
      }
    }

    public int getPriorityOrder() {
      return this.priorityOrder;
    }

    public addLocalDataMovementDetails_args setPriorityOrder(int priorityOrder) {
      this.priorityOrder = priorityOrder;
      setPriorityOrderIsSet(true);
      return this;
    }

    public void unsetPriorityOrder() {
      __isset_bitfield = EncodingUtils.clearBit(__isset_bitfield, __PRIORITYORDER_ISSET_ID);
    }

    /** Returns true if field priorityOrder is set (has been assigned a value) and false otherwise */
    public boolean isSetPriorityOrder() {
      return EncodingUtils.testBit(__isset_bitfield, __PRIORITYORDER_ISSET_ID);
    }

    public void setPriorityOrderIsSet(boolean value) {
      __isset_bitfield = EncodingUtils.setBit(__isset_bitfield, __PRIORITYORDER_ISSET_ID, value);
    }

    public org.apache.airavata.model.appcatalog.computeresource.LOCALDataMovement getLocalDataMovement() {
      return this.localDataMovement;
    }

    public addLocalDataMovementDetails_args setLocalDataMovement(org.apache.airavata.model.appcatalog.computeresource.LOCALDataMovement localDataMovement) {
      this.localDataMovement = localDataMovement;
      return this;
    }

    public void unsetLocalDataMovement() {
      this.localDataMovement = null;
    }

    /** Returns true if field localDataMovement is set (has been assigned a value) and false otherwise */
    public boolean isSetLocalDataMovement() {
      return this.localDataMovement != null;
    }

    public void setLocalDataMovementIsSet(boolean value) {
      if (!value) {
        this.localDataMovement = null;
      }
    }

    public void setFieldValue(_Fields field, Object value) {
      switch (field) {
      case AUTHZ_TOKEN:
        if (value == null) {
          unsetAuthzToken();
        } else {
          setAuthzToken((org.apache.airavata.model.security.AuthzToken)value);
        }
        break;

      case COMPUTE_RESOURCE_ID:
        if (value == null) {
          unsetComputeResourceId();
        } else {
          setComputeResourceId((String)value);
        }
        break;

      case PRIORITY_ORDER:
        if (value == null) {
          unsetPriorityOrder();
        } else {
          setPriorityOrder((Integer)value);
        }
        break;

      case LOCAL_DATA_MOVEMENT:
        if (value == null) {
          unsetLocalDataMovement();
        } else {
          setLocalDataMovement((org.apache.airavata.model.appcatalog.computeresource.LOCALDataMovement)value);
        }
        break;

      }
    }

    public Object getFieldValue(_Fields field) {
      switch (field) {
      case AUTHZ_TOKEN:
        return getAuthzToken();

      case COMPUTE_RESOURCE_ID:
        return getComputeResourceId();

      case PRIORITY_ORDER:
        return Integer.valueOf(getPriorityOrder());

      case LOCAL_DATA_MOVEMENT:
        return getLocalDataMovement();

      }
      throw new IllegalStateException();
    }

    /** Returns true if field corresponding to fieldID is set (has been assigned a value) and false otherwise */
    public boolean isSet(_Fields field) {
      if (field == null) {
        throw new IllegalArgumentException();
      }

      switch (field) {
      case AUTHZ_TOKEN:
        return isSetAuthzToken();
      case COMPUTE_RESOURCE_ID:
        return isSetComputeResourceId();
      case PRIORITY_ORDER:
        return isSetPriorityOrder();
      case LOCAL_DATA_MOVEMENT:
        return isSetLocalDataMovement();
      }
      throw new IllegalStateException();
    }

    @Override
    public boolean equals(Object that) {
      if (that == null)
        return false;
      if (that instanceof addLocalDataMovementDetails_args)
        return this.equals((addLocalDataMovementDetails_args)that);
      return false;
    }

    public boolean equals(addLocalDataMovementDetails_args that) {
      if (that == null)
        return false;

      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_computeResourceId = true && this.isSetComputeResourceId();
      boolean that_present_computeResourceId = true && that.isSetComputeResourceId();
      if (this_present_computeResourceId || that_present_computeResourceId) {
        if (!(this_present_computeResourceId && that_present_computeResourceId))
          return false;
        if (!this.computeResourceId.equals(that.computeResourceId))
          return false;
      }

      boolean this_present_priorityOrder = true;
      boolean that_present_priorityOrder = true;
      if (this_present_priorityOrder || that_present_priorityOrder) {
        if (!(this_present_priorityOrder && that_present_priorityOrder))
          return false;
        if (this.priorityOrder != that.priorityOrder)
          return false;
      }

      boolean this_present_localDataMovement = true && this.isSetLocalDataMovement();
      boolean that_present_localDataMovement = true && that.isSetLocalDataMovement();
      if (this_present_localDataMovement || that_present_localDataMovement) {
        if (!(this_present_localDataMovement && that_present_localDataMovement))
          return false;
        if (!this.localDataMovement.equals(that.localDataMovement))
          return false;
      }

      return true;
    }

    @Override
    public int hashCode() {
      List<Object> list = new ArrayList<Object>();

      boolean present_authzToken = true && (isSetAuthzToken());
      list.add(present_authzToken);
      if (present_authzToken)
        list.add(authzToken);

      boolean present_computeResourceId = true && (isSetComputeResourceId());
      list.add(present_computeResourceId);
      if (present_computeResourceId)
        list.add(computeResourceId);

      boolean present_priorityOrder = true;
      list.add(present_priorityOrder);
      if (present_priorityOrder)
        list.add(priorityOrder);

      boolean present_localDataMovement = true && (isSetLocalDataMovement());
      list.add(present_localDataMovement);
      if (present_localDataMovement)
        list.add(localDataMovement);

      return list.hashCode();
    }

    @Override
    public int compareTo(addLocalDataMovementDetails_args other) {
      if (!getClass().equals(other.getClass())) {
        return getClass().getName().compareTo(other.getClass().getName());
      }

      int lastComparison = 0;

      lastComparison = 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 = Boolean.valueOf(isSetComputeResourceId()).compareTo(other.isSetComputeResourceId());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetComputeResourceId()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.computeResourceId, other.computeResourceId);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = Boolean.valueOf(isSetPriorityOrder()).compareTo(other.isSetPriorityOrder());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetPriorityOrder()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.priorityOrder, other.priorityOrder);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = Boolean.valueOf(isSetLocalDataMovement()).compareTo(other.isSetLocalDataMovement());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetLocalDataMovement()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.localDataMovement, other.localDataMovement);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      return 0;
    }

    public _Fields fieldForId(int fieldId) {
      return _Fields.findByThriftId(fieldId);
    }

    public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
      schemes.get(iprot.getScheme()).getScheme().read(iprot, this);
    }

    public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException {
      schemes.get(oprot.getScheme()).getScheme().write(oprot, this);
    }

    @Override
    public String toString() {
      StringBuilder sb = new StringBuilder("addLocalDataMovementDetails_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("computeResourceId:");
      if (this.computeResourceId == null) {
        sb.append("null");
      } else {
        sb.append(this.computeResourceId);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("priorityOrder:");
      sb.append(this.priorityOrder);
      first = false;
      if (!first) sb.append(", ");
      sb.append("localDataMovement:");
      if (this.localDataMovement == null) {
        sb.append("null");
      } else {
        sb.append(this.localDataMovement);
      }
      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 (computeResourceId == null) {
        throw new org.apache.thrift.protocol.TProtocolException("Required field 'computeResourceId' was not present! Struct: " + toString());
      }
      // alas, we cannot check 'priorityOrder' because it's a primitive and you chose the non-beans generator.
      if (localDataMovement == null) {
        throw new org.apache.thrift.protocol.TProtocolException("Required field 'localDataMovement' was not present! Struct: " + toString());
      }
      // check for sub-struct validity
      if (authzToken != null) {
        authzToken.validate();
      }
      if (localDataMovement != null) {
        localDataMovement.validate();
      }
    }

    private void writeObject(java.io.ObjectOutputStream out) throws java.io.IOException {
      try {
        write(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(out)));
      } catch (org.apache.thrift.TException te) {
        throw new java.io.IOException(te);
      }
    }

    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, ClassNotFoundException {
      try {
        // 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 addLocalDataMovementDetails_argsStandardSchemeFactory implements SchemeFactory {
      public addLocalDataMovementDetails_argsStandardScheme getScheme() {
        return new addLocalDataMovementDetails_argsStandardScheme();
      }
    }

    private static class addLocalDataMovementDetails_argsStandardScheme extends StandardScheme<addLocalDataMovementDetails_args> {

      public void read(org.apache.thrift.protocol.TProtocol iprot, addLocalDataMovementDetails_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: // COMPUTE_RESOURCE_ID
              if (schemeField.type == org.apache.thrift.protocol.TType.STRING) {
                struct.computeResourceId = iprot.readString();
                struct.setComputeResourceIdIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 3: // PRIORITY_ORDER
              if (schemeField.type == org.apache.thrift.protocol.TType.I32) {
                struct.priorityOrder = iprot.readI32();
                struct.setPriorityOrderIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 4: // LOCAL_DATA_MOVEMENT
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.localDataMovement = new org.apache.airavata.model.appcatalog.computeresource.LOCALDataMovement();
                struct.localDataMovement.read(iprot);
                struct.setLocalDataMovementIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            default:
              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
          }
          iprot.readFieldEnd();
        }
        iprot.readStructEnd();

        // check for required fields of primitive type, which can't be checked in the validate method
        if (!struct.isSetPriorityOrder()) {
          throw new org.apache.thrift.protocol.TProtocolException("Required field 'priorityOrder' was not found in serialized data! Struct: " + toString());
        }
        struct.validate();
      }

      public void write(org.apache.thrift.protocol.TProtocol oprot, addLocalDataMovementDetails_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.computeResourceId != null) {
          oprot.writeFieldBegin(COMPUTE_RESOURCE_ID_FIELD_DESC);
          oprot.writeString(struct.computeResourceId);
          oprot.writeFieldEnd();
        }
        oprot.writeFieldBegin(PRIORITY_ORDER_FIELD_DESC);
        oprot.writeI32(struct.priorityOrder);
        oprot.writeFieldEnd();
        if (struct.localDataMovement != null) {
          oprot.writeFieldBegin(LOCAL_DATA_MOVEMENT_FIELD_DESC);
          struct.localDataMovement.write(oprot);
          oprot.writeFieldEnd();
        }
        oprot.writeFieldStop();
        oprot.writeStructEnd();
      }

    }

    private static class addLocalDataMovementDetails_argsTupleSchemeFactory implements SchemeFactory {
      public addLocalDataMovementDetails_argsTupleScheme getScheme() {
        return new addLocalDataMovementDetails_argsTupleScheme();
      }
    }

    private static class addLocalDataMovementDetails_argsTupleScheme extends TupleScheme<addLocalDataMovementDetails_args> {

      @Override
      public void write(org.apache.thrift.protocol.TProtocol prot, addLocalDataMovementDetails_args struct) throws org.apache.thrift.TException {
        TTupleProtocol oprot = (TTupleProtocol) prot;
        struct.authzToken.write(oprot);
        oprot.writeString(struct.computeResourceId);
        oprot.writeI32(struct.priorityOrder);
        struct.localDataMovement.write(oprot);
      }

      @Override
      public void read(org.apache.thrift.protocol.TProtocol prot, addLocalDataMovementDetails_args struct) throws org.apache.thrift.TException {
        TTupleProtocol iprot = (TTupleProtocol) prot;
        struct.authzToken = new org.apache.airavata.model.security.AuthzToken();
        struct.authzToken.read(iprot);
        struct.setAuthzTokenIsSet(true);
        struct.computeResourceId = iprot.readString();
        struct.setComputeResourceIdIsSet(true);
        struct.priorityOrder = iprot.readI32();
        struct.setPriorityOrderIsSet(true);
        struct.localDataMovement = new org.apache.airavata.model.appcatalog.computeresource.LOCALDataMovement();
        struct.localDataMovement.read(iprot);
        struct.setLocalDataMovementIsSet(true);
      }
    }

  }

  public static class addLocalDataMovementDetails_result implements org.apache.thrift.TBase<addLocalDataMovementDetails_result, addLocalDataMovementDetails_result._Fields>, java.io.Serializable, Cloneable, Comparable<addLocalDataMovementDetails_result>   {
    private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("addLocalDataMovementDetails_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 IRE_FIELD_DESC = new org.apache.thrift.protocol.TField("ire", org.apache.thrift.protocol.TType.STRUCT, (short)1);
    private static final org.apache.thrift.protocol.TField ACE_FIELD_DESC = new org.apache.thrift.protocol.TField("ace", org.apache.thrift.protocol.TType.STRUCT, (short)2);
    private static final org.apache.thrift.protocol.TField ASE_FIELD_DESC = new org.apache.thrift.protocol.TField("ase", org.apache.thrift.protocol.TType.STRUCT, (short)3);
    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)4);

    private static final Map<Class<? extends IScheme>, SchemeFactory> schemes = new HashMap<Class<? extends IScheme>, SchemeFactory>();
    static {
      schemes.put(StandardScheme.class, new addLocalDataMovementDetails_resultStandardSchemeFactory());
      schemes.put(TupleScheme.class, new addLocalDataMovementDetails_resultTupleSchemeFactory());
    }

    public String success; // required
    public org.apache.airavata.model.error.InvalidRequestException ire; // required
    public org.apache.airavata.model.error.AiravataClientException ace; // required
    public org.apache.airavata.model.error.AiravataSystemException ase; // 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"),
      IRE((short)1, "ire"),
      ACE((short)2, "ace"),
      ASE((short)3, "ase"),
      AE((short)4, "ae");

      private static final Map<String, _Fields> byName = new HashMap<String, _Fields>();

      static {
        for (_Fields field : EnumSet.allOf(_Fields.class)) {
          byName.put(field.getFieldName(), field);
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, or null if its not found.
       */
      public static _Fields findByThriftId(int fieldId) {
        switch(fieldId) {
          case 0: // SUCCESS
            return SUCCESS;
          case 1: // IRE
            return IRE;
          case 2: // ACE
            return ACE;
          case 3: // ASE
            return ASE;
          case 4: // 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 IllegalArgumentException("Field " + fieldId + " doesn't exist!");
        return fields;
      }

      /**
       * Find the _Fields constant that matches name, or null if its not found.
       */
      public static _Fields findByName(String name) {
        return byName.get(name);
      }

      private final short _thriftId;
      private final String _fieldName;

      _Fields(short thriftId, String fieldName) {
        _thriftId = thriftId;
        _fieldName = fieldName;
      }

      public short getThriftFieldId() {
        return _thriftId;
      }

      public String getFieldName() {
        return _fieldName;
      }
    }

    // isset id assignments
    public static final Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
    static {
      Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new EnumMap<_Fields, org.apache.thrift.meta_data.FieldMetaData>(_Fields.class);
      tmpMap.put(_Fields.SUCCESS, new org.apache.thrift.meta_data.FieldMetaData("success", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING)));
      tmpMap.put(_Fields.IRE, new org.apache.thrift.meta_data.FieldMetaData("ire", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRUCT)));
      tmpMap.put(_Fields.ACE, new org.apache.thrift.meta_data.FieldMetaData("ace", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRUCT)));
      tmpMap.put(_Fields.ASE, new org.apache.thrift.meta_data.FieldMetaData("ase", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRUCT)));
      tmpMap.put(_Fields.AE, new org.apache.thrift.meta_data.FieldMetaData("ae", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRUCT)));
      metaDataMap = Collections.unmodifiableMap(tmpMap);
      org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(addLocalDataMovementDetails_result.class, metaDataMap);
    }

    public addLocalDataMovementDetails_result() {
    }

    public addLocalDataMovementDetails_result(
      String success,
      org.apache.airavata.model.error.InvalidRequestException ire,
      org.apache.airavata.model.error.AiravataClientException ace,
      org.apache.airavata.model.error.AiravataSystemException ase,
      org.apache.airavata.model.error.AuthorizationException ae)
    {
      this();
      this.success = success;
      this.ire = ire;
      this.ace = ace;
      this.ase = ase;
      this.ae = ae;
    }

    /**
     * Performs a deep copy on <i>other</i>.
     */
    public addLocalDataMovementDetails_result(addLocalDataMovementDetails_result other) {
      if (other.isSetSuccess()) {
        this.success = other.success;
      }
      if (other.isSetIre()) {
        this.ire = new org.apache.airavata.model.error.InvalidRequestException(other.ire);
      }
      if (other.isSetAce()) {
        this.ace = new org.apache.airavata.model.error.AiravataClientException(other.ace);
      }
      if (other.isSetAse()) {
        this.ase = new org.apache.airavata.model.error.AiravataSystemException(other.ase);
      }
      if (other.isSetAe()) {
        this.ae = new org.apache.airavata.model.error.AuthorizationException(other.ae);
      }
    }

    public addLocalDataMovementDetails_result deepCopy() {
      return new addLocalDataMovementDetails_result(this);
    }

    @Override
    public void clear() {
      this.success = null;
      this.ire = null;
      this.ace = null;
      this.ase = null;
      this.ae = null;
    }

    public String getSuccess() {
      return this.success;
    }

    public addLocalDataMovementDetails_result setSuccess(String success) {
      this.success = success;
      return this;
    }

    public void unsetSuccess() {
      this.success = null;
    }

    /** Returns true if field success is set (has been assigned a value) and false otherwise */
    public boolean isSetSuccess() {
      return this.success != null;
    }

    public void setSuccessIsSet(boolean value) {
      if (!value) {
        this.success = null;
      }
    }

    public org.apache.airavata.model.error.InvalidRequestException getIre() {
      return this.ire;
    }

    public addLocalDataMovementDetails_result setIre(org.apache.airavata.model.error.InvalidRequestException ire) {
      this.ire = ire;
      return this;
    }

    public void unsetIre() {
      this.ire = null;
    }

    /** Returns true if field ire is set (has been assigned a value) and false otherwise */
    public boolean isSetIre() {
      return this.ire != null;
    }

    public void setIreIsSet(boolean value) {
      if (!value) {
        this.ire = null;
      }
    }

    public org.apache.airavata.model.error.AiravataClientException getAce() {
      return this.ace;
    }

    public addLocalDataMovementDetails_result setAce(org.apache.airavata.model.error.AiravataClientException ace) {
      this.ace = ace;
      return this;
    }

    public void unsetAce() {
      this.ace = null;
    }

    /** Returns true if field ace is set (has been assigned a value) and false otherwise */
    public boolean isSetAce() {
      return this.ace != null;
    }

    public void setAceIsSet(boolean value) {
      if (!value) {
        this.ace = null;
      }
    }

    public org.apache.airavata.model.error.AiravataSystemException getAse() {
      return this.ase;
    }

    public addLocalDataMovementDetails_result setAse(org.apache.airavata.model.error.AiravataSystemException ase) {
      this.ase = ase;
      return this;
    }

    public void unsetAse() {
      this.ase = null;
    }

    /** Returns true if field ase is set (has been assigned a value) and false otherwise */
    public boolean isSetAse() {
      return this.ase != null;
    }

    public void setAseIsSet(boolean value) {
      if (!value) {
        this.ase = null;
      }
    }

    public org.apache.airavata.model.error.AuthorizationException getAe() {
      return this.ae;
    }

    public addLocalDataMovementDetails_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, Object value) {
      switch (field) {
      case SUCCESS:
        if (value == null) {
          unsetSuccess();
        } else {
          setSuccess((String)value);
        }
        break;

      case IRE:
        if (value == null) {
          unsetIre();
        } else {
          setIre((org.apache.airavata.model.error.InvalidRequestException)value);
        }
        break;

      case ACE:
        if (value == null) {
          unsetAce();
        } else {
          setAce((org.apache.airavata.model.error.AiravataClientException)value);
        }
        break;

      case ASE:
        if (value == null) {
          unsetAse();
        } else {
          setAse((org.apache.airavata.model.error.AiravataSystemException)value);
        }
        break;

      case AE:
        if (value == null) {
          unsetAe();
        } else {
          setAe((org.apache.airavata.model.error.AuthorizationException)value);
        }
        break;

      }
    }

    public Object getFieldValue(_Fields field) {
      switch (field) {
      case SUCCESS:
        return getSuccess();

      case IRE:
        return getIre();

      case ACE:
        return getAce();

      case ASE:
        return getAse();

      case AE:
        return getAe();

      }
      throw new IllegalStateException();
    }

    /** Returns true if field corresponding to fieldID is set (has been assigned a value) and false otherwise */
    public boolean isSet(_Fields field) {
      if (field == null) {
        throw new IllegalArgumentException();
      }

      switch (field) {
      case SUCCESS:
        return isSetSuccess();
      case IRE:
        return isSetIre();
      case ACE:
        return isSetAce();
      case ASE:
        return isSetAse();
      case AE:
        return isSetAe();
      }
      throw new IllegalStateException();
    }

    @Override
    public boolean equals(Object that) {
      if (that == null)
        return false;
      if (that instanceof addLocalDataMovementDetails_result)
        return this.equals((addLocalDataMovementDetails_result)that);
      return false;
    }

    public boolean equals(addLocalDataMovementDetails_result that) {
      if (that == null)
        return false;

      boolean this_present_success = true && this.isSetSuccess();
      boolean that_present_success = true && that.isSetSuccess();
      if (this_present_success || that_present_success) {
        if (!(this_present_success && that_present_success))
          return false;
        if (!this.success.equals(that.success))
          return false;
      }

      boolean this_present_ire = true && this.isSetIre();
      boolean that_present_ire = true && that.isSetIre();
      if (this_present_ire || that_present_ire) {
        if (!(this_present_ire && that_present_ire))
          return false;
        if (!this.ire.equals(that.ire))
          return false;
      }

      boolean this_present_ace = true && this.isSetAce();
      boolean that_present_ace = true && that.isSetAce();
      if (this_present_ace || that_present_ace) {
        if (!(this_present_ace && that_present_ace))
          return false;
        if (!this.ace.equals(that.ace))
          return false;
      }

      boolean this_present_ase = true && this.isSetAse();
      boolean that_present_ase = true && that.isSetAse();
      if (this_present_ase || that_present_ase) {
        if (!(this_present_ase && that_present_ase))
          return false;
        if (!this.ase.equals(that.ase))
          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() {
      List<Object> list = new ArrayList<Object>();

      boolean present_success = true && (isSetSuccess());
      list.add(present_success);
      if (present_success)
        list.add(success);

      boolean present_ire = true && (isSetIre());
      list.add(present_ire);
      if (present_ire)
        list.add(ire);

      boolean present_ace = true && (isSetAce());
      list.add(present_ace);
      if (present_ace)
        list.add(ace);

      boolean present_ase = true && (isSetAse());
      list.add(present_ase);
      if (present_ase)
        list.add(ase);

      boolean present_ae = true && (isSetAe());
      list.add(present_ae);
      if (present_ae)
        list.add(ae);

      return list.hashCode();
    }

    @Override
    public int compareTo(addLocalDataMovementDetails_result other) {
      if (!getClass().equals(other.getClass())) {
        return getClass().getName().compareTo(other.getClass().getName());
      }

      int lastComparison = 0;

      lastComparison = Boolean.valueOf(isSetSuccess()).compareTo(other.isSetSuccess());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetSuccess()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.success, other.success);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = Boolean.valueOf(isSetIre()).compareTo(other.isSetIre());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetIre()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.ire, other.ire);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = Boolean.valueOf(isSetAce()).compareTo(other.isSetAce());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetAce()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.ace, other.ace);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = Boolean.valueOf(isSetAse()).compareTo(other.isSetAse());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetAse()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.ase, other.ase);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = 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 {
      schemes.get(iprot.getScheme()).getScheme().read(iprot, this);
    }

    public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException {
      schemes.get(oprot.getScheme()).getScheme().write(oprot, this);
      }

    @Override
    public String toString() {
      StringBuilder sb = new StringBuilder("addLocalDataMovementDetails_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("ire:");
      if (this.ire == null) {
        sb.append("null");
      } else {
        sb.append(this.ire);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("ace:");
      if (this.ace == null) {
        sb.append("null");
      } else {
        sb.append(this.ace);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("ase:");
      if (this.ase == null) {
        sb.append("null");
      } else {
        sb.append(this.ase);
      }
      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, 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 addLocalDataMovementDetails_resultStandardSchemeFactory implements SchemeFactory {
      public addLocalDataMovementDetails_resultStandardScheme getScheme() {
        return new addLocalDataMovementDetails_resultStandardScheme();
      }
    }

    private static class addLocalDataMovementDetails_resultStandardScheme extends StandardScheme<addLocalDataMovementDetails_result> {

      public void read(org.apache.thrift.protocol.TProtocol iprot, addLocalDataMovementDetails_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: // IRE
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.ire = new org.apache.airavata.model.error.InvalidRequestException();
                struct.ire.read(iprot);
                struct.setIreIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 2: // ACE
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.ace = new org.apache.airavata.model.error.AiravataClientException();
                struct.ace.read(iprot);
                struct.setAceIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 3: // ASE
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.ase = new org.apache.airavata.model.error.AiravataSystemException();
                struct.ase.read(iprot);
                struct.setAseIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 4: // 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, addLocalDataMovementDetails_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.ire != null) {
          oprot.writeFieldBegin(IRE_FIELD_DESC);
          struct.ire.write(oprot);
          oprot.writeFieldEnd();
        }
        if (struct.ace != null) {
          oprot.writeFieldBegin(ACE_FIELD_DESC);
          struct.ace.write(oprot);
          oprot.writeFieldEnd();
        }
        if (struct.ase != null) {
          oprot.writeFieldBegin(ASE_FIELD_DESC);
          struct.ase.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 addLocalDataMovementDetails_resultTupleSchemeFactory implements SchemeFactory {
      public addLocalDataMovementDetails_resultTupleScheme getScheme() {
        return new addLocalDataMovementDetails_resultTupleScheme();
      }
    }

    private static class addLocalDataMovementDetails_resultTupleScheme extends TupleScheme<addLocalDataMovementDetails_result> {

      @Override
      public void write(org.apache.thrift.protocol.TProtocol prot, addLocalDataMovementDetails_result struct) throws org.apache.thrift.TException {
        TTupleProtocol oprot = (TTupleProtocol) prot;
        BitSet optionals = new BitSet();
        if (struct.isSetSuccess()) {
          optionals.set(0);
        }
        if (struct.isSetIre()) {
          optionals.set(1);
        }
        if (struct.isSetAce()) {
          optionals.set(2);
        }
        if (struct.isSetAse()) {
          optionals.set(3);
        }
        if (struct.isSetAe()) {
          optionals.set(4);
        }
        oprot.writeBitSet(optionals, 5);
        if (struct.isSetSuccess()) {
          oprot.writeString(struct.success);
        }
        if (struct.isSetIre()) {
          struct.ire.write(oprot);
        }
        if (struct.isSetAce()) {
          struct.ace.write(oprot);
        }
        if (struct.isSetAse()) {
          struct.ase.write(oprot);
        }
        if (struct.isSetAe()) {
          struct.ae.write(oprot);
        }
      }

      @Override
      public void read(org.apache.thrift.protocol.TProtocol prot, addLocalDataMovementDetails_result struct) throws org.apache.thrift.TException {
        TTupleProtocol iprot = (TTupleProtocol) prot;
        BitSet incoming = iprot.readBitSet(5);
        if (incoming.get(0)) {
          struct.success = iprot.readString();
          struct.setSuccessIsSet(true);
        }
        if (incoming.get(1)) {
          struct.ire = new org.apache.airavata.model.error.InvalidRequestException();
          struct.ire.read(iprot);
          struct.setIreIsSet(true);
        }
        if (incoming.get(2)) {
          struct.ace = new org.apache.airavata.model.error.AiravataClientException();
          struct.ace.read(iprot);
          struct.setAceIsSet(true);
        }
        if (incoming.get(3)) {
          struct.ase = new org.apache.airavata.model.error.AiravataSystemException();
          struct.ase.read(iprot);
          struct.setAseIsSet(true);
        }
        if (incoming.get(4)) {
          struct.ae = new org.apache.airavata.model.error.AuthorizationException();
          struct.ae.read(iprot);
          struct.setAeIsSet(true);
        }
      }
    }

  }

  public static class updateLocalDataMovementDetails_args implements org.apache.thrift.TBase<updateLocalDataMovementDetails_args, updateLocalDataMovementDetails_args._Fields>, java.io.Serializable, Cloneable, Comparable<updateLocalDataMovementDetails_args>   {
    private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("updateLocalDataMovementDetails_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 DATA_MOVEMENT_INTERFACE_ID_FIELD_DESC = new org.apache.thrift.protocol.TField("dataMovementInterfaceId", org.apache.thrift.protocol.TType.STRING, (short)2);
    private static final org.apache.thrift.protocol.TField LOCAL_DATA_MOVEMENT_FIELD_DESC = new org.apache.thrift.protocol.TField("localDataMovement", org.apache.thrift.protocol.TType.STRUCT, (short)3);

    private static final Map<Class<? extends IScheme>, SchemeFactory> schemes = new HashMap<Class<? extends IScheme>, SchemeFactory>();
    static {
      schemes.put(StandardScheme.class, new updateLocalDataMovementDetails_argsStandardSchemeFactory());
      schemes.put(TupleScheme.class, new updateLocalDataMovementDetails_argsTupleSchemeFactory());
    }

    public org.apache.airavata.model.security.AuthzToken authzToken; // required
    public String dataMovementInterfaceId; // required
    public org.apache.airavata.model.appcatalog.computeresource.LOCALDataMovement localDataMovement; // required

    /** 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"),
      DATA_MOVEMENT_INTERFACE_ID((short)2, "dataMovementInterfaceId"),
      LOCAL_DATA_MOVEMENT((short)3, "localDataMovement");

      private static final Map<String, _Fields> byName = new HashMap<String, _Fields>();

      static {
        for (_Fields field : EnumSet.allOf(_Fields.class)) {
          byName.put(field.getFieldName(), field);
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, or null if its not found.
       */
      public static _Fields findByThriftId(int fieldId) {
        switch(fieldId) {
          case 1: // AUTHZ_TOKEN
            return AUTHZ_TOKEN;
          case 2: // DATA_MOVEMENT_INTERFACE_ID
            return DATA_MOVEMENT_INTERFACE_ID;
          case 3: // LOCAL_DATA_MOVEMENT
            return LOCAL_DATA_MOVEMENT;
          default:
            return null;
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, throwing an exception
       * if it is not found.
       */
      public static _Fields findByThriftIdOrThrow(int fieldId) {
        _Fields fields = findByThriftId(fieldId);
        if (fields == null) throw new IllegalArgumentException("Field " + fieldId + " doesn't exist!");
        return fields;
      }

      /**
       * Find the _Fields constant that matches name, or null if its not found.
       */
      public static _Fields findByName(String name) {
        return byName.get(name);
      }

      private final short _thriftId;
      private final String _fieldName;

      _Fields(short thriftId, String fieldName) {
        _thriftId = thriftId;
        _fieldName = fieldName;
      }

      public short getThriftFieldId() {
        return _thriftId;
      }

      public String getFieldName() {
        return _fieldName;
      }
    }

    // isset id assignments
    public static final Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
    static {
      Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new EnumMap<_Fields, org.apache.thrift.meta_data.FieldMetaData>(_Fields.class);
      tmpMap.put(_Fields.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.DATA_MOVEMENT_INTERFACE_ID, new org.apache.thrift.meta_data.FieldMetaData("dataMovementInterfaceId", org.apache.thrift.TFieldRequirementType.REQUIRED, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING)));
      tmpMap.put(_Fields.LOCAL_DATA_MOVEMENT, new org.apache.thrift.meta_data.FieldMetaData("localDataMovement", org.apache.thrift.TFieldRequirementType.REQUIRED, 
          new org.apache.thrift.meta_data.StructMetaData(org.apache.thrift.protocol.TType.STRUCT, org.apache.airavata.model.appcatalog.computeresource.LOCALDataMovement.class)));
      metaDataMap = Collections.unmodifiableMap(tmpMap);
      org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(updateLocalDataMovementDetails_args.class, metaDataMap);
    }

    public updateLocalDataMovementDetails_args() {
    }

    public updateLocalDataMovementDetails_args(
      org.apache.airavata.model.security.AuthzToken authzToken,
      String dataMovementInterfaceId,
      org.apache.airavata.model.appcatalog.computeresource.LOCALDataMovement localDataMovement)
    {
      this();
      this.authzToken = authzToken;
      this.dataMovementInterfaceId = dataMovementInterfaceId;
      this.localDataMovement = localDataMovement;
    }

    /**
     * Performs a deep copy on <i>other</i>.
     */
    public updateLocalDataMovementDetails_args(updateLocalDataMovementDetails_args other) {
      if (other.isSetAuthzToken()) {
        this.authzToken = new org.apache.airavata.model.security.AuthzToken(other.authzToken);
      }
      if (other.isSetDataMovementInterfaceId()) {
        this.dataMovementInterfaceId = other.dataMovementInterfaceId;
      }
      if (other.isSetLocalDataMovement()) {
        this.localDataMovement = new org.apache.airavata.model.appcatalog.computeresource.LOCALDataMovement(other.localDataMovement);
      }
    }

    public updateLocalDataMovementDetails_args deepCopy() {
      return new updateLocalDataMovementDetails_args(this);
    }

    @Override
    public void clear() {
      this.authzToken = null;
      this.dataMovementInterfaceId = null;
      this.localDataMovement = null;
    }

    public org.apache.airavata.model.security.AuthzToken getAuthzToken() {
      return this.authzToken;
    }

    public updateLocalDataMovementDetails_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 String getDataMovementInterfaceId() {
      return this.dataMovementInterfaceId;
    }

    public updateLocalDataMovementDetails_args setDataMovementInterfaceId(String dataMovementInterfaceId) {
      this.dataMovementInterfaceId = dataMovementInterfaceId;
      return this;
    }

    public void unsetDataMovementInterfaceId() {
      this.dataMovementInterfaceId = null;
    }

    /** Returns true if field dataMovementInterfaceId is set (has been assigned a value) and false otherwise */
    public boolean isSetDataMovementInterfaceId() {
      return this.dataMovementInterfaceId != null;
    }

    public void setDataMovementInterfaceIdIsSet(boolean value) {
      if (!value) {
        this.dataMovementInterfaceId = null;
      }
    }

    public org.apache.airavata.model.appcatalog.computeresource.LOCALDataMovement getLocalDataMovement() {
      return this.localDataMovement;
    }

    public updateLocalDataMovementDetails_args setLocalDataMovement(org.apache.airavata.model.appcatalog.computeresource.LOCALDataMovement localDataMovement) {
      this.localDataMovement = localDataMovement;
      return this;
    }

    public void unsetLocalDataMovement() {
      this.localDataMovement = null;
    }

    /** Returns true if field localDataMovement is set (has been assigned a value) and false otherwise */
    public boolean isSetLocalDataMovement() {
      return this.localDataMovement != null;
    }

    public void setLocalDataMovementIsSet(boolean value) {
      if (!value) {
        this.localDataMovement = null;
      }
    }

    public void setFieldValue(_Fields field, Object value) {
      switch (field) {
      case AUTHZ_TOKEN:
        if (value == null) {
          unsetAuthzToken();
        } else {
          setAuthzToken((org.apache.airavata.model.security.AuthzToken)value);
        }
        break;

      case DATA_MOVEMENT_INTERFACE_ID:
        if (value == null) {
          unsetDataMovementInterfaceId();
        } else {
          setDataMovementInterfaceId((String)value);
        }
        break;

      case LOCAL_DATA_MOVEMENT:
        if (value == null) {
          unsetLocalDataMovement();
        } else {
          setLocalDataMovement((org.apache.airavata.model.appcatalog.computeresource.LOCALDataMovement)value);
        }
        break;

      }
    }

    public Object getFieldValue(_Fields field) {
      switch (field) {
      case AUTHZ_TOKEN:
        return getAuthzToken();

      case DATA_MOVEMENT_INTERFACE_ID:
        return getDataMovementInterfaceId();

      case LOCAL_DATA_MOVEMENT:
        return getLocalDataMovement();

      }
      throw new IllegalStateException();
    }

    /** Returns true if field corresponding to fieldID is set (has been assigned a value) and false otherwise */
    public boolean isSet(_Fields field) {
      if (field == null) {
        throw new IllegalArgumentException();
      }

      switch (field) {
      case AUTHZ_TOKEN:
        return isSetAuthzToken();
      case DATA_MOVEMENT_INTERFACE_ID:
        return isSetDataMovementInterfaceId();
      case LOCAL_DATA_MOVEMENT:
        return isSetLocalDataMovement();
      }
      throw new IllegalStateException();
    }

    @Override
    public boolean equals(Object that) {
      if (that == null)
        return false;
      if (that instanceof updateLocalDataMovementDetails_args)
        return this.equals((updateLocalDataMovementDetails_args)that);
      return false;
    }

    public boolean equals(updateLocalDataMovementDetails_args that) {
      if (that == null)
        return false;

      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_dataMovementInterfaceId = true && this.isSetDataMovementInterfaceId();
      boolean that_present_dataMovementInterfaceId = true && that.isSetDataMovementInterfaceId();
      if (this_present_dataMovementInterfaceId || that_present_dataMovementInterfaceId) {
        if (!(this_present_dataMovementInterfaceId && that_present_dataMovementInterfaceId))
          return false;
        if (!this.dataMovementInterfaceId.equals(that.dataMovementInterfaceId))
          return false;
      }

      boolean this_present_localDataMovement = true && this.isSetLocalDataMovement();
      boolean that_present_localDataMovement = true && that.isSetLocalDataMovement();
      if (this_present_localDataMovement || that_present_localDataMovement) {
        if (!(this_present_localDataMovement && that_present_localDataMovement))
          return false;
        if (!this.localDataMovement.equals(that.localDataMovement))
          return false;
      }

      return true;
    }

    @Override
    public int hashCode() {
      List<Object> list = new ArrayList<Object>();

      boolean present_authzToken = true && (isSetAuthzToken());
      list.add(present_authzToken);
      if (present_authzToken)
        list.add(authzToken);

      boolean present_dataMovementInterfaceId = true && (isSetDataMovementInterfaceId());
      list.add(present_dataMovementInterfaceId);
      if (present_dataMovementInterfaceId)
        list.add(dataMovementInterfaceId);

      boolean present_localDataMovement = true && (isSetLocalDataMovement());
      list.add(present_localDataMovement);
      if (present_localDataMovement)
        list.add(localDataMovement);

      return list.hashCode();
    }

    @Override
    public int compareTo(updateLocalDataMovementDetails_args other) {
      if (!getClass().equals(other.getClass())) {
        return getClass().getName().compareTo(other.getClass().getName());
      }

      int lastComparison = 0;

      lastComparison = 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 = Boolean.valueOf(isSetDataMovementInterfaceId()).compareTo(other.isSetDataMovementInterfaceId());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetDataMovementInterfaceId()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.dataMovementInterfaceId, other.dataMovementInterfaceId);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = Boolean.valueOf(isSetLocalDataMovement()).compareTo(other.isSetLocalDataMovement());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetLocalDataMovement()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.localDataMovement, other.localDataMovement);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      return 0;
    }

    public _Fields fieldForId(int fieldId) {
      return _Fields.findByThriftId(fieldId);
    }

    public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
      schemes.get(iprot.getScheme()).getScheme().read(iprot, this);
    }

    public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException {
      schemes.get(oprot.getScheme()).getScheme().write(oprot, this);
    }

    @Override
    public String toString() {
      StringBuilder sb = new StringBuilder("updateLocalDataMovementDetails_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("dataMovementInterfaceId:");
      if (this.dataMovementInterfaceId == null) {
        sb.append("null");
      } else {
        sb.append(this.dataMovementInterfaceId);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("localDataMovement:");
      if (this.localDataMovement == null) {
        sb.append("null");
      } else {
        sb.append(this.localDataMovement);
      }
      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 (dataMovementInterfaceId == null) {
        throw new org.apache.thrift.protocol.TProtocolException("Required field 'dataMovementInterfaceId' was not present! Struct: " + toString());
      }
      if (localDataMovement == null) {
        throw new org.apache.thrift.protocol.TProtocolException("Required field 'localDataMovement' was not present! Struct: " + toString());
      }
      // check for sub-struct validity
      if (authzToken != null) {
        authzToken.validate();
      }
      if (localDataMovement != null) {
        localDataMovement.validate();
      }
    }

    private void writeObject(java.io.ObjectOutputStream out) throws java.io.IOException {
      try {
        write(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(out)));
      } catch (org.apache.thrift.TException te) {
        throw new java.io.IOException(te);
      }
    }

    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, ClassNotFoundException {
      try {
        read(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(in)));
      } catch (org.apache.thrift.TException te) {
        throw new java.io.IOException(te);
      }
    }

    private static class updateLocalDataMovementDetails_argsStandardSchemeFactory implements SchemeFactory {
      public updateLocalDataMovementDetails_argsStandardScheme getScheme() {
        return new updateLocalDataMovementDetails_argsStandardScheme();
      }
    }

    private static class updateLocalDataMovementDetails_argsStandardScheme extends StandardScheme<updateLocalDataMovementDetails_args> {

      public void read(org.apache.thrift.protocol.TProtocol iprot, updateLocalDataMovementDetails_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: // DATA_MOVEMENT_INTERFACE_ID
              if (schemeField.type == org.apache.thrift.protocol.TType.STRING) {
                struct.dataMovementInterfaceId = iprot.readString();
                struct.setDataMovementInterfaceIdIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 3: // LOCAL_DATA_MOVEMENT
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.localDataMovement = new org.apache.airavata.model.appcatalog.computeresource.LOCALDataMovement();
                struct.localDataMovement.read(iprot);
                struct.setLocalDataMovementIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            default:
              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
          }
          iprot.readFieldEnd();
        }
        iprot.readStructEnd();

        // check for required fields of primitive type, which can't be checked in the validate method
        struct.validate();
      }

      public void write(org.apache.thrift.protocol.TProtocol oprot, updateLocalDataMovementDetails_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.dataMovementInterfaceId != null) {
          oprot.writeFieldBegin(DATA_MOVEMENT_INTERFACE_ID_FIELD_DESC);
          oprot.writeString(struct.dataMovementInterfaceId);
          oprot.writeFieldEnd();
        }
        if (struct.localDataMovement != null) {
          oprot.writeFieldBegin(LOCAL_DATA_MOVEMENT_FIELD_DESC);
          struct.localDataMovement.write(oprot);
          oprot.writeFieldEnd();
        }
        oprot.writeFieldStop();
        oprot.writeStructEnd();
      }

    }

    private static class updateLocalDataMovementDetails_argsTupleSchemeFactory implements SchemeFactory {
      public updateLocalDataMovementDetails_argsTupleScheme getScheme() {
        return new updateLocalDataMovementDetails_argsTupleScheme();
      }
    }

    private static class updateLocalDataMovementDetails_argsTupleScheme extends TupleScheme<updateLocalDataMovementDetails_args> {

      @Override
      public void write(org.apache.thrift.protocol.TProtocol prot, updateLocalDataMovementDetails_args struct) throws org.apache.thrift.TException {
        TTupleProtocol oprot = (TTupleProtocol) prot;
        struct.authzToken.write(oprot);
        oprot.writeString(struct.dataMovementInterfaceId);
        struct.localDataMovement.write(oprot);
      }

      @Override
      public void read(org.apache.thrift.protocol.TProtocol prot, updateLocalDataMovementDetails_args struct) throws org.apache.thrift.TException {
        TTupleProtocol iprot = (TTupleProtocol) prot;
        struct.authzToken = new org.apache.airavata.model.security.AuthzToken();
        struct.authzToken.read(iprot);
        struct.setAuthzTokenIsSet(true);
        struct.dataMovementInterfaceId = iprot.readString();
        struct.setDataMovementInterfaceIdIsSet(true);
        struct.localDataMovement = new org.apache.airavata.model.appcatalog.computeresource.LOCALDataMovement();
        struct.localDataMovement.read(iprot);
        struct.setLocalDataMovementIsSet(true);
      }
    }

  }

  public static class updateLocalDataMovementDetails_result implements org.apache.thrift.TBase<updateLocalDataMovementDetails_result, updateLocalDataMovementDetails_result._Fields>, java.io.Serializable, Cloneable, Comparable<updateLocalDataMovementDetails_result>   {
    private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("updateLocalDataMovementDetails_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 IRE_FIELD_DESC = new org.apache.thrift.protocol.TField("ire", org.apache.thrift.protocol.TType.STRUCT, (short)1);
    private static final org.apache.thrift.protocol.TField ACE_FIELD_DESC = new org.apache.thrift.protocol.TField("ace", org.apache.thrift.protocol.TType.STRUCT, (short)2);
    private static final org.apache.thrift.protocol.TField ASE_FIELD_DESC = new org.apache.thrift.protocol.TField("ase", org.apache.thrift.protocol.TType.STRUCT, (short)3);
    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)4);

    private static final Map<Class<? extends IScheme>, SchemeFactory> schemes = new HashMap<Class<? extends IScheme>, SchemeFactory>();
    static {
      schemes.put(StandardScheme.class, new updateLocalDataMovementDetails_resultStandardSchemeFactory());
      schemes.put(TupleScheme.class, new updateLocalDataMovementDetails_resultTupleSchemeFactory());
    }

    public boolean success; // required
    public org.apache.airavata.model.error.InvalidRequestException ire; // required
    public org.apache.airavata.model.error.AiravataClientException ace; // required
    public org.apache.airavata.model.error.AiravataSystemException ase; // 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"),
      IRE((short)1, "ire"),
      ACE((short)2, "ace"),
      ASE((short)3, "ase"),
      AE((short)4, "ae");

      private static final Map<String, _Fields> byName = new HashMap<String, _Fields>();

      static {
        for (_Fields field : EnumSet.allOf(_Fields.class)) {
          byName.put(field.getFieldName(), field);
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, or null if its not found.
       */
      public static _Fields findByThriftId(int fieldId) {
        switch(fieldId) {
          case 0: // SUCCESS
            return SUCCESS;
          case 1: // IRE
            return IRE;
          case 2: // ACE
            return ACE;
          case 3: // ASE
            return ASE;
          case 4: // 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 IllegalArgumentException("Field " + fieldId + " doesn't exist!");
        return fields;
      }

      /**
       * Find the _Fields constant that matches name, or null if its not found.
       */
      public static _Fields findByName(String name) {
        return byName.get(name);
      }

      private final short _thriftId;
      private final String _fieldName;

      _Fields(short thriftId, String fieldName) {
        _thriftId = thriftId;
        _fieldName = fieldName;
      }

      public short getThriftFieldId() {
        return _thriftId;
      }

      public String getFieldName() {
        return _fieldName;
      }
    }

    // isset id assignments
    private static final int __SUCCESS_ISSET_ID = 0;
    private byte __isset_bitfield = 0;
    public static final Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
    static {
      Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new EnumMap<_Fields, org.apache.thrift.meta_data.FieldMetaData>(_Fields.class);
      tmpMap.put(_Fields.SUCCESS, new org.apache.thrift.meta_data.FieldMetaData("success", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.BOOL)));
      tmpMap.put(_Fields.IRE, new org.apache.thrift.meta_data.FieldMetaData("ire", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRUCT)));
      tmpMap.put(_Fields.ACE, new org.apache.thrift.meta_data.FieldMetaData("ace", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRUCT)));
      tmpMap.put(_Fields.ASE, new org.apache.thrift.meta_data.FieldMetaData("ase", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRUCT)));
      tmpMap.put(_Fields.AE, new org.apache.thrift.meta_data.FieldMetaData("ae", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRUCT)));
      metaDataMap = Collections.unmodifiableMap(tmpMap);
      org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(updateLocalDataMovementDetails_result.class, metaDataMap);
    }

    public updateLocalDataMovementDetails_result() {
    }

    public updateLocalDataMovementDetails_result(
      boolean success,
      org.apache.airavata.model.error.InvalidRequestException ire,
      org.apache.airavata.model.error.AiravataClientException ace,
      org.apache.airavata.model.error.AiravataSystemException ase,
      org.apache.airavata.model.error.AuthorizationException ae)
    {
      this();
      this.success = success;
      setSuccessIsSet(true);
      this.ire = ire;
      this.ace = ace;
      this.ase = ase;
      this.ae = ae;
    }

    /**
     * Performs a deep copy on <i>other</i>.
     */
    public updateLocalDataMovementDetails_result(updateLocalDataMovementDetails_result other) {
      __isset_bitfield = other.__isset_bitfield;
      this.success = other.success;
      if (other.isSetIre()) {
        this.ire = new org.apache.airavata.model.error.InvalidRequestException(other.ire);
      }
      if (other.isSetAce()) {
        this.ace = new org.apache.airavata.model.error.AiravataClientException(other.ace);
      }
      if (other.isSetAse()) {
        this.ase = new org.apache.airavata.model.error.AiravataSystemException(other.ase);
      }
      if (other.isSetAe()) {
        this.ae = new org.apache.airavata.model.error.AuthorizationException(other.ae);
      }
    }

    public updateLocalDataMovementDetails_result deepCopy() {
      return new updateLocalDataMovementDetails_result(this);
    }

    @Override
    public void clear() {
      setSuccessIsSet(false);
      this.success = false;
      this.ire = null;
      this.ace = null;
      this.ase = null;
      this.ae = null;
    }

    public boolean isSuccess() {
      return this.success;
    }

    public updateLocalDataMovementDetails_result setSuccess(boolean success) {
      this.success = success;
      setSuccessIsSet(true);
      return this;
    }

    public void unsetSuccess() {
      __isset_bitfield = EncodingUtils.clearBit(__isset_bitfield, __SUCCESS_ISSET_ID);
    }

    /** Returns true if field success is set (has been assigned a value) and false otherwise */
    public boolean isSetSuccess() {
      return EncodingUtils.testBit(__isset_bitfield, __SUCCESS_ISSET_ID);
    }

    public void setSuccessIsSet(boolean value) {
      __isset_bitfield = EncodingUtils.setBit(__isset_bitfield, __SUCCESS_ISSET_ID, value);
    }

    public org.apache.airavata.model.error.InvalidRequestException getIre() {
      return this.ire;
    }

    public updateLocalDataMovementDetails_result setIre(org.apache.airavata.model.error.InvalidRequestException ire) {
      this.ire = ire;
      return this;
    }

    public void unsetIre() {
      this.ire = null;
    }

    /** Returns true if field ire is set (has been assigned a value) and false otherwise */
    public boolean isSetIre() {
      return this.ire != null;
    }

    public void setIreIsSet(boolean value) {
      if (!value) {
        this.ire = null;
      }
    }

    public org.apache.airavata.model.error.AiravataClientException getAce() {
      return this.ace;
    }

    public updateLocalDataMovementDetails_result setAce(org.apache.airavata.model.error.AiravataClientException ace) {
      this.ace = ace;
      return this;
    }

    public void unsetAce() {
      this.ace = null;
    }

    /** Returns true if field ace is set (has been assigned a value) and false otherwise */
    public boolean isSetAce() {
      return this.ace != null;
    }

    public void setAceIsSet(boolean value) {
      if (!value) {
        this.ace = null;
      }
    }

    public org.apache.airavata.model.error.AiravataSystemException getAse() {
      return this.ase;
    }

    public updateLocalDataMovementDetails_result setAse(org.apache.airavata.model.error.AiravataSystemException ase) {
      this.ase = ase;
      return this;
    }

    public void unsetAse() {
      this.ase = null;
    }

    /** Returns true if field ase is set (has been assigned a value) and false otherwise */
    public boolean isSetAse() {
      return this.ase != null;
    }

    public void setAseIsSet(boolean value) {
      if (!value) {
        this.ase = null;
      }
    }

    public org.apache.airavata.model.error.AuthorizationException getAe() {
      return this.ae;
    }

    public updateLocalDataMovementDetails_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, Object value) {
      switch (field) {
      case SUCCESS:
        if (value == null) {
          unsetSuccess();
        } else {
          setSuccess((Boolean)value);
        }
        break;

      case IRE:
        if (value == null) {
          unsetIre();
        } else {
          setIre((org.apache.airavata.model.error.InvalidRequestException)value);
        }
        break;

      case ACE:
        if (value == null) {
          unsetAce();
        } else {
          setAce((org.apache.airavata.model.error.AiravataClientException)value);
        }
        break;

      case ASE:
        if (value == null) {
          unsetAse();
        } else {
          setAse((org.apache.airavata.model.error.AiravataSystemException)value);
        }
        break;

      case AE:
        if (value == null) {
          unsetAe();
        } else {
          setAe((org.apache.airavata.model.error.AuthorizationException)value);
        }
        break;

      }
    }

    public Object getFieldValue(_Fields field) {
      switch (field) {
      case SUCCESS:
        return Boolean.valueOf(isSuccess());

      case IRE:
        return getIre();

      case ACE:
        return getAce();

      case ASE:
        return getAse();

      case AE:
        return getAe();

      }
      throw new IllegalStateException();
    }

    /** Returns true if field corresponding to fieldID is set (has been assigned a value) and false otherwise */
    public boolean isSet(_Fields field) {
      if (field == null) {
        throw new IllegalArgumentException();
      }

      switch (field) {
      case SUCCESS:
        return isSetSuccess();
      case IRE:
        return isSetIre();
      case ACE:
        return isSetAce();
      case ASE:
        return isSetAse();
      case AE:
        return isSetAe();
      }
      throw new IllegalStateException();
    }

    @Override
    public boolean equals(Object that) {
      if (that == null)
        return false;
      if (that instanceof updateLocalDataMovementDetails_result)
        return this.equals((updateLocalDataMovementDetails_result)that);
      return false;
    }

    public boolean equals(updateLocalDataMovementDetails_result that) {
      if (that == null)
        return false;

      boolean this_present_success = true;
      boolean that_present_success = true;
      if (this_present_success || that_present_success) {
        if (!(this_present_success && that_present_success))
          return false;
        if (this.success != that.success)
          return false;
      }

      boolean this_present_ire = true && this.isSetIre();
      boolean that_present_ire = true && that.isSetIre();
      if (this_present_ire || that_present_ire) {
        if (!(this_present_ire && that_present_ire))
          return false;
        if (!this.ire.equals(that.ire))
          return false;
      }

      boolean this_present_ace = true && this.isSetAce();
      boolean that_present_ace = true && that.isSetAce();
      if (this_present_ace || that_present_ace) {
        if (!(this_present_ace && that_present_ace))
          return false;
        if (!this.ace.equals(that.ace))
          return false;
      }

      boolean this_present_ase = true && this.isSetAse();
      boolean that_present_ase = true && that.isSetAse();
      if (this_present_ase || that_present_ase) {
        if (!(this_present_ase && that_present_ase))
          return false;
        if (!this.ase.equals(that.ase))
          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() {
      List<Object> list = new ArrayList<Object>();

      boolean present_success = true;
      list.add(present_success);
      if (present_success)
        list.add(success);

      boolean present_ire = true && (isSetIre());
      list.add(present_ire);
      if (present_ire)
        list.add(ire);

      boolean present_ace = true && (isSetAce());
      list.add(present_ace);
      if (present_ace)
        list.add(ace);

      boolean present_ase = true && (isSetAse());
      list.add(present_ase);
      if (present_ase)
        list.add(ase);

      boolean present_ae = true && (isSetAe());
      list.add(present_ae);
      if (present_ae)
        list.add(ae);

      return list.hashCode();
    }

    @Override
    public int compareTo(updateLocalDataMovementDetails_result other) {
      if (!getClass().equals(other.getClass())) {
        return getClass().getName().compareTo(other.getClass().getName());
      }

      int lastComparison = 0;

      lastComparison = Boolean.valueOf(isSetSuccess()).compareTo(other.isSetSuccess());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetSuccess()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.success, other.success);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = Boolean.valueOf(isSetIre()).compareTo(other.isSetIre());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetIre()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.ire, other.ire);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = Boolean.valueOf(isSetAce()).compareTo(other.isSetAce());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetAce()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.ace, other.ace);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = Boolean.valueOf(isSetAse()).compareTo(other.isSetAse());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetAse()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.ase, other.ase);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = 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 {
      schemes.get(iprot.getScheme()).getScheme().read(iprot, this);
    }

    public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException {
      schemes.get(oprot.getScheme()).getScheme().write(oprot, this);
      }

    @Override
    public String toString() {
      StringBuilder sb = new StringBuilder("updateLocalDataMovementDetails_result(");
      boolean first = true;

      sb.append("success:");
      sb.append(this.success);
      first = false;
      if (!first) sb.append(", ");
      sb.append("ire:");
      if (this.ire == null) {
        sb.append("null");
      } else {
        sb.append(this.ire);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("ace:");
      if (this.ace == null) {
        sb.append("null");
      } else {
        sb.append(this.ace);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("ase:");
      if (this.ase == null) {
        sb.append("null");
      } else {
        sb.append(this.ase);
      }
      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, 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 updateLocalDataMovementDetails_resultStandardSchemeFactory implements SchemeFactory {
      public updateLocalDataMovementDetails_resultStandardScheme getScheme() {
        return new updateLocalDataMovementDetails_resultStandardScheme();
      }
    }

    private static class updateLocalDataMovementDetails_resultStandardScheme extends StandardScheme<updateLocalDataMovementDetails_result> {

      public void read(org.apache.thrift.protocol.TProtocol iprot, updateLocalDataMovementDetails_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: // IRE
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.ire = new org.apache.airavata.model.error.InvalidRequestException();
                struct.ire.read(iprot);
                struct.setIreIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 2: // ACE
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.ace = new org.apache.airavata.model.error.AiravataClientException();
                struct.ace.read(iprot);
                struct.setAceIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 3: // ASE
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.ase = new org.apache.airavata.model.error.AiravataSystemException();
                struct.ase.read(iprot);
                struct.setAseIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 4: // 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, updateLocalDataMovementDetails_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.ire != null) {
          oprot.writeFieldBegin(IRE_FIELD_DESC);
          struct.ire.write(oprot);
          oprot.writeFieldEnd();
        }
        if (struct.ace != null) {
          oprot.writeFieldBegin(ACE_FIELD_DESC);
          struct.ace.write(oprot);
          oprot.writeFieldEnd();
        }
        if (struct.ase != null) {
          oprot.writeFieldBegin(ASE_FIELD_DESC);
          struct.ase.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 updateLocalDataMovementDetails_resultTupleSchemeFactory implements SchemeFactory {
      public updateLocalDataMovementDetails_resultTupleScheme getScheme() {
        return new updateLocalDataMovementDetails_resultTupleScheme();
      }
    }

    private static class updateLocalDataMovementDetails_resultTupleScheme extends TupleScheme<updateLocalDataMovementDetails_result> {

      @Override
      public void write(org.apache.thrift.protocol.TProtocol prot, updateLocalDataMovementDetails_result struct) throws org.apache.thrift.TException {
        TTupleProtocol oprot = (TTupleProtocol) prot;
        BitSet optionals = new BitSet();
        if (struct.isSetSuccess()) {
          optionals.set(0);
        }
        if (struct.isSetIre()) {
          optionals.set(1);
        }
        if (struct.isSetAce()) {
          optionals.set(2);
        }
        if (struct.isSetAse()) {
          optionals.set(3);
        }
        if (struct.isSetAe()) {
          optionals.set(4);
        }
        oprot.writeBitSet(optionals, 5);
        if (struct.isSetSuccess()) {
          oprot.writeBool(struct.success);
        }
        if (struct.isSetIre()) {
          struct.ire.write(oprot);
        }
        if (struct.isSetAce()) {
          struct.ace.write(oprot);
        }
        if (struct.isSetAse()) {
          struct.ase.write(oprot);
        }
        if (struct.isSetAe()) {
          struct.ae.write(oprot);
        }
      }

      @Override
      public void read(org.apache.thrift.protocol.TProtocol prot, updateLocalDataMovementDetails_result struct) throws org.apache.thrift.TException {
        TTupleProtocol iprot = (TTupleProtocol) prot;
        BitSet incoming = iprot.readBitSet(5);
        if (incoming.get(0)) {
          struct.success = iprot.readBool();
          struct.setSuccessIsSet(true);
        }
        if (incoming.get(1)) {
          struct.ire = new org.apache.airavata.model.error.InvalidRequestException();
          struct.ire.read(iprot);
          struct.setIreIsSet(true);
        }
        if (incoming.get(2)) {
          struct.ace = new org.apache.airavata.model.error.AiravataClientException();
          struct.ace.read(iprot);
          struct.setAceIsSet(true);
        }
        if (incoming.get(3)) {
          struct.ase = new org.apache.airavata.model.error.AiravataSystemException();
          struct.ase.read(iprot);
          struct.setAseIsSet(true);
        }
        if (incoming.get(4)) {
          struct.ae = new org.apache.airavata.model.error.AuthorizationException();
          struct.ae.read(iprot);
          struct.setAeIsSet(true);
        }
      }
    }

  }

  public static class getLocalDataMovement_args implements org.apache.thrift.TBase<getLocalDataMovement_args, getLocalDataMovement_args._Fields>, java.io.Serializable, Cloneable, Comparable<getLocalDataMovement_args>   {
    private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("getLocalDataMovement_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 DATA_MOVEMENT_ID_FIELD_DESC = new org.apache.thrift.protocol.TField("dataMovementId", org.apache.thrift.protocol.TType.STRING, (short)2);

    private static final Map<Class<? extends IScheme>, SchemeFactory> schemes = new HashMap<Class<? extends IScheme>, SchemeFactory>();
    static {
      schemes.put(StandardScheme.class, new getLocalDataMovement_argsStandardSchemeFactory());
      schemes.put(TupleScheme.class, new getLocalDataMovement_argsTupleSchemeFactory());
    }

    public org.apache.airavata.model.security.AuthzToken authzToken; // required
    public String dataMovementId; // required

    /** 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"),
      DATA_MOVEMENT_ID((short)2, "dataMovementId");

      private static final Map<String, _Fields> byName = new HashMap<String, _Fields>();

      static {
        for (_Fields field : EnumSet.allOf(_Fields.class)) {
          byName.put(field.getFieldName(), field);
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, or null if its not found.
       */
      public static _Fields findByThriftId(int fieldId) {
        switch(fieldId) {
          case 1: // AUTHZ_TOKEN
            return AUTHZ_TOKEN;
          case 2: // DATA_MOVEMENT_ID
            return DATA_MOVEMENT_ID;
          default:
            return null;
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, throwing an exception
       * if it is not found.
       */
      public static _Fields findByThriftIdOrThrow(int fieldId) {
        _Fields fields = findByThriftId(fieldId);
        if (fields == null) throw new IllegalArgumentException("Field " + fieldId + " doesn't exist!");
        return fields;
      }

      /**
       * Find the _Fields constant that matches name, or null if its not found.
       */
      public static _Fields findByName(String name) {
        return byName.get(name);
      }

      private final short _thriftId;
      private final String _fieldName;

      _Fields(short thriftId, String fieldName) {
        _thriftId = thriftId;
        _fieldName = fieldName;
      }

      public short getThriftFieldId() {
        return _thriftId;
      }

      public String getFieldName() {
        return _fieldName;
      }
    }

    // isset id assignments
    public static final Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
    static {
      Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new EnumMap<_Fields, org.apache.thrift.meta_data.FieldMetaData>(_Fields.class);
      tmpMap.put(_Fields.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.DATA_MOVEMENT_ID, new org.apache.thrift.meta_data.FieldMetaData("dataMovementId", org.apache.thrift.TFieldRequirementType.REQUIRED, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING)));
      metaDataMap = Collections.unmodifiableMap(tmpMap);
      org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(getLocalDataMovement_args.class, metaDataMap);
    }

    public getLocalDataMovement_args() {
    }

    public getLocalDataMovement_args(
      org.apache.airavata.model.security.AuthzToken authzToken,
      String dataMovementId)
    {
      this();
      this.authzToken = authzToken;
      this.dataMovementId = dataMovementId;
    }

    /**
     * Performs a deep copy on <i>other</i>.
     */
    public getLocalDataMovement_args(getLocalDataMovement_args other) {
      if (other.isSetAuthzToken()) {
        this.authzToken = new org.apache.airavata.model.security.AuthzToken(other.authzToken);
      }
      if (other.isSetDataMovementId()) {
        this.dataMovementId = other.dataMovementId;
      }
    }

    public getLocalDataMovement_args deepCopy() {
      return new getLocalDataMovement_args(this);
    }

    @Override
    public void clear() {
      this.authzToken = null;
      this.dataMovementId = null;
    }

    public org.apache.airavata.model.security.AuthzToken getAuthzToken() {
      return this.authzToken;
    }

    public getLocalDataMovement_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 String getDataMovementId() {
      return this.dataMovementId;
    }

    public getLocalDataMovement_args setDataMovementId(String dataMovementId) {
      this.dataMovementId = dataMovementId;
      return this;
    }

    public void unsetDataMovementId() {
      this.dataMovementId = null;
    }

    /** Returns true if field dataMovementId is set (has been assigned a value) and false otherwise */
    public boolean isSetDataMovementId() {
      return this.dataMovementId != null;
    }

    public void setDataMovementIdIsSet(boolean value) {
      if (!value) {
        this.dataMovementId = null;
      }
    }

    public void setFieldValue(_Fields field, Object value) {
      switch (field) {
      case AUTHZ_TOKEN:
        if (value == null) {
          unsetAuthzToken();
        } else {
          setAuthzToken((org.apache.airavata.model.security.AuthzToken)value);
        }
        break;

      case DATA_MOVEMENT_ID:
        if (value == null) {
          unsetDataMovementId();
        } else {
          setDataMovementId((String)value);
        }
        break;

      }
    }

    public Object getFieldValue(_Fields field) {
      switch (field) {
      case AUTHZ_TOKEN:
        return getAuthzToken();

      case DATA_MOVEMENT_ID:
        return getDataMovementId();

      }
      throw new IllegalStateException();
    }

    /** Returns true if field corresponding to fieldID is set (has been assigned a value) and false otherwise */
    public boolean isSet(_Fields field) {
      if (field == null) {
        throw new IllegalArgumentException();
      }

      switch (field) {
      case AUTHZ_TOKEN:
        return isSetAuthzToken();
      case DATA_MOVEMENT_ID:
        return isSetDataMovementId();
      }
      throw new IllegalStateException();
    }

    @Override
    public boolean equals(Object that) {
      if (that == null)
        return false;
      if (that instanceof getLocalDataMovement_args)
        return this.equals((getLocalDataMovement_args)that);
      return false;
    }

    public boolean equals(getLocalDataMovement_args that) {
      if (that == null)
        return false;

      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_dataMovementId = true && this.isSetDataMovementId();
      boolean that_present_dataMovementId = true && that.isSetDataMovementId();
      if (this_present_dataMovementId || that_present_dataMovementId) {
        if (!(this_present_dataMovementId && that_present_dataMovementId))
          return false;
        if (!this.dataMovementId.equals(that.dataMovementId))
          return false;
      }

      return true;
    }

    @Override
    public int hashCode() {
      List<Object> list = new ArrayList<Object>();

      boolean present_authzToken = true && (isSetAuthzToken());
      list.add(present_authzToken);
      if (present_authzToken)
        list.add(authzToken);

      boolean present_dataMovementId = true && (isSetDataMovementId());
      list.add(present_dataMovementId);
      if (present_dataMovementId)
        list.add(dataMovementId);

      return list.hashCode();
    }

    @Override
    public int compareTo(getLocalDataMovement_args other) {
      if (!getClass().equals(other.getClass())) {
        return getClass().getName().compareTo(other.getClass().getName());
      }

      int lastComparison = 0;

      lastComparison = 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 = Boolean.valueOf(isSetDataMovementId()).compareTo(other.isSetDataMovementId());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetDataMovementId()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.dataMovementId, other.dataMovementId);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      return 0;
    }

    public _Fields fieldForId(int fieldId) {
      return _Fields.findByThriftId(fieldId);
    }

    public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
      schemes.get(iprot.getScheme()).getScheme().read(iprot, this);
    }

    public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException {
      schemes.get(oprot.getScheme()).getScheme().write(oprot, this);
    }

    @Override
    public String toString() {
      StringBuilder sb = new StringBuilder("getLocalDataMovement_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("dataMovementId:");
      if (this.dataMovementId == null) {
        sb.append("null");
      } else {
        sb.append(this.dataMovementId);
      }
      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 (dataMovementId == null) {
        throw new org.apache.thrift.protocol.TProtocolException("Required field 'dataMovementId' 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, 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 getLocalDataMovement_argsStandardSchemeFactory implements SchemeFactory {
      public getLocalDataMovement_argsStandardScheme getScheme() {
        return new getLocalDataMovement_argsStandardScheme();
      }
    }

    private static class getLocalDataMovement_argsStandardScheme extends StandardScheme<getLocalDataMovement_args> {

      public void read(org.apache.thrift.protocol.TProtocol iprot, getLocalDataMovement_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: // DATA_MOVEMENT_ID
              if (schemeField.type == org.apache.thrift.protocol.TType.STRING) {
                struct.dataMovementId = iprot.readString();
                struct.setDataMovementIdIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            default:
              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
          }
          iprot.readFieldEnd();
        }
        iprot.readStructEnd();

        // check for required fields of primitive type, which can't be checked in the validate method
        struct.validate();
      }

      public void write(org.apache.thrift.protocol.TProtocol oprot, getLocalDataMovement_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.dataMovementId != null) {
          oprot.writeFieldBegin(DATA_MOVEMENT_ID_FIELD_DESC);
          oprot.writeString(struct.dataMovementId);
          oprot.writeFieldEnd();
        }
        oprot.writeFieldStop();
        oprot.writeStructEnd();
      }

    }

    private static class getLocalDataMovement_argsTupleSchemeFactory implements SchemeFactory {
      public getLocalDataMovement_argsTupleScheme getScheme() {
        return new getLocalDataMovement_argsTupleScheme();
      }
    }

    private static class getLocalDataMovement_argsTupleScheme extends TupleScheme<getLocalDataMovement_args> {

      @Override
      public void write(org.apache.thrift.protocol.TProtocol prot, getLocalDataMovement_args struct) throws org.apache.thrift.TException {
        TTupleProtocol oprot = (TTupleProtocol) prot;
        struct.authzToken.write(oprot);
        oprot.writeString(struct.dataMovementId);
      }

      @Override
      public void read(org.apache.thrift.protocol.TProtocol prot, getLocalDataMovement_args struct) throws org.apache.thrift.TException {
        TTupleProtocol iprot = (TTupleProtocol) prot;
        struct.authzToken = new org.apache.airavata.model.security.AuthzToken();
        struct.authzToken.read(iprot);
        struct.setAuthzTokenIsSet(true);
        struct.dataMovementId = iprot.readString();
        struct.setDataMovementIdIsSet(true);
      }
    }

  }

  public static class getLocalDataMovement_result implements org.apache.thrift.TBase<getLocalDataMovement_result, getLocalDataMovement_result._Fields>, java.io.Serializable, Cloneable, Comparable<getLocalDataMovement_result>   {
    private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("getLocalDataMovement_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 IRE_FIELD_DESC = new org.apache.thrift.protocol.TField("ire", org.apache.thrift.protocol.TType.STRUCT, (short)1);
    private static final org.apache.thrift.protocol.TField ACE_FIELD_DESC = new org.apache.thrift.protocol.TField("ace", org.apache.thrift.protocol.TType.STRUCT, (short)2);
    private static final org.apache.thrift.protocol.TField ASE_FIELD_DESC = new org.apache.thrift.protocol.TField("ase", org.apache.thrift.protocol.TType.STRUCT, (short)3);
    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)4);

    private static final Map<Class<? extends IScheme>, SchemeFactory> schemes = new HashMap<Class<? extends IScheme>, SchemeFactory>();
    static {
      schemes.put(StandardScheme.class, new getLocalDataMovement_resultStandardSchemeFactory());
      schemes.put(TupleScheme.class, new getLocalDataMovement_resultTupleSchemeFactory());
    }

    public org.apache.airavata.model.appcatalog.computeresource.LOCALDataMovement success; // required
    public org.apache.airavata.model.error.InvalidRequestException ire; // required
    public org.apache.airavata.model.error.AiravataClientException ace; // required
    public org.apache.airavata.model.error.AiravataSystemException ase; // 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"),
      IRE((short)1, "ire"),
      ACE((short)2, "ace"),
      ASE((short)3, "ase"),
      AE((short)4, "ae");

      private static final Map<String, _Fields> byName = new HashMap<String, _Fields>();

      static {
        for (_Fields field : EnumSet.allOf(_Fields.class)) {
          byName.put(field.getFieldName(), field);
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, or null if its not found.
       */
      public static _Fields findByThriftId(int fieldId) {
        switch(fieldId) {
          case 0: // SUCCESS
            return SUCCESS;
          case 1: // IRE
            return IRE;
          case 2: // ACE
            return ACE;
          case 3: // ASE
            return ASE;
          case 4: // 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 IllegalArgumentException("Field " + fieldId + " doesn't exist!");
        return fields;
      }

      /**
       * Find the _Fields constant that matches name, or null if its not found.
       */
      public static _Fields findByName(String name) {
        return byName.get(name);
      }

      private final short _thriftId;
      private final String _fieldName;

      _Fields(short thriftId, String fieldName) {
        _thriftId = thriftId;
        _fieldName = fieldName;
      }

      public short getThriftFieldId() {
        return _thriftId;
      }

      public String getFieldName() {
        return _fieldName;
      }
    }

    // isset id assignments
    public static final Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
    static {
      Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new EnumMap<_Fields, org.apache.thrift.meta_data.FieldMetaData>(_Fields.class);
      tmpMap.put(_Fields.SUCCESS, new org.apache.thrift.meta_data.FieldMetaData("success", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.StructMetaData(org.apache.thrift.protocol.TType.STRUCT, org.apache.airavata.model.appcatalog.computeresource.LOCALDataMovement.class)));
      tmpMap.put(_Fields.IRE, new org.apache.thrift.meta_data.FieldMetaData("ire", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRUCT)));
      tmpMap.put(_Fields.ACE, new org.apache.thrift.meta_data.FieldMetaData("ace", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRUCT)));
      tmpMap.put(_Fields.ASE, new org.apache.thrift.meta_data.FieldMetaData("ase", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRUCT)));
      tmpMap.put(_Fields.AE, new org.apache.thrift.meta_data.FieldMetaData("ae", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRUCT)));
      metaDataMap = Collections.unmodifiableMap(tmpMap);
      org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(getLocalDataMovement_result.class, metaDataMap);
    }

    public getLocalDataMovement_result() {
    }

    public getLocalDataMovement_result(
      org.apache.airavata.model.appcatalog.computeresource.LOCALDataMovement success,
      org.apache.airavata.model.error.InvalidRequestException ire,
      org.apache.airavata.model.error.AiravataClientException ace,
      org.apache.airavata.model.error.AiravataSystemException ase,
      org.apache.airavata.model.error.AuthorizationException ae)
    {
      this();
      this.success = success;
      this.ire = ire;
      this.ace = ace;
      this.ase = ase;
      this.ae = ae;
    }

    /**
     * Performs a deep copy on <i>other</i>.
     */
    public getLocalDataMovement_result(getLocalDataMovement_result other) {
      if (other.isSetSuccess()) {
        this.success = new org.apache.airavata.model.appcatalog.computeresource.LOCALDataMovement(other.success);
      }
      if (other.isSetIre()) {
        this.ire = new org.apache.airavata.model.error.InvalidRequestException(other.ire);
      }
      if (other.isSetAce()) {
        this.ace = new org.apache.airavata.model.error.AiravataClientException(other.ace);
      }
      if (other.isSetAse()) {
        this.ase = new org.apache.airavata.model.error.AiravataSystemException(other.ase);
      }
      if (other.isSetAe()) {
        this.ae = new org.apache.airavata.model.error.AuthorizationException(other.ae);
      }
    }

    public getLocalDataMovement_result deepCopy() {
      return new getLocalDataMovement_result(this);
    }

    @Override
    public void clear() {
      this.success = null;
      this.ire = null;
      this.ace = null;
      this.ase = null;
      this.ae = null;
    }

    public org.apache.airavata.model.appcatalog.computeresource.LOCALDataMovement getSuccess() {
      return this.success;
    }

    public getLocalDataMovement_result setSuccess(org.apache.airavata.model.appcatalog.computeresource.LOCALDataMovement 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.model.error.InvalidRequestException getIre() {
      return this.ire;
    }

    public getLocalDataMovement_result setIre(org.apache.airavata.model.error.InvalidRequestException ire) {
      this.ire = ire;
      return this;
    }

    public void unsetIre() {
      this.ire = null;
    }

    /** Returns true if field ire is set (has been assigned a value) and false otherwise */
    public boolean isSetIre() {
      return this.ire != null;
    }

    public void setIreIsSet(boolean value) {
      if (!value) {
        this.ire = null;
      }
    }

    public org.apache.airavata.model.error.AiravataClientException getAce() {
      return this.ace;
    }

    public getLocalDataMovement_result setAce(org.apache.airavata.model.error.AiravataClientException ace) {
      this.ace = ace;
      return this;
    }

    public void unsetAce() {
      this.ace = null;
    }

    /** Returns true if field ace is set (has been assigned a value) and false otherwise */
    public boolean isSetAce() {
      return this.ace != null;
    }

    public void setAceIsSet(boolean value) {
      if (!value) {
        this.ace = null;
      }
    }

    public org.apache.airavata.model.error.AiravataSystemException getAse() {
      return this.ase;
    }

    public getLocalDataMovement_result setAse(org.apache.airavata.model.error.AiravataSystemException ase) {
      this.ase = ase;
      return this;
    }

    public void unsetAse() {
      this.ase = null;
    }

    /** Returns true if field ase is set (has been assigned a value) and false otherwise */
    public boolean isSetAse() {
      return this.ase != null;
    }

    public void setAseIsSet(boolean value) {
      if (!value) {
        this.ase = null;
      }
    }

    public org.apache.airavata.model.error.AuthorizationException getAe() {
      return this.ae;
    }

    public getLocalDataMovement_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, Object value) {
      switch (field) {
      case SUCCESS:
        if (value == null) {
          unsetSuccess();
        } else {
          setSuccess((org.apache.airavata.model.appcatalog.computeresource.LOCALDataMovement)value);
        }
        break;

      case IRE:
        if (value == null) {
          unsetIre();
        } else {
          setIre((org.apache.airavata.model.error.InvalidRequestException)value);
        }
        break;

      case ACE:
        if (value == null) {
          unsetAce();
        } else {
          setAce((org.apache.airavata.model.error.AiravataClientException)value);
        }
        break;

      case ASE:
        if (value == null) {
          unsetAse();
        } else {
          setAse((org.apache.airavata.model.error.AiravataSystemException)value);
        }
        break;

      case AE:
        if (value == null) {
          unsetAe();
        } else {
          setAe((org.apache.airavata.model.error.AuthorizationException)value);
        }
        break;

      }
    }

    public Object getFieldValue(_Fields field) {
      switch (field) {
      case SUCCESS:
        return getSuccess();

      case IRE:
        return getIre();

      case ACE:
        return getAce();

      case ASE:
        return getAse();

      case AE:
        return getAe();

      }
      throw new IllegalStateException();
    }

    /** Returns true if field corresponding to fieldID is set (has been assigned a value) and false otherwise */
    public boolean isSet(_Fields field) {
      if (field == null) {
        throw new IllegalArgumentException();
      }

      switch (field) {
      case SUCCESS:
        return isSetSuccess();
      case IRE:
        return isSetIre();
      case ACE:
        return isSetAce();
      case ASE:
        return isSetAse();
      case AE:
        return isSetAe();
      }
      throw new IllegalStateException();
    }

    @Override
    public boolean equals(Object that) {
      if (that == null)
        return false;
      if (that instanceof getLocalDataMovement_result)
        return this.equals((getLocalDataMovement_result)that);
      return false;
    }

    public boolean equals(getLocalDataMovement_result that) {
      if (that == null)
        return false;

      boolean this_present_success = true && this.isSetSuccess();
      boolean that_present_success = true && that.isSetSuccess();
      if (this_present_success || that_present_success) {
        if (!(this_present_success && that_present_success))
          return false;
        if (!this.success.equals(that.success))
          return false;
      }

      boolean this_present_ire = true && this.isSetIre();
      boolean that_present_ire = true && that.isSetIre();
      if (this_present_ire || that_present_ire) {
        if (!(this_present_ire && that_present_ire))
          return false;
        if (!this.ire.equals(that.ire))
          return false;
      }

      boolean this_present_ace = true && this.isSetAce();
      boolean that_present_ace = true && that.isSetAce();
      if (this_present_ace || that_present_ace) {
        if (!(this_present_ace && that_present_ace))
          return false;
        if (!this.ace.equals(that.ace))
          return false;
      }

      boolean this_present_ase = true && this.isSetAse();
      boolean that_present_ase = true && that.isSetAse();
      if (this_present_ase || that_present_ase) {
        if (!(this_present_ase && that_present_ase))
          return false;
        if (!this.ase.equals(that.ase))
          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() {
      List<Object> list = new ArrayList<Object>();

      boolean present_success = true && (isSetSuccess());
      list.add(present_success);
      if (present_success)
        list.add(success);

      boolean present_ire = true && (isSetIre());
      list.add(present_ire);
      if (present_ire)
        list.add(ire);

      boolean present_ace = true && (isSetAce());
      list.add(present_ace);
      if (present_ace)
        list.add(ace);

      boolean present_ase = true && (isSetAse());
      list.add(present_ase);
      if (present_ase)
        list.add(ase);

      boolean present_ae = true && (isSetAe());
      list.add(present_ae);
      if (present_ae)
        list.add(ae);

      return list.hashCode();
    }

    @Override
    public int compareTo(getLocalDataMovement_result other) {
      if (!getClass().equals(other.getClass())) {
        return getClass().getName().compareTo(other.getClass().getName());
      }

      int lastComparison = 0;

      lastComparison = Boolean.valueOf(isSetSuccess()).compareTo(other.isSetSuccess());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetSuccess()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.success, other.success);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = Boolean.valueOf(isSetIre()).compareTo(other.isSetIre());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetIre()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.ire, other.ire);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = Boolean.valueOf(isSetAce()).compareTo(other.isSetAce());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetAce()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.ace, other.ace);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = Boolean.valueOf(isSetAse()).compareTo(other.isSetAse());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetAse()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.ase, other.ase);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = 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 {
      schemes.get(iprot.getScheme()).getScheme().read(iprot, this);
    }

    public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException {
      schemes.get(oprot.getScheme()).getScheme().write(oprot, this);
      }

    @Override
    public String toString() {
      StringBuilder sb = new StringBuilder("getLocalDataMovement_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("ire:");
      if (this.ire == null) {
        sb.append("null");
      } else {
        sb.append(this.ire);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("ace:");
      if (this.ace == null) {
        sb.append("null");
      } else {
        sb.append(this.ace);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("ase:");
      if (this.ase == null) {
        sb.append("null");
      } else {
        sb.append(this.ase);
      }
      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, 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 getLocalDataMovement_resultStandardSchemeFactory implements SchemeFactory {
      public getLocalDataMovement_resultStandardScheme getScheme() {
        return new getLocalDataMovement_resultStandardScheme();
      }
    }

    private static class getLocalDataMovement_resultStandardScheme extends StandardScheme<getLocalDataMovement_result> {

      public void read(org.apache.thrift.protocol.TProtocol iprot, getLocalDataMovement_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.appcatalog.computeresource.LOCALDataMovement();
                struct.success.read(iprot);
                struct.setSuccessIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 1: // IRE
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.ire = new org.apache.airavata.model.error.InvalidRequestException();
                struct.ire.read(iprot);
                struct.setIreIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 2: // ACE
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.ace = new org.apache.airavata.model.error.AiravataClientException();
                struct.ace.read(iprot);
                struct.setAceIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 3: // ASE
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.ase = new org.apache.airavata.model.error.AiravataSystemException();
                struct.ase.read(iprot);
                struct.setAseIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 4: // 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, getLocalDataMovement_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.ire != null) {
          oprot.writeFieldBegin(IRE_FIELD_DESC);
          struct.ire.write(oprot);
          oprot.writeFieldEnd();
        }
        if (struct.ace != null) {
          oprot.writeFieldBegin(ACE_FIELD_DESC);
          struct.ace.write(oprot);
          oprot.writeFieldEnd();
        }
        if (struct.ase != null) {
          oprot.writeFieldBegin(ASE_FIELD_DESC);
          struct.ase.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 getLocalDataMovement_resultTupleSchemeFactory implements SchemeFactory {
      public getLocalDataMovement_resultTupleScheme getScheme() {
        return new getLocalDataMovement_resultTupleScheme();
      }
    }

    private static class getLocalDataMovement_resultTupleScheme extends TupleScheme<getLocalDataMovement_result> {

      @Override
      public void write(org.apache.thrift.protocol.TProtocol prot, getLocalDataMovement_result struct) throws org.apache.thrift.TException {
        TTupleProtocol oprot = (TTupleProtocol) prot;
        BitSet optionals = new BitSet();
        if (struct.isSetSuccess()) {
          optionals.set(0);
        }
        if (struct.isSetIre()) {
          optionals.set(1);
        }
        if (struct.isSetAce()) {
          optionals.set(2);
        }
        if (struct.isSetAse()) {
          optionals.set(3);
        }
        if (struct.isSetAe()) {
          optionals.set(4);
        }
        oprot.writeBitSet(optionals, 5);
        if (struct.isSetSuccess()) {
          struct.success.write(oprot);
        }
        if (struct.isSetIre()) {
          struct.ire.write(oprot);
        }
        if (struct.isSetAce()) {
          struct.ace.write(oprot);
        }
        if (struct.isSetAse()) {
          struct.ase.write(oprot);
        }
        if (struct.isSetAe()) {
          struct.ae.write(oprot);
        }
      }

      @Override
      public void read(org.apache.thrift.protocol.TProtocol prot, getLocalDataMovement_result struct) throws org.apache.thrift.TException {
        TTupleProtocol iprot = (TTupleProtocol) prot;
        BitSet incoming = iprot.readBitSet(5);
        if (incoming.get(0)) {
          struct.success = new org.apache.airavata.model.appcatalog.computeresource.LOCALDataMovement();
          struct.success.read(iprot);
          struct.setSuccessIsSet(true);
        }
        if (incoming.get(1)) {
          struct.ire = new org.apache.airavata.model.error.InvalidRequestException();
          struct.ire.read(iprot);
          struct.setIreIsSet(true);
        }
        if (incoming.get(2)) {
          struct.ace = new org.apache.airavata.model.error.AiravataClientException();
          struct.ace.read(iprot);
          struct.setAceIsSet(true);
        }
        if (incoming.get(3)) {
          struct.ase = new org.apache.airavata.model.error.AiravataSystemException();
          struct.ase.read(iprot);
          struct.setAseIsSet(true);
        }
        if (incoming.get(4)) {
          struct.ae = new org.apache.airavata.model.error.AuthorizationException();
          struct.ae.read(iprot);
          struct.setAeIsSet(true);
        }
      }
    }

  }

  public static class addSCPDataMovementDetails_args implements org.apache.thrift.TBase<addSCPDataMovementDetails_args, addSCPDataMovementDetails_args._Fields>, java.io.Serializable, Cloneable, Comparable<addSCPDataMovementDetails_args>   {
    private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("addSCPDataMovementDetails_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 COMPUTE_RESOURCE_ID_FIELD_DESC = new org.apache.thrift.protocol.TField("computeResourceId", org.apache.thrift.protocol.TType.STRING, (short)2);
    private static final org.apache.thrift.protocol.TField PRIORITY_ORDER_FIELD_DESC = new org.apache.thrift.protocol.TField("priorityOrder", org.apache.thrift.protocol.TType.I32, (short)3);
    private static final org.apache.thrift.protocol.TField SCP_DATA_MOVEMENT_FIELD_DESC = new org.apache.thrift.protocol.TField("scpDataMovement", org.apache.thrift.protocol.TType.STRUCT, (short)4);

    private static final Map<Class<? extends IScheme>, SchemeFactory> schemes = new HashMap<Class<? extends IScheme>, SchemeFactory>();
    static {
      schemes.put(StandardScheme.class, new addSCPDataMovementDetails_argsStandardSchemeFactory());
      schemes.put(TupleScheme.class, new addSCPDataMovementDetails_argsTupleSchemeFactory());
    }

    public org.apache.airavata.model.security.AuthzToken authzToken; // required
    public String computeResourceId; // required
    public int priorityOrder; // required
    public org.apache.airavata.model.appcatalog.computeresource.SCPDataMovement scpDataMovement; // required

    /** 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"),
      COMPUTE_RESOURCE_ID((short)2, "computeResourceId"),
      PRIORITY_ORDER((short)3, "priorityOrder"),
      SCP_DATA_MOVEMENT((short)4, "scpDataMovement");

      private static final Map<String, _Fields> byName = new HashMap<String, _Fields>();

      static {
        for (_Fields field : EnumSet.allOf(_Fields.class)) {
          byName.put(field.getFieldName(), field);
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, or null if its not found.
       */
      public static _Fields findByThriftId(int fieldId) {
        switch(fieldId) {
          case 1: // AUTHZ_TOKEN
            return AUTHZ_TOKEN;
          case 2: // COMPUTE_RESOURCE_ID
            return COMPUTE_RESOURCE_ID;
          case 3: // PRIORITY_ORDER
            return PRIORITY_ORDER;
          case 4: // SCP_DATA_MOVEMENT
            return SCP_DATA_MOVEMENT;
          default:
            return null;
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, throwing an exception
       * if it is not found.
       */
      public static _Fields findByThriftIdOrThrow(int fieldId) {
        _Fields fields = findByThriftId(fieldId);
        if (fields == null) throw new IllegalArgumentException("Field " + fieldId + " doesn't exist!");
        return fields;
      }

      /**
       * Find the _Fields constant that matches name, or null if its not found.
       */
      public static _Fields findByName(String name) {
        return byName.get(name);
      }

      private final short _thriftId;
      private final String _fieldName;

      _Fields(short thriftId, String fieldName) {
        _thriftId = thriftId;
        _fieldName = fieldName;
      }

      public short getThriftFieldId() {
        return _thriftId;
      }

      public String getFieldName() {
        return _fieldName;
      }
    }

    // isset id assignments
    private static final int __PRIORITYORDER_ISSET_ID = 0;
    private byte __isset_bitfield = 0;
    public static final Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
    static {
      Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new EnumMap<_Fields, org.apache.thrift.meta_data.FieldMetaData>(_Fields.class);
      tmpMap.put(_Fields.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.COMPUTE_RESOURCE_ID, new org.apache.thrift.meta_data.FieldMetaData("computeResourceId", org.apache.thrift.TFieldRequirementType.REQUIRED, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING)));
      tmpMap.put(_Fields.PRIORITY_ORDER, new org.apache.thrift.meta_data.FieldMetaData("priorityOrder", org.apache.thrift.TFieldRequirementType.REQUIRED, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.I32)));
      tmpMap.put(_Fields.SCP_DATA_MOVEMENT, new org.apache.thrift.meta_data.FieldMetaData("scpDataMovement", org.apache.thrift.TFieldRequirementType.REQUIRED, 
          new org.apache.thrift.meta_data.StructMetaData(org.apache.thrift.protocol.TType.STRUCT, org.apache.airavata.model.appcatalog.computeresource.SCPDataMovement.class)));
      metaDataMap = Collections.unmodifiableMap(tmpMap);
      org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(addSCPDataMovementDetails_args.class, metaDataMap);
    }

    public addSCPDataMovementDetails_args() {
    }

    public addSCPDataMovementDetails_args(
      org.apache.airavata.model.security.AuthzToken authzToken,
      String computeResourceId,
      int priorityOrder,
      org.apache.airavata.model.appcatalog.computeresource.SCPDataMovement scpDataMovement)
    {
      this();
      this.authzToken = authzToken;
      this.computeResourceId = computeResourceId;
      this.priorityOrder = priorityOrder;
      setPriorityOrderIsSet(true);
      this.scpDataMovement = scpDataMovement;
    }

    /**
     * Performs a deep copy on <i>other</i>.
     */
    public addSCPDataMovementDetails_args(addSCPDataMovementDetails_args other) {
      __isset_bitfield = other.__isset_bitfield;
      if (other.isSetAuthzToken()) {
        this.authzToken = new org.apache.airavata.model.security.AuthzToken(other.authzToken);
      }
      if (other.isSetComputeResourceId()) {
        this.computeResourceId = other.computeResourceId;
      }
      this.priorityOrder = other.priorityOrder;
      if (other.isSetScpDataMovement()) {
        this.scpDataMovement = new org.apache.airavata.model.appcatalog.computeresource.SCPDataMovement(other.scpDataMovement);
      }
    }

    public addSCPDataMovementDetails_args deepCopy() {
      return new addSCPDataMovementDetails_args(this);
    }

    @Override
    public void clear() {
      this.authzToken = null;
      this.computeResourceId = null;
      setPriorityOrderIsSet(false);
      this.priorityOrder = 0;
      this.scpDataMovement = null;
    }

    public org.apache.airavata.model.security.AuthzToken getAuthzToken() {
      return this.authzToken;
    }

    public addSCPDataMovementDetails_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 String getComputeResourceId() {
      return this.computeResourceId;
    }

    public addSCPDataMovementDetails_args setComputeResourceId(String computeResourceId) {
      this.computeResourceId = computeResourceId;
      return this;
    }

    public void unsetComputeResourceId() {
      this.computeResourceId = null;
    }

    /** Returns true if field computeResourceId is set (has been assigned a value) and false otherwise */
    public boolean isSetComputeResourceId() {
      return this.computeResourceId != null;
    }

    public void setComputeResourceIdIsSet(boolean value) {
      if (!value) {
        this.computeResourceId = null;
      }
    }

    public int getPriorityOrder() {
      return this.priorityOrder;
    }

    public addSCPDataMovementDetails_args setPriorityOrder(int priorityOrder) {
      this.priorityOrder = priorityOrder;
      setPriorityOrderIsSet(true);
      return this;
    }

    public void unsetPriorityOrder() {
      __isset_bitfield = EncodingUtils.clearBit(__isset_bitfield, __PRIORITYORDER_ISSET_ID);
    }

    /** Returns true if field priorityOrder is set (has been assigned a value) and false otherwise */
    public boolean isSetPriorityOrder() {
      return EncodingUtils.testBit(__isset_bitfield, __PRIORITYORDER_ISSET_ID);
    }

    public void setPriorityOrderIsSet(boolean value) {
      __isset_bitfield = EncodingUtils.setBit(__isset_bitfield, __PRIORITYORDER_ISSET_ID, value);
    }

    public org.apache.airavata.model.appcatalog.computeresource.SCPDataMovement getScpDataMovement() {
      return this.scpDataMovement;
    }

    public addSCPDataMovementDetails_args setScpDataMovement(org.apache.airavata.model.appcatalog.computeresource.SCPDataMovement scpDataMovement) {
      this.scpDataMovement = scpDataMovement;
      return this;
    }

    public void unsetScpDataMovement() {
      this.scpDataMovement = null;
    }

    /** Returns true if field scpDataMovement is set (has been assigned a value) and false otherwise */
    public boolean isSetScpDataMovement() {
      return this.scpDataMovement != null;
    }

    public void setScpDataMovementIsSet(boolean value) {
      if (!value) {
        this.scpDataMovement = null;
      }
    }

    public void setFieldValue(_Fields field, Object value) {
      switch (field) {
      case AUTHZ_TOKEN:
        if (value == null) {
          unsetAuthzToken();
        } else {
          setAuthzToken((org.apache.airavata.model.security.AuthzToken)value);
        }
        break;

      case COMPUTE_RESOURCE_ID:
        if (value == null) {
          unsetComputeResourceId();
        } else {
          setComputeResourceId((String)value);
        }
        break;

      case PRIORITY_ORDER:
        if (value == null) {
          unsetPriorityOrder();
        } else {
          setPriorityOrder((Integer)value);
        }
        break;

      case SCP_DATA_MOVEMENT:
        if (value == null) {
          unsetScpDataMovement();
        } else {
          setScpDataMovement((org.apache.airavata.model.appcatalog.computeresource.SCPDataMovement)value);
        }
        break;

      }
    }

    public Object getFieldValue(_Fields field) {
      switch (field) {
      case AUTHZ_TOKEN:
        return getAuthzToken();

      case COMPUTE_RESOURCE_ID:
        return getComputeResourceId();

      case PRIORITY_ORDER:
        return Integer.valueOf(getPriorityOrder());

      case SCP_DATA_MOVEMENT:
        return getScpDataMovement();

      }
      throw new IllegalStateException();
    }

    /** Returns true if field corresponding to fieldID is set (has been assigned a value) and false otherwise */
    public boolean isSet(_Fields field) {
      if (field == null) {
        throw new IllegalArgumentException();
      }

      switch (field) {
      case AUTHZ_TOKEN:
        return isSetAuthzToken();
      case COMPUTE_RESOURCE_ID:
        return isSetComputeResourceId();
      case PRIORITY_ORDER:
        return isSetPriorityOrder();
      case SCP_DATA_MOVEMENT:
        return isSetScpDataMovement();
      }
      throw new IllegalStateException();
    }

    @Override
    public boolean equals(Object that) {
      if (that == null)
        return false;
      if (that instanceof addSCPDataMovementDetails_args)
        return this.equals((addSCPDataMovementDetails_args)that);
      return false;
    }

    public boolean equals(addSCPDataMovementDetails_args that) {
      if (that == null)
        return false;

      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_computeResourceId = true && this.isSetComputeResourceId();
      boolean that_present_computeResourceId = true && that.isSetComputeResourceId();
      if (this_present_computeResourceId || that_present_computeResourceId) {
        if (!(this_present_computeResourceId && that_present_computeResourceId))
          return false;
        if (!this.computeResourceId.equals(that.computeResourceId))
          return false;
      }

      boolean this_present_priorityOrder = true;
      boolean that_present_priorityOrder = true;
      if (this_present_priorityOrder || that_present_priorityOrder) {
        if (!(this_present_priorityOrder && that_present_priorityOrder))
          return false;
        if (this.priorityOrder != that.priorityOrder)
          return false;
      }

      boolean this_present_scpDataMovement = true && this.isSetScpDataMovement();
      boolean that_present_scpDataMovement = true && that.isSetScpDataMovement();
      if (this_present_scpDataMovement || that_present_scpDataMovement) {
        if (!(this_present_scpDataMovement && that_present_scpDataMovement))
          return false;
        if (!this.scpDataMovement.equals(that.scpDataMovement))
          return false;
      }

      return true;
    }

    @Override
    public int hashCode() {
      List<Object> list = new ArrayList<Object>();

      boolean present_authzToken = true && (isSetAuthzToken());
      list.add(present_authzToken);
      if (present_authzToken)
        list.add(authzToken);

      boolean present_computeResourceId = true && (isSetComputeResourceId());
      list.add(present_computeResourceId);
      if (present_computeResourceId)
        list.add(computeResourceId);

      boolean present_priorityOrder = true;
      list.add(present_priorityOrder);
      if (present_priorityOrder)
        list.add(priorityOrder);

      boolean present_scpDataMovement = true && (isSetScpDataMovement());
      list.add(present_scpDataMovement);
      if (present_scpDataMovement)
        list.add(scpDataMovement);

      return list.hashCode();
    }

    @Override
    public int compareTo(addSCPDataMovementDetails_args other) {
      if (!getClass().equals(other.getClass())) {
        return getClass().getName().compareTo(other.getClass().getName());
      }

      int lastComparison = 0;

      lastComparison = 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 = Boolean.valueOf(isSetComputeResourceId()).compareTo(other.isSetComputeResourceId());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetComputeResourceId()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.computeResourceId, other.computeResourceId);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = Boolean.valueOf(isSetPriorityOrder()).compareTo(other.isSetPriorityOrder());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetPriorityOrder()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.priorityOrder, other.priorityOrder);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = Boolean.valueOf(isSetScpDataMovement()).compareTo(other.isSetScpDataMovement());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetScpDataMovement()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.scpDataMovement, other.scpDataMovement);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      return 0;
    }

    public _Fields fieldForId(int fieldId) {
      return _Fields.findByThriftId(fieldId);
    }

    public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
      schemes.get(iprot.getScheme()).getScheme().read(iprot, this);
    }

    public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException {
      schemes.get(oprot.getScheme()).getScheme().write(oprot, this);
    }

    @Override
    public String toString() {
      StringBuilder sb = new StringBuilder("addSCPDataMovementDetails_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("computeResourceId:");
      if (this.computeResourceId == null) {
        sb.append("null");
      } else {
        sb.append(this.computeResourceId);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("priorityOrder:");
      sb.append(this.priorityOrder);
      first = false;
      if (!first) sb.append(", ");
      sb.append("scpDataMovement:");
      if (this.scpDataMovement == null) {
        sb.append("null");
      } else {
        sb.append(this.scpDataMovement);
      }
      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 (computeResourceId == null) {
        throw new org.apache.thrift.protocol.TProtocolException("Required field 'computeResourceId' was not present! Struct: " + toString());
      }
      // alas, we cannot check 'priorityOrder' because it's a primitive and you chose the non-beans generator.
      if (scpDataMovement == null) {
        throw new org.apache.thrift.protocol.TProtocolException("Required field 'scpDataMovement' was not present! Struct: " + toString());
      }
      // check for sub-struct validity
      if (authzToken != null) {
        authzToken.validate();
      }
      if (scpDataMovement != null) {
        scpDataMovement.validate();
      }
    }

    private void writeObject(java.io.ObjectOutputStream out) throws java.io.IOException {
      try {
        write(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(out)));
      } catch (org.apache.thrift.TException te) {
        throw new java.io.IOException(te);
      }
    }

    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, ClassNotFoundException {
      try {
        // 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 addSCPDataMovementDetails_argsStandardSchemeFactory implements SchemeFactory {
      public addSCPDataMovementDetails_argsStandardScheme getScheme() {
        return new addSCPDataMovementDetails_argsStandardScheme();
      }
    }

    private static class addSCPDataMovementDetails_argsStandardScheme extends StandardScheme<addSCPDataMovementDetails_args> {

      public void read(org.apache.thrift.protocol.TProtocol iprot, addSCPDataMovementDetails_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: // COMPUTE_RESOURCE_ID
              if (schemeField.type == org.apache.thrift.protocol.TType.STRING) {
                struct.computeResourceId = iprot.readString();
                struct.setComputeResourceIdIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 3: // PRIORITY_ORDER
              if (schemeField.type == org.apache.thrift.protocol.TType.I32) {
                struct.priorityOrder = iprot.readI32();
                struct.setPriorityOrderIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 4: // SCP_DATA_MOVEMENT
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.scpDataMovement = new org.apache.airavata.model.appcatalog.computeresource.SCPDataMovement();
                struct.scpDataMovement.read(iprot);
                struct.setScpDataMovementIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            default:
              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
          }
          iprot.readFieldEnd();
        }
        iprot.readStructEnd();

        // check for required fields of primitive type, which can't be checked in the validate method
        if (!struct.isSetPriorityOrder()) {
          throw new org.apache.thrift.protocol.TProtocolException("Required field 'priorityOrder' was not found in serialized data! Struct: " + toString());
        }
        struct.validate();
      }

      public void write(org.apache.thrift.protocol.TProtocol oprot, addSCPDataMovementDetails_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.computeResourceId != null) {
          oprot.writeFieldBegin(COMPUTE_RESOURCE_ID_FIELD_DESC);
          oprot.writeString(struct.computeResourceId);
          oprot.writeFieldEnd();
        }
        oprot.writeFieldBegin(PRIORITY_ORDER_FIELD_DESC);
        oprot.writeI32(struct.priorityOrder);
        oprot.writeFieldEnd();
        if (struct.scpDataMovement != null) {
          oprot.writeFieldBegin(SCP_DATA_MOVEMENT_FIELD_DESC);
          struct.scpDataMovement.write(oprot);
          oprot.writeFieldEnd();
        }
        oprot.writeFieldStop();
        oprot.writeStructEnd();
      }

    }

    private static class addSCPDataMovementDetails_argsTupleSchemeFactory implements SchemeFactory {
      public addSCPDataMovementDetails_argsTupleScheme getScheme() {
        return new addSCPDataMovementDetails_argsTupleScheme();
      }
    }

    private static class addSCPDataMovementDetails_argsTupleScheme extends TupleScheme<addSCPDataMovementDetails_args> {

      @Override
      public void write(org.apache.thrift.protocol.TProtocol prot, addSCPDataMovementDetails_args struct) throws org.apache.thrift.TException {
        TTupleProtocol oprot = (TTupleProtocol) prot;
        struct.authzToken.write(oprot);
        oprot.writeString(struct.computeResourceId);
        oprot.writeI32(struct.priorityOrder);
        struct.scpDataMovement.write(oprot);
      }

      @Override
      public void read(org.apache.thrift.protocol.TProtocol prot, addSCPDataMovementDetails_args struct) throws org.apache.thrift.TException {
        TTupleProtocol iprot = (TTupleProtocol) prot;
        struct.authzToken = new org.apache.airavata.model.security.AuthzToken();
        struct.authzToken.read(iprot);
        struct.setAuthzTokenIsSet(true);
        struct.computeResourceId = iprot.readString();
        struct.setComputeResourceIdIsSet(true);
        struct.priorityOrder = iprot.readI32();
        struct.setPriorityOrderIsSet(true);
        struct.scpDataMovement = new org.apache.airavata.model.appcatalog.computeresource.SCPDataMovement();
        struct.scpDataMovement.read(iprot);
        struct.setScpDataMovementIsSet(true);
      }
    }

  }

  public static class addSCPDataMovementDetails_result implements org.apache.thrift.TBase<addSCPDataMovementDetails_result, addSCPDataMovementDetails_result._Fields>, java.io.Serializable, Cloneable, Comparable<addSCPDataMovementDetails_result>   {
    private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("addSCPDataMovementDetails_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 IRE_FIELD_DESC = new org.apache.thrift.protocol.TField("ire", org.apache.thrift.protocol.TType.STRUCT, (short)1);
    private static final org.apache.thrift.protocol.TField ACE_FIELD_DESC = new org.apache.thrift.protocol.TField("ace", org.apache.thrift.protocol.TType.STRUCT, (short)2);
    private static final org.apache.thrift.protocol.TField ASE_FIELD_DESC = new org.apache.thrift.protocol.TField("ase", org.apache.thrift.protocol.TType.STRUCT, (short)3);
    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)4);

    private static final Map<Class<? extends IScheme>, SchemeFactory> schemes = new HashMap<Class<? extends IScheme>, SchemeFactory>();
    static {
      schemes.put(StandardScheme.class, new addSCPDataMovementDetails_resultStandardSchemeFactory());
      schemes.put(TupleScheme.class, new addSCPDataMovementDetails_resultTupleSchemeFactory());
    }

    public String success; // required
    public org.apache.airavata.model.error.InvalidRequestException ire; // required
    public org.apache.airavata.model.error.AiravataClientException ace; // required
    public org.apache.airavata.model.error.AiravataSystemException ase; // 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"),
      IRE((short)1, "ire"),
      ACE((short)2, "ace"),
      ASE((short)3, "ase"),
      AE((short)4, "ae");

      private static final Map<String, _Fields> byName = new HashMap<String, _Fields>();

      static {
        for (_Fields field : EnumSet.allOf(_Fields.class)) {
          byName.put(field.getFieldName(), field);
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, or null if its not found.
       */
      public static _Fields findByThriftId(int fieldId) {
        switch(fieldId) {
          case 0: // SUCCESS
            return SUCCESS;
          case 1: // IRE
            return IRE;
          case 2: // ACE
            return ACE;
          case 3: // ASE
            return ASE;
          case 4: // 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 IllegalArgumentException("Field " + fieldId + " doesn't exist!");
        return fields;
      }

      /**
       * Find the _Fields constant that matches name, or null if its not found.
       */
      public static _Fields findByName(String name) {
        return byName.get(name);
      }

      private final short _thriftId;
      private final String _fieldName;

      _Fields(short thriftId, String fieldName) {
        _thriftId = thriftId;
        _fieldName = fieldName;
      }

      public short getThriftFieldId() {
        return _thriftId;
      }

      public String getFieldName() {
        return _fieldName;
      }
    }

    // isset id assignments
    public static final Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
    static {
      Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new EnumMap<_Fields, org.apache.thrift.meta_data.FieldMetaData>(_Fields.class);
      tmpMap.put(_Fields.SUCCESS, new org.apache.thrift.meta_data.FieldMetaData("success", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING)));
      tmpMap.put(_Fields.IRE, new org.apache.thrift.meta_data.FieldMetaData("ire", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRUCT)));
      tmpMap.put(_Fields.ACE, new org.apache.thrift.meta_data.FieldMetaData("ace", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRUCT)));
      tmpMap.put(_Fields.ASE, new org.apache.thrift.meta_data.FieldMetaData("ase", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRUCT)));
      tmpMap.put(_Fields.AE, new org.apache.thrift.meta_data.FieldMetaData("ae", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRUCT)));
      metaDataMap = Collections.unmodifiableMap(tmpMap);
      org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(addSCPDataMovementDetails_result.class, metaDataMap);
    }

    public addSCPDataMovementDetails_result() {
    }

    public addSCPDataMovementDetails_result(
      String success,
      org.apache.airavata.model.error.InvalidRequestException ire,
      org.apache.airavata.model.error.AiravataClientException ace,
      org.apache.airavata.model.error.AiravataSystemException ase,
      org.apache.airavata.model.error.AuthorizationException ae)
    {
      this();
      this.success = success;
      this.ire = ire;
      this.ace = ace;
      this.ase = ase;
      this.ae = ae;
    }

    /**
     * Performs a deep copy on <i>other</i>.
     */
    public addSCPDataMovementDetails_result(addSCPDataMovementDetails_result other) {
      if (other.isSetSuccess()) {
        this.success = other.success;
      }
      if (other.isSetIre()) {
        this.ire = new org.apache.airavata.model.error.InvalidRequestException(other.ire);
      }
      if (other.isSetAce()) {
        this.ace = new org.apache.airavata.model.error.AiravataClientException(other.ace);
      }
      if (other.isSetAse()) {
        this.ase = new org.apache.airavata.model.error.AiravataSystemException(other.ase);
      }
      if (other.isSetAe()) {
        this.ae = new org.apache.airavata.model.error.AuthorizationException(other.ae);
      }
    }

    public addSCPDataMovementDetails_result deepCopy() {
      return new addSCPDataMovementDetails_result(this);
    }

    @Override
    public void clear() {
      this.success = null;
      this.ire = null;
      this.ace = null;
      this.ase = null;
      this.ae = null;
    }

    public String getSuccess() {
      return this.success;
    }

    public addSCPDataMovementDetails_result setSuccess(String success) {
      this.success = success;
      return this;
    }

    public void unsetSuccess() {
      this.success = null;
    }

    /** Returns true if field success is set (has been assigned a value) and false otherwise */
    public boolean isSetSuccess() {
      return this.success != null;
    }

    public void setSuccessIsSet(boolean value) {
      if (!value) {
        this.success = null;
      }
    }

    public org.apache.airavata.model.error.InvalidRequestException getIre() {
      return this.ire;
    }

    public addSCPDataMovementDetails_result setIre(org.apache.airavata.model.error.InvalidRequestException ire) {
      this.ire = ire;
      return this;
    }

    public void unsetIre() {
      this.ire = null;
    }

    /** Returns true if field ire is set (has been assigned a value) and false otherwise */
    public boolean isSetIre() {
      return this.ire != null;
    }

    public void setIreIsSet(boolean value) {
      if (!value) {
        this.ire = null;
      }
    }

    public org.apache.airavata.model.error.AiravataClientException getAce() {
      return this.ace;
    }

    public addSCPDataMovementDetails_result setAce(org.apache.airavata.model.error.AiravataClientException ace) {
      this.ace = ace;
      return this;
    }

    public void unsetAce() {
      this.ace = null;
    }

    /** Returns true if field ace is set (has been assigned a value) and false otherwise */
    public boolean isSetAce() {
      return this.ace != null;
    }

    public void setAceIsSet(boolean value) {
      if (!value) {
        this.ace = null;
      }
    }

    public org.apache.airavata.model.error.AiravataSystemException getAse() {
      return this.ase;
    }

    public addSCPDataMovementDetails_result setAse(org.apache.airavata.model.error.AiravataSystemException ase) {
      this.ase = ase;
      return this;
    }

    public void unsetAse() {
      this.ase = null;
    }

    /** Returns true if field ase is set (has been assigned a value) and false otherwise */
    public boolean isSetAse() {
      return this.ase != null;
    }

    public void setAseIsSet(boolean value) {
      if (!value) {
        this.ase = null;
      }
    }

    public org.apache.airavata.model.error.AuthorizationException getAe() {
      return this.ae;
    }

    public addSCPDataMovementDetails_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, Object value) {
      switch (field) {
      case SUCCESS:
        if (value == null) {
          unsetSuccess();
        } else {
          setSuccess((String)value);
        }
        break;

      case IRE:
        if (value == null) {
          unsetIre();
        } else {
          setIre((org.apache.airavata.model.error.InvalidRequestException)value);
        }
        break;

      case ACE:
        if (value == null) {
          unsetAce();
        } else {
          setAce((org.apache.airavata.model.error.AiravataClientException)value);
        }
        break;

      case ASE:
        if (value == null) {
          unsetAse();
        } else {
          setAse((org.apache.airavata.model.error.AiravataSystemException)value);
        }
        break;

      case AE:
        if (value == null) {
          unsetAe();
        } else {
          setAe((org.apache.airavata.model.error.AuthorizationException)value);
        }
        break;

      }
    }

    public Object getFieldValue(_Fields field) {
      switch (field) {
      case SUCCESS:
        return getSuccess();

      case IRE:
        return getIre();

      case ACE:
        return getAce();

      case ASE:
        return getAse();

      case AE:
        return getAe();

      }
      throw new IllegalStateException();
    }

    /** Returns true if field corresponding to fieldID is set (has been assigned a value) and false otherwise */
    public boolean isSet(_Fields field) {
      if (field == null) {
        throw new IllegalArgumentException();
      }

      switch (field) {
      case SUCCESS:
        return isSetSuccess();
      case IRE:
        return isSetIre();
      case ACE:
        return isSetAce();
      case ASE:
        return isSetAse();
      case AE:
        return isSetAe();
      }
      throw new IllegalStateException();
    }

    @Override
    public boolean equals(Object that) {
      if (that == null)
        return false;
      if (that instanceof addSCPDataMovementDetails_result)
        return this.equals((addSCPDataMovementDetails_result)that);
      return false;
    }

    public boolean equals(addSCPDataMovementDetails_result that) {
      if (that == null)
        return false;

      boolean this_present_success = true && this.isSetSuccess();
      boolean that_present_success = true && that.isSetSuccess();
      if (this_present_success || that_present_success) {
        if (!(this_present_success && that_present_success))
          return false;
        if (!this.success.equals(that.success))
          return false;
      }

      boolean this_present_ire = true && this.isSetIre();
      boolean that_present_ire = true && that.isSetIre();
      if (this_present_ire || that_present_ire) {
        if (!(this_present_ire && that_present_ire))
          return false;
        if (!this.ire.equals(that.ire))
          return false;
      }

      boolean this_present_ace = true && this.isSetAce();
      boolean that_present_ace = true && that.isSetAce();
      if (this_present_ace || that_present_ace) {
        if (!(this_present_ace && that_present_ace))
          return false;
        if (!this.ace.equals(that.ace))
          return false;
      }

      boolean this_present_ase = true && this.isSetAse();
      boolean that_present_ase = true && that.isSetAse();
      if (this_present_ase || that_present_ase) {
        if (!(this_present_ase && that_present_ase))
          return false;
        if (!this.ase.equals(that.ase))
          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() {
      List<Object> list = new ArrayList<Object>();

      boolean present_success = true && (isSetSuccess());
      list.add(present_success);
      if (present_success)
        list.add(success);

      boolean present_ire = true && (isSetIre());
      list.add(present_ire);
      if (present_ire)
        list.add(ire);

      boolean present_ace = true && (isSetAce());
      list.add(present_ace);
      if (present_ace)
        list.add(ace);

      boolean present_ase = true && (isSetAse());
      list.add(present_ase);
      if (present_ase)
        list.add(ase);

      boolean present_ae = true && (isSetAe());
      list.add(present_ae);
      if (present_ae)
        list.add(ae);

      return list.hashCode();
    }

    @Override
    public int compareTo(addSCPDataMovementDetails_result other) {
      if (!getClass().equals(other.getClass())) {
        return getClass().getName().compareTo(other.getClass().getName());
      }

      int lastComparison = 0;

      lastComparison = Boolean.valueOf(isSetSuccess()).compareTo(other.isSetSuccess());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetSuccess()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.success, other.success);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = Boolean.valueOf(isSetIre()).compareTo(other.isSetIre());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetIre()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.ire, other.ire);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = Boolean.valueOf(isSetAce()).compareTo(other.isSetAce());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetAce()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.ace, other.ace);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = Boolean.valueOf(isSetAse()).compareTo(other.isSetAse());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetAse()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.ase, other.ase);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = 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 {
      schemes.get(iprot.getScheme()).getScheme().read(iprot, this);
    }

    public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException {
      schemes.get(oprot.getScheme()).getScheme().write(oprot, this);
      }

    @Override
    public String toString() {
      StringBuilder sb = new StringBuilder("addSCPDataMovementDetails_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("ire:");
      if (this.ire == null) {
        sb.append("null");
      } else {
        sb.append(this.ire);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("ace:");
      if (this.ace == null) {
        sb.append("null");
      } else {
        sb.append(this.ace);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("ase:");
      if (this.ase == null) {
        sb.append("null");
      } else {
        sb.append(this.ase);
      }
      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, 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 addSCPDataMovementDetails_resultStandardSchemeFactory implements SchemeFactory {
      public addSCPDataMovementDetails_resultStandardScheme getScheme() {
        return new addSCPDataMovementDetails_resultStandardScheme();
      }
    }

    private static class addSCPDataMovementDetails_resultStandardScheme extends StandardScheme<addSCPDataMovementDetails_result> {

      public void read(org.apache.thrift.protocol.TProtocol iprot, addSCPDataMovementDetails_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: // IRE
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.ire = new org.apache.airavata.model.error.InvalidRequestException();
                struct.ire.read(iprot);
                struct.setIreIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 2: // ACE
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.ace = new org.apache.airavata.model.error.AiravataClientException();
                struct.ace.read(iprot);
                struct.setAceIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 3: // ASE
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.ase = new org.apache.airavata.model.error.AiravataSystemException();
                struct.ase.read(iprot);
                struct.setAseIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 4: // 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, addSCPDataMovementDetails_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.ire != null) {
          oprot.writeFieldBegin(IRE_FIELD_DESC);
          struct.ire.write(oprot);
          oprot.writeFieldEnd();
        }
        if (struct.ace != null) {
          oprot.writeFieldBegin(ACE_FIELD_DESC);
          struct.ace.write(oprot);
          oprot.writeFieldEnd();
        }
        if (struct.ase != null) {
          oprot.writeFieldBegin(ASE_FIELD_DESC);
          struct.ase.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 addSCPDataMovementDetails_resultTupleSchemeFactory implements SchemeFactory {
      public addSCPDataMovementDetails_resultTupleScheme getScheme() {
        return new addSCPDataMovementDetails_resultTupleScheme();
      }
    }

    private static class addSCPDataMovementDetails_resultTupleScheme extends TupleScheme<addSCPDataMovementDetails_result> {

      @Override
      public void write(org.apache.thrift.protocol.TProtocol prot, addSCPDataMovementDetails_result struct) throws org.apache.thrift.TException {
        TTupleProtocol oprot = (TTupleProtocol) prot;
        BitSet optionals = new BitSet();
        if (struct.isSetSuccess()) {
          optionals.set(0);
        }
        if (struct.isSetIre()) {
          optionals.set(1);
        }
        if (struct.isSetAce()) {
          optionals.set(2);
        }
        if (struct.isSetAse()) {
          optionals.set(3);
        }
        if (struct.isSetAe()) {
          optionals.set(4);
        }
        oprot.writeBitSet(optionals, 5);
        if (struct.isSetSuccess()) {
          oprot.writeString(struct.success);
        }
        if (struct.isSetIre()) {
          struct.ire.write(oprot);
        }
        if (struct.isSetAce()) {
          struct.ace.write(oprot);
        }
        if (struct.isSetAse()) {
          struct.ase.write(oprot);
        }
        if (struct.isSetAe()) {
          struct.ae.write(oprot);
        }
      }

      @Override
      public void read(org.apache.thrift.protocol.TProtocol prot, addSCPDataMovementDetails_result struct) throws org.apache.thrift.TException {
        TTupleProtocol iprot = (TTupleProtocol) prot;
        BitSet incoming = iprot.readBitSet(5);
        if (incoming.get(0)) {
          struct.success = iprot.readString();
          struct.setSuccessIsSet(true);
        }
        if (incoming.get(1)) {
          struct.ire = new org.apache.airavata.model.error.InvalidRequestException();
          struct.ire.read(iprot);
          struct.setIreIsSet(true);
        }
        if (incoming.get(2)) {
          struct.ace = new org.apache.airavata.model.error.AiravataClientException();
          struct.ace.read(iprot);
          struct.setAceIsSet(true);
        }
        if (incoming.get(3)) {
          struct.ase = new org.apache.airavata.model.error.AiravataSystemException();
          struct.ase.read(iprot);
          struct.setAseIsSet(true);
        }
        if (incoming.get(4)) {
          struct.ae = new org.apache.airavata.model.error.AuthorizationException();
          struct.ae.read(iprot);
          struct.setAeIsSet(true);
        }
      }
    }

  }

  public static class updateSCPDataMovementDetails_args implements org.apache.thrift.TBase<updateSCPDataMovementDetails_args, updateSCPDataMovementDetails_args._Fields>, java.io.Serializable, Cloneable, Comparable<updateSCPDataMovementDetails_args>   {
    private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("updateSCPDataMovementDetails_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 DATA_MOVEMENT_INTERFACE_ID_FIELD_DESC = new org.apache.thrift.protocol.TField("dataMovementInterfaceId", org.apache.thrift.protocol.TType.STRING, (short)2);
    private static final org.apache.thrift.protocol.TField SCP_DATA_MOVEMENT_FIELD_DESC = new org.apache.thrift.protocol.TField("scpDataMovement", org.apache.thrift.protocol.TType.STRUCT, (short)3);

    private static final Map<Class<? extends IScheme>, SchemeFactory> schemes = new HashMap<Class<? extends IScheme>, SchemeFactory>();
    static {
      schemes.put(StandardScheme.class, new updateSCPDataMovementDetails_argsStandardSchemeFactory());
      schemes.put(TupleScheme.class, new updateSCPDataMovementDetails_argsTupleSchemeFactory());
    }

    public org.apache.airavata.model.security.AuthzToken authzToken; // required
    public String dataMovementInterfaceId; // required
    public org.apache.airavata.model.appcatalog.computeresource.SCPDataMovement scpDataMovement; // required

    /** 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"),
      DATA_MOVEMENT_INTERFACE_ID((short)2, "dataMovementInterfaceId"),
      SCP_DATA_MOVEMENT((short)3, "scpDataMovement");

      private static final Map<String, _Fields> byName = new HashMap<String, _Fields>();

      static {
        for (_Fields field : EnumSet.allOf(_Fields.class)) {
          byName.put(field.getFieldName(), field);
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, or null if its not found.
       */
      public static _Fields findByThriftId(int fieldId) {
        switch(fieldId) {
          case 1: // AUTHZ_TOKEN
            return AUTHZ_TOKEN;
          case 2: // DATA_MOVEMENT_INTERFACE_ID
            return DATA_MOVEMENT_INTERFACE_ID;
          case 3: // SCP_DATA_MOVEMENT
            return SCP_DATA_MOVEMENT;
          default:
            return null;
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, throwing an exception
       * if it is not found.
       */
      public static _Fields findByThriftIdOrThrow(int fieldId) {
        _Fields fields = findByThriftId(fieldId);
        if (fields == null) throw new IllegalArgumentException("Field " + fieldId + " doesn't exist!");
        return fields;
      }

      /**
       * Find the _Fields constant that matches name, or null if its not found.
       */
      public static _Fields findByName(String name) {
        return byName.get(name);
      }

      private final short _thriftId;
      private final String _fieldName;

      _Fields(short thriftId, String fieldName) {
        _thriftId = thriftId;
        _fieldName = fieldName;
      }

      public short getThriftFieldId() {
        return _thriftId;
      }

      public String getFieldName() {
        return _fieldName;
      }
    }

    // isset id assignments
    public static final Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
    static {
      Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new EnumMap<_Fields, org.apache.thrift.meta_data.FieldMetaData>(_Fields.class);
      tmpMap.put(_Fields.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.DATA_MOVEMENT_INTERFACE_ID, new org.apache.thrift.meta_data.FieldMetaData("dataMovementInterfaceId", org.apache.thrift.TFieldRequirementType.REQUIRED, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING)));
      tmpMap.put(_Fields.SCP_DATA_MOVEMENT, new org.apache.thrift.meta_data.FieldMetaData("scpDataMovement", org.apache.thrift.TFieldRequirementType.REQUIRED, 
          new org.apache.thrift.meta_data.StructMetaData(org.apache.thrift.protocol.TType.STRUCT, org.apache.airavata.model.appcatalog.computeresource.SCPDataMovement.class)));
      metaDataMap = Collections.unmodifiableMap(tmpMap);
      org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(updateSCPDataMovementDetails_args.class, metaDataMap);
    }

    public updateSCPDataMovementDetails_args() {
    }

    public updateSCPDataMovementDetails_args(
      org.apache.airavata.model.security.AuthzToken authzToken,
      String dataMovementInterfaceId,
      org.apache.airavata.model.appcatalog.computeresource.SCPDataMovement scpDataMovement)
    {
      this();
      this.authzToken = authzToken;
      this.dataMovementInterfaceId = dataMovementInterfaceId;
      this.scpDataMovement = scpDataMovement;
    }

    /**
     * Performs a deep copy on <i>other</i>.
     */
    public updateSCPDataMovementDetails_args(updateSCPDataMovementDetails_args other) {
      if (other.isSetAuthzToken()) {
        this.authzToken = new org.apache.airavata.model.security.AuthzToken(other.authzToken);
      }
      if (other.isSetDataMovementInterfaceId()) {
        this.dataMovementInterfaceId = other.dataMovementInterfaceId;
      }
      if (other.isSetScpDataMovement()) {
        this.scpDataMovement = new org.apache.airavata.model.appcatalog.computeresource.SCPDataMovement(other.scpDataMovement);
      }
    }

    public updateSCPDataMovementDetails_args deepCopy() {
      return new updateSCPDataMovementDetails_args(this);
    }

    @Override
    public void clear() {
      this.authzToken = null;
      this.dataMovementInterfaceId = null;
      this.scpDataMovement = null;
    }

    public org.apache.airavata.model.security.AuthzToken getAuthzToken() {
      return this.authzToken;
    }

    public updateSCPDataMovementDetails_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 String getDataMovementInterfaceId() {
      return this.dataMovementInterfaceId;
    }

    public updateSCPDataMovementDetails_args setDataMovementInterfaceId(String dataMovementInterfaceId) {
      this.dataMovementInterfaceId = dataMovementInterfaceId;
      return this;
    }

    public void unsetDataMovementInterfaceId() {
      this.dataMovementInterfaceId = null;
    }

    /** Returns true if field dataMovementInterfaceId is set (has been assigned a value) and false otherwise */
    public boolean isSetDataMovementInterfaceId() {
      return this.dataMovementInterfaceId != null;
    }

    public void setDataMovementInterfaceIdIsSet(boolean value) {
      if (!value) {
        this.dataMovementInterfaceId = null;
      }
    }

    public org.apache.airavata.model.appcatalog.computeresource.SCPDataMovement getScpDataMovement() {
      return this.scpDataMovement;
    }

    public updateSCPDataMovementDetails_args setScpDataMovement(org.apache.airavata.model.appcatalog.computeresource.SCPDataMovement scpDataMovement) {
      this.scpDataMovement = scpDataMovement;
      return this;
    }

    public void unsetScpDataMovement() {
      this.scpDataMovement = null;
    }

    /** Returns true if field scpDataMovement is set (has been assigned a value) and false otherwise */
    public boolean isSetScpDataMovement() {
      return this.scpDataMovement != null;
    }

    public void setScpDataMovementIsSet(boolean value) {
      if (!value) {
        this.scpDataMovement = null;
      }
    }

    public void setFieldValue(_Fields field, Object value) {
      switch (field) {
      case AUTHZ_TOKEN:
        if (value == null) {
          unsetAuthzToken();
        } else {
          setAuthzToken((org.apache.airavata.model.security.AuthzToken)value);
        }
        break;

      case DATA_MOVEMENT_INTERFACE_ID:
        if (value == null) {
          unsetDataMovementInterfaceId();
        } else {
          setDataMovementInterfaceId((String)value);
        }
        break;

      case SCP_DATA_MOVEMENT:
        if (value == null) {
          unsetScpDataMovement();
        } else {
          setScpDataMovement((org.apache.airavata.model.appcatalog.computeresource.SCPDataMovement)value);
        }
        break;

      }
    }

    public Object getFieldValue(_Fields field) {
      switch (field) {
      case AUTHZ_TOKEN:
        return getAuthzToken();

      case DATA_MOVEMENT_INTERFACE_ID:
        return getDataMovementInterfaceId();

      case SCP_DATA_MOVEMENT:
        return getScpDataMovement();

      }
      throw new IllegalStateException();
    }

    /** Returns true if field corresponding to fieldID is set (has been assigned a value) and false otherwise */
    public boolean isSet(_Fields field) {
      if (field == null) {
        throw new IllegalArgumentException();
      }

      switch (field) {
      case AUTHZ_TOKEN:
        return isSetAuthzToken();
      case DATA_MOVEMENT_INTERFACE_ID:
        return isSetDataMovementInterfaceId();
      case SCP_DATA_MOVEMENT:
        return isSetScpDataMovement();
      }
      throw new IllegalStateException();
    }

    @Override
    public boolean equals(Object that) {
      if (that == null)
        return false;
      if (that instanceof updateSCPDataMovementDetails_args)
        return this.equals((updateSCPDataMovementDetails_args)that);
      return false;
    }

    public boolean equals(updateSCPDataMovementDetails_args that) {
      if (that == null)
        return false;

      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_dataMovementInterfaceId = true && this.isSetDataMovementInterfaceId();
      boolean that_present_dataMovementInterfaceId = true && that.isSetDataMovementInterfaceId();
      if (this_present_dataMovementInterfaceId || that_present_dataMovementInterfaceId) {
        if (!(this_present_dataMovementInterfaceId && that_present_dataMovementInterfaceId))
          return false;
        if (!this.dataMovementInterfaceId.equals(that.dataMovementInterfaceId))
          return false;
      }

      boolean this_present_scpDataMovement = true && this.isSetScpDataMovement();
      boolean that_present_scpDataMovement = true && that.isSetScpDataMovement();
      if (this_present_scpDataMovement || that_present_scpDataMovement) {
        if (!(this_present_scpDataMovement && that_present_scpDataMovement))
          return false;
        if (!this.scpDataMovement.equals(that.scpDataMovement))
          return false;
      }

      return true;
    }

    @Override
    public int hashCode() {
      List<Object> list = new ArrayList<Object>();

      boolean present_authzToken = true && (isSetAuthzToken());
      list.add(present_authzToken);
      if (present_authzToken)
        list.add(authzToken);

      boolean present_dataMovementInterfaceId = true && (isSetDataMovementInterfaceId());
      list.add(present_dataMovementInterfaceId);
      if (present_dataMovementInterfaceId)
        list.add(dataMovementInterfaceId);

      boolean present_scpDataMovement = true && (isSetScpDataMovement());
      list.add(present_scpDataMovement);
      if (present_scpDataMovement)
        list.add(scpDataMovement);

      return list.hashCode();
    }

    @Override
    public int compareTo(updateSCPDataMovementDetails_args other) {
      if (!getClass().equals(other.getClass())) {
        return getClass().getName().compareTo(other.getClass().getName());
      }

      int lastComparison = 0;

      lastComparison = 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 = Boolean.valueOf(isSetDataMovementInterfaceId()).compareTo(other.isSetDataMovementInterfaceId());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetDataMovementInterfaceId()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.dataMovementInterfaceId, other.dataMovementInterfaceId);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = Boolean.valueOf(isSetScpDataMovement()).compareTo(other.isSetScpDataMovement());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetScpDataMovement()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.scpDataMovement, other.scpDataMovement);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      return 0;
    }

    public _Fields fieldForId(int fieldId) {
      return _Fields.findByThriftId(fieldId);
    }

    public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
      schemes.get(iprot.getScheme()).getScheme().read(iprot, this);
    }

    public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException {
      schemes.get(oprot.getScheme()).getScheme().write(oprot, this);
    }

    @Override
    public String toString() {
      StringBuilder sb = new StringBuilder("updateSCPDataMovementDetails_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("dataMovementInterfaceId:");
      if (this.dataMovementInterfaceId == null) {
        sb.append("null");
      } else {
        sb.append(this.dataMovementInterfaceId);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("scpDataMovement:");
      if (this.scpDataMovement == null) {
        sb.append("null");
      } else {
        sb.append(this.scpDataMovement);
      }
      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 (dataMovementInterfaceId == null) {
        throw new org.apache.thrift.protocol.TProtocolException("Required field 'dataMovementInterfaceId' was not present! Struct: " + toString());
      }
      if (scpDataMovement == null) {
        throw new org.apache.thrift.protocol.TProtocolException("Required field 'scpDataMovement' was not present! Struct: " + toString());
      }
      // check for sub-struct validity
      if (authzToken != null) {
        authzToken.validate();
      }
      if (scpDataMovement != null) {
        scpDataMovement.validate();
      }
    }

    private void writeObject(java.io.ObjectOutputStream out) throws java.io.IOException {
      try {
        write(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(out)));
      } catch (org.apache.thrift.TException te) {
        throw new java.io.IOException(te);
      }
    }

    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, ClassNotFoundException {
      try {
        read(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(in)));
      } catch (org.apache.thrift.TException te) {
        throw new java.io.IOException(te);
      }
    }

    private static class updateSCPDataMovementDetails_argsStandardSchemeFactory implements SchemeFactory {
      public updateSCPDataMovementDetails_argsStandardScheme getScheme() {
        return new updateSCPDataMovementDetails_argsStandardScheme();
      }
    }

    private static class updateSCPDataMovementDetails_argsStandardScheme extends StandardScheme<updateSCPDataMovementDetails_args> {

      public void read(org.apache.thrift.protocol.TProtocol iprot, updateSCPDataMovementDetails_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: // DATA_MOVEMENT_INTERFACE_ID
              if (schemeField.type == org.apache.thrift.protocol.TType.STRING) {
                struct.dataMovementInterfaceId = iprot.readString();
                struct.setDataMovementInterfaceIdIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 3: // SCP_DATA_MOVEMENT
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.scpDataMovement = new org.apache.airavata.model.appcatalog.computeresource.SCPDataMovement();
                struct.scpDataMovement.read(iprot);
                struct.setScpDataMovementIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            default:
              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
          }
          iprot.readFieldEnd();
        }
        iprot.readStructEnd();

        // check for required fields of primitive type, which can't be checked in the validate method
        struct.validate();
      }

      public void write(org.apache.thrift.protocol.TProtocol oprot, updateSCPDataMovementDetails_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.dataMovementInterfaceId != null) {
          oprot.writeFieldBegin(DATA_MOVEMENT_INTERFACE_ID_FIELD_DESC);
          oprot.writeString(struct.dataMovementInterfaceId);
          oprot.writeFieldEnd();
        }
        if (struct.scpDataMovement != null) {
          oprot.writeFieldBegin(SCP_DATA_MOVEMENT_FIELD_DESC);
          struct.scpDataMovement.write(oprot);
          oprot.writeFieldEnd();
        }
        oprot.writeFieldStop();
        oprot.writeStructEnd();
      }

    }

    private static class updateSCPDataMovementDetails_argsTupleSchemeFactory implements SchemeFactory {
      public updateSCPDataMovementDetails_argsTupleScheme getScheme() {
        return new updateSCPDataMovementDetails_argsTupleScheme();
      }
    }

    private static class updateSCPDataMovementDetails_argsTupleScheme extends TupleScheme<updateSCPDataMovementDetails_args> {

      @Override
      public void write(org.apache.thrift.protocol.TProtocol prot, updateSCPDataMovementDetails_args struct) throws org.apache.thrift.TException {
        TTupleProtocol oprot = (TTupleProtocol) prot;
        struct.authzToken.write(oprot);
        oprot.writeString(struct.dataMovementInterfaceId);
        struct.scpDataMovement.write(oprot);
      }

      @Override
      public void read(org.apache.thrift.protocol.TProtocol prot, updateSCPDataMovementDetails_args struct) throws org.apache.thrift.TException {
        TTupleProtocol iprot = (TTupleProtocol) prot;
        struct.authzToken = new org.apache.airavata.model.security.AuthzToken();
        struct.authzToken.read(iprot);
        struct.setAuthzTokenIsSet(true);
        struct.dataMovementInterfaceId = iprot.readString();
        struct.setDataMovementInterfaceIdIsSet(true);
        struct.scpDataMovement = new org.apache.airavata.model.appcatalog.computeresource.SCPDataMovement();
        struct.scpDataMovement.read(iprot);
        struct.setScpDataMovementIsSet(true);
      }
    }

  }

  public static class updateSCPDataMovementDetails_result implements org.apache.thrift.TBase<updateSCPDataMovementDetails_result, updateSCPDataMovementDetails_result._Fields>, java.io.Serializable, Cloneable, Comparable<updateSCPDataMovementDetails_result>   {
    private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("updateSCPDataMovementDetails_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 IRE_FIELD_DESC = new org.apache.thrift.protocol.TField("ire", org.apache.thrift.protocol.TType.STRUCT, (short)1);
    private static final org.apache.thrift.protocol.TField ACE_FIELD_DESC = new org.apache.thrift.protocol.TField("ace", org.apache.thrift.protocol.TType.STRUCT, (short)2);
    private static final org.apache.thrift.protocol.TField ASE_FIELD_DESC = new org.apache.thrift.protocol.TField("ase", org.apache.thrift.protocol.TType.STRUCT, (short)3);
    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)4);

    private static final Map<Class<? extends IScheme>, SchemeFactory> schemes = new HashMap<Class<? extends IScheme>, SchemeFactory>();
    static {
      schemes.put(StandardScheme.class, new updateSCPDataMovementDetails_resultStandardSchemeFactory());
      schemes.put(TupleScheme.class, new updateSCPDataMovementDetails_resultTupleSchemeFactory());
    }

    public boolean success; // required
    public org.apache.airavata.model.error.InvalidRequestException ire; // required
    public org.apache.airavata.model.error.AiravataClientException ace; // required
    public org.apache.airavata.model.error.AiravataSystemException ase; // 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"),
      IRE((short)1, "ire"),
      ACE((short)2, "ace"),
      ASE((short)3, "ase"),
      AE((short)4, "ae");

      private static final Map<String, _Fields> byName = new HashMap<String, _Fields>();

      static {
        for (_Fields field : EnumSet.allOf(_Fields.class)) {
          byName.put(field.getFieldName(), field);
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, or null if its not found.
       */
      public static _Fields findByThriftId(int fieldId) {
        switch(fieldId) {
          case 0: // SUCCESS
            return SUCCESS;
          case 1: // IRE
            return IRE;
          case 2: // ACE
            return ACE;
          case 3: // ASE
            return ASE;
          case 4: // 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 IllegalArgumentException("Field " + fieldId + " doesn't exist!");
        return fields;
      }

      /**
       * Find the _Fields constant that matches name, or null if its not found.
       */
      public static _Fields findByName(String name) {
        return byName.get(name);
      }

      private final short _thriftId;
      private final String _fieldName;

      _Fields(short thriftId, String fieldName) {
        _thriftId = thriftId;
        _fieldName = fieldName;
      }

      public short getThriftFieldId() {
        return _thriftId;
      }

      public String getFieldName() {
        return _fieldName;
      }
    }

    // isset id assignments
    private static final int __SUCCESS_ISSET_ID = 0;
    private byte __isset_bitfield = 0;
    public static final Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
    static {
      Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new EnumMap<_Fields, org.apache.thrift.meta_data.FieldMetaData>(_Fields.class);
      tmpMap.put(_Fields.SUCCESS, new org.apache.thrift.meta_data.FieldMetaData("success", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.BOOL)));
      tmpMap.put(_Fields.IRE, new org.apache.thrift.meta_data.FieldMetaData("ire", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRUCT)));
      tmpMap.put(_Fields.ACE, new org.apache.thrift.meta_data.FieldMetaData("ace", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRUCT)));
      tmpMap.put(_Fields.ASE, new org.apache.thrift.meta_data.FieldMetaData("ase", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRUCT)));
      tmpMap.put(_Fields.AE, new org.apache.thrift.meta_data.FieldMetaData("ae", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRUCT)));
      metaDataMap = Collections.unmodifiableMap(tmpMap);
      org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(updateSCPDataMovementDetails_result.class, metaDataMap);
    }

    public updateSCPDataMovementDetails_result() {
    }

    public updateSCPDataMovementDetails_result(
      boolean success,
      org.apache.airavata.model.error.InvalidRequestException ire,
      org.apache.airavata.model.error.AiravataClientException ace,
      org.apache.airavata.model.error.AiravataSystemException ase,
      org.apache.airavata.model.error.AuthorizationException ae)
    {
      this();
      this.success = success;
      setSuccessIsSet(true);
      this.ire = ire;
      this.ace = ace;
      this.ase = ase;
      this.ae = ae;
    }

    /**
     * Performs a deep copy on <i>other</i>.
     */
    public updateSCPDataMovementDetails_result(updateSCPDataMovementDetails_result other) {
      __isset_bitfield = other.__isset_bitfield;
      this.success = other.success;
      if (other.isSetIre()) {
        this.ire = new org.apache.airavata.model.error.InvalidRequestException(other.ire);
      }
      if (other.isSetAce()) {
        this.ace = new org.apache.airavata.model.error.AiravataClientException(other.ace);
      }
      if (other.isSetAse()) {
        this.ase = new org.apache.airavata.model.error.AiravataSystemException(other.ase);
      }
      if (other.isSetAe()) {
        this.ae = new org.apache.airavata.model.error.AuthorizationException(other.ae);
      }
    }

    public updateSCPDataMovementDetails_result deepCopy() {
      return new updateSCPDataMovementDetails_result(this);
    }

    @Override
    public void clear() {
      setSuccessIsSet(false);
      this.success = false;
      this.ire = null;
      this.ace = null;
      this.ase = null;
      this.ae = null;
    }

    public boolean isSuccess() {
      return this.success;
    }

    public updateSCPDataMovementDetails_result setSuccess(boolean success) {
      this.success = success;
      setSuccessIsSet(true);
      return this;
    }

    public void unsetSuccess() {
      __isset_bitfield = EncodingUtils.clearBit(__isset_bitfield, __SUCCESS_ISSET_ID);
    }

    /** Returns true if field success is set (has been assigned a value) and false otherwise */
    public boolean isSetSuccess() {
      return EncodingUtils.testBit(__isset_bitfield, __SUCCESS_ISSET_ID);
    }

    public void setSuccessIsSet(boolean value) {
      __isset_bitfield = EncodingUtils.setBit(__isset_bitfield, __SUCCESS_ISSET_ID, value);
    }

    public org.apache.airavata.model.error.InvalidRequestException getIre() {
      return this.ire;
    }

    public updateSCPDataMovementDetails_result setIre(org.apache.airavata.model.error.InvalidRequestException ire) {
      this.ire = ire;
      return this;
    }

    public void unsetIre() {
      this.ire = null;
    }

    /** Returns true if field ire is set (has been assigned a value) and false otherwise */
    public boolean isSetIre() {
      return this.ire != null;
    }

    public void setIreIsSet(boolean value) {
      if (!value) {
        this.ire = null;
      }
    }

    public org.apache.airavata.model.error.AiravataClientException getAce() {
      return this.ace;
    }

    public updateSCPDataMovementDetails_result setAce(org.apache.airavata.model.error.AiravataClientException ace) {
      this.ace = ace;
      return this;
    }

    public void unsetAce() {
      this.ace = null;
    }

    /** Returns true if field ace is set (has been assigned a value) and false otherwise */
    public boolean isSetAce() {
      return this.ace != null;
    }

    public void setAceIsSet(boolean value) {
      if (!value) {
        this.ace = null;
      }
    }

    public org.apache.airavata.model.error.AiravataSystemException getAse() {
      return this.ase;
    }

    public updateSCPDataMovementDetails_result setAse(org.apache.airavata.model.error.AiravataSystemException ase) {
      this.ase = ase;
      return this;
    }

    public void unsetAse() {
      this.ase = null;
    }

    /** Returns true if field ase is set (has been assigned a value) and false otherwise */
    public boolean isSetAse() {
      return this.ase != null;
    }

    public void setAseIsSet(boolean value) {
      if (!value) {
        this.ase = null;
      }
    }

    public org.apache.airavata.model.error.AuthorizationException getAe() {
      return this.ae;
    }

    public updateSCPDataMovementDetails_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, Object value) {
      switch (field) {
      case SUCCESS:
        if (value == null) {
          unsetSuccess();
        } else {
          setSuccess((Boolean)value);
        }
        break;

      case IRE:
        if (value == null) {
          unsetIre();
        } else {
          setIre((org.apache.airavata.model.error.InvalidRequestException)value);
        }
        break;

      case ACE:
        if (value == null) {
          unsetAce();
        } else {
          setAce((org.apache.airavata.model.error.AiravataClientException)value);
        }
        break;

      case ASE:
        if (value == null) {
          unsetAse();
        } else {
          setAse((org.apache.airavata.model.error.AiravataSystemException)value);
        }
        break;

      case AE:
        if (value == null) {
          unsetAe();
        } else {
          setAe((org.apache.airavata.model.error.AuthorizationException)value);
        }
        break;

      }
    }

    public Object getFieldValue(_Fields field) {
      switch (field) {
      case SUCCESS:
        return Boolean.valueOf(isSuccess());

      case IRE:
        return getIre();

      case ACE:
        return getAce();

      case ASE:
        return getAse();

      case AE:
        return getAe();

      }
      throw new IllegalStateException();
    }

    /** Returns true if field corresponding to fieldID is set (has been assigned a value) and false otherwise */
    public boolean isSet(_Fields field) {
      if (field == null) {
        throw new IllegalArgumentException();
      }

      switch (field) {
      case SUCCESS:
        return isSetSuccess();
      case IRE:
        return isSetIre();
      case ACE:
        return isSetAce();
      case ASE:
        return isSetAse();
      case AE:
        return isSetAe();
      }
      throw new IllegalStateException();
    }

    @Override
    public boolean equals(Object that) {
      if (that == null)
        return false;
      if (that instanceof updateSCPDataMovementDetails_result)
        return this.equals((updateSCPDataMovementDetails_result)that);
      return false;
    }

    public boolean equals(updateSCPDataMovementDetails_result that) {
      if (that == null)
        return false;

      boolean this_present_success = true;
      boolean that_present_success = true;
      if (this_present_success || that_present_success) {
        if (!(this_present_success && that_present_success))
          return false;
        if (this.success != that.success)
          return false;
      }

      boolean this_present_ire = true && this.isSetIre();
      boolean that_present_ire = true && that.isSetIre();
      if (this_present_ire || that_present_ire) {
        if (!(this_present_ire && that_present_ire))
          return false;
        if (!this.ire.equals(that.ire))
          return false;
      }

      boolean this_present_ace = true && this.isSetAce();
      boolean that_present_ace = true && that.isSetAce();
      if (this_present_ace || that_present_ace) {
        if (!(this_present_ace && that_present_ace))
          return false;
        if (!this.ace.equals(that.ace))
          return false;
      }

      boolean this_present_ase = true && this.isSetAse();
      boolean that_present_ase = true && that.isSetAse();
      if (this_present_ase || that_present_ase) {
        if (!(this_present_ase && that_present_ase))
          return false;
        if (!this.ase.equals(that.ase))
          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() {
      List<Object> list = new ArrayList<Object>();

      boolean present_success = true;
      list.add(present_success);
      if (present_success)
        list.add(success);

      boolean present_ire = true && (isSetIre());
      list.add(present_ire);
      if (present_ire)
        list.add(ire);

      boolean present_ace = true && (isSetAce());
      list.add(present_ace);
      if (present_ace)
        list.add(ace);

      boolean present_ase = true && (isSetAse());
      list.add(present_ase);
      if (present_ase)
        list.add(ase);

      boolean present_ae = true && (isSetAe());
      list.add(present_ae);
      if (present_ae)
        list.add(ae);

      return list.hashCode();
    }

    @Override
    public int compareTo(updateSCPDataMovementDetails_result other) {
      if (!getClass().equals(other.getClass())) {
        return getClass().getName().compareTo(other.getClass().getName());
      }

      int lastComparison = 0;

      lastComparison = Boolean.valueOf(isSetSuccess()).compareTo(other.isSetSuccess());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetSuccess()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.success, other.success);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = Boolean.valueOf(isSetIre()).compareTo(other.isSetIre());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetIre()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.ire, other.ire);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = Boolean.valueOf(isSetAce()).compareTo(other.isSetAce());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetAce()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.ace, other.ace);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = Boolean.valueOf(isSetAse()).compareTo(other.isSetAse());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetAse()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.ase, other.ase);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = 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 {
      schemes.get(iprot.getScheme()).getScheme().read(iprot, this);
    }

    public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException {
      schemes.get(oprot.getScheme()).getScheme().write(oprot, this);
      }

    @Override
    public String toString() {
      StringBuilder sb = new StringBuilder("updateSCPDataMovementDetails_result(");
      boolean first = true;

      sb.append("success:");
      sb.append(this.success);
      first = false;
      if (!first) sb.append(", ");
      sb.append("ire:");
      if (this.ire == null) {
        sb.append("null");
      } else {
        sb.append(this.ire);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("ace:");
      if (this.ace == null) {
        sb.append("null");
      } else {
        sb.append(this.ace);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("ase:");
      if (this.ase == null) {
        sb.append("null");
      } else {
        sb.append(this.ase);
      }
      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, 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 updateSCPDataMovementDetails_resultStandardSchemeFactory implements SchemeFactory {
      public updateSCPDataMovementDetails_resultStandardScheme getScheme() {
        return new updateSCPDataMovementDetails_resultStandardScheme();
      }
    }

    private static class updateSCPDataMovementDetails_resultStandardScheme extends StandardScheme<updateSCPDataMovementDetails_result> {

      public void read(org.apache.thrift.protocol.TProtocol iprot, updateSCPDataMovementDetails_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: // IRE
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.ire = new org.apache.airavata.model.error.InvalidRequestException();
                struct.ire.read(iprot);
                struct.setIreIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 2: // ACE
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.ace = new org.apache.airavata.model.error.AiravataClientException();
                struct.ace.read(iprot);
                struct.setAceIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 3: // ASE
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.ase = new org.apache.airavata.model.error.AiravataSystemException();
                struct.ase.read(iprot);
                struct.setAseIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 4: // 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, updateSCPDataMovementDetails_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.ire != null) {
          oprot.writeFieldBegin(IRE_FIELD_DESC);
          struct.ire.write(oprot);
          oprot.writeFieldEnd();
        }
        if (struct.ace != null) {
          oprot.writeFieldBegin(ACE_FIELD_DESC);
          struct.ace.write(oprot);
          oprot.writeFieldEnd();
        }
        if (struct.ase != null) {
          oprot.writeFieldBegin(ASE_FIELD_DESC);
          struct.ase.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 updateSCPDataMovementDetails_resultTupleSchemeFactory implements SchemeFactory {
      public updateSCPDataMovementDetails_resultTupleScheme getScheme() {
        return new updateSCPDataMovementDetails_resultTupleScheme();
      }
    }

    private static class updateSCPDataMovementDetails_resultTupleScheme extends TupleScheme<updateSCPDataMovementDetails_result> {

      @Override
      public void write(org.apache.thrift.protocol.TProtocol prot, updateSCPDataMovementDetails_result struct) throws org.apache.thrift.TException {
        TTupleProtocol oprot = (TTupleProtocol) prot;
        BitSet optionals = new BitSet();
        if (struct.isSetSuccess()) {
          optionals.set(0);
        }
        if (struct.isSetIre()) {
          optionals.set(1);
        }
        if (struct.isSetAce()) {
          optionals.set(2);
        }
        if (struct.isSetAse()) {
          optionals.set(3);
        }
        if (struct.isSetAe()) {
          optionals.set(4);
        }
        oprot.writeBitSet(optionals, 5);
        if (struct.isSetSuccess()) {
          oprot.writeBool(struct.success);
        }
        if (struct.isSetIre()) {
          struct.ire.write(oprot);
        }
        if (struct.isSetAce()) {
          struct.ace.write(oprot);
        }
        if (struct.isSetAse()) {
          struct.ase.write(oprot);
        }
        if (struct.isSetAe()) {
          struct.ae.write(oprot);
        }
      }

      @Override
      public void read(org.apache.thrift.protocol.TProtocol prot, updateSCPDataMovementDetails_result struct) throws org.apache.thrift.TException {
        TTupleProtocol iprot = (TTupleProtocol) prot;
        BitSet incoming = iprot.readBitSet(5);
        if (incoming.get(0)) {
          struct.success = iprot.readBool();
          struct.setSuccessIsSet(true);
        }
        if (incoming.get(1)) {
          struct.ire = new org.apache.airavata.model.error.InvalidRequestException();
          struct.ire.read(iprot);
          struct.setIreIsSet(true);
        }
        if (incoming.get(2)) {
          struct.ace = new org.apache.airavata.model.error.AiravataClientException();
          struct.ace.read(iprot);
          struct.setAceIsSet(true);
        }
        if (incoming.get(3)) {
          struct.ase = new org.apache.airavata.model.error.AiravataSystemException();
          struct.ase.read(iprot);
          struct.setAseIsSet(true);
        }
        if (incoming.get(4)) {
          struct.ae = new org.apache.airavata.model.error.AuthorizationException();
          struct.ae.read(iprot);
          struct.setAeIsSet(true);
        }
      }
    }

  }

  public static class getSCPDataMovement_args implements org.apache.thrift.TBase<getSCPDataMovement_args, getSCPDataMovement_args._Fields>, java.io.Serializable, Cloneable, Comparable<getSCPDataMovement_args>   {
    private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("getSCPDataMovement_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 DATA_MOVEMENT_ID_FIELD_DESC = new org.apache.thrift.protocol.TField("dataMovementId", org.apache.thrift.protocol.TType.STRING, (short)2);

    private static final Map<Class<? extends IScheme>, SchemeFactory> schemes = new HashMap<Class<? extends IScheme>, SchemeFactory>();
    static {
      schemes.put(StandardScheme.class, new getSCPDataMovement_argsStandardSchemeFactory());
      schemes.put(TupleScheme.class, new getSCPDataMovement_argsTupleSchemeFactory());
    }

    public org.apache.airavata.model.security.AuthzToken authzToken; // required
    public String dataMovementId; // required

    /** 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"),
      DATA_MOVEMENT_ID((short)2, "dataMovementId");

      private static final Map<String, _Fields> byName = new HashMap<String, _Fields>();

      static {
        for (_Fields field : EnumSet.allOf(_Fields.class)) {
          byName.put(field.getFieldName(), field);
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, or null if its not found.
       */
      public static _Fields findByThriftId(int fieldId) {
        switch(fieldId) {
          case 1: // AUTHZ_TOKEN
            return AUTHZ_TOKEN;
          case 2: // DATA_MOVEMENT_ID
            return DATA_MOVEMENT_ID;
          default:
            return null;
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, throwing an exception
       * if it is not found.
       */
      public static _Fields findByThriftIdOrThrow(int fieldId) {
        _Fields fields = findByThriftId(fieldId);
        if (fields == null) throw new IllegalArgumentException("Field " + fieldId + " doesn't exist!");
        return fields;
      }

      /**
       * Find the _Fields constant that matches name, or null if its not found.
       */
      public static _Fields findByName(String name) {
        return byName.get(name);
      }

      private final short _thriftId;
      private final String _fieldName;

      _Fields(short thriftId, String fieldName) {
        _thriftId = thriftId;
        _fieldName = fieldName;
      }

      public short getThriftFieldId() {
        return _thriftId;
      }

      public String getFieldName() {
        return _fieldName;
      }
    }

    // isset id assignments
    public static final Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
    static {
      Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new EnumMap<_Fields, org.apache.thrift.meta_data.FieldMetaData>(_Fields.class);
      tmpMap.put(_Fields.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.DATA_MOVEMENT_ID, new org.apache.thrift.meta_data.FieldMetaData("dataMovementId", org.apache.thrift.TFieldRequirementType.REQUIRED, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING)));
      metaDataMap = Collections.unmodifiableMap(tmpMap);
      org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(getSCPDataMovement_args.class, metaDataMap);
    }

    public getSCPDataMovement_args() {
    }

    public getSCPDataMovement_args(
      org.apache.airavata.model.security.AuthzToken authzToken,
      String dataMovementId)
    {
      this();
      this.authzToken = authzToken;
      this.dataMovementId = dataMovementId;
    }

    /**
     * Performs a deep copy on <i>other</i>.
     */
    public getSCPDataMovement_args(getSCPDataMovement_args other) {
      if (other.isSetAuthzToken()) {
        this.authzToken = new org.apache.airavata.model.security.AuthzToken(other.authzToken);
      }
      if (other.isSetDataMovementId()) {
        this.dataMovementId = other.dataMovementId;
      }
    }

    public getSCPDataMovement_args deepCopy() {
      return new getSCPDataMovement_args(this);
    }

    @Override
    public void clear() {
      this.authzToken = null;
      this.dataMovementId = null;
    }

    public org.apache.airavata.model.security.AuthzToken getAuthzToken() {
      return this.authzToken;
    }

    public getSCPDataMovement_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 String getDataMovementId() {
      return this.dataMovementId;
    }

    public getSCPDataMovement_args setDataMovementId(String dataMovementId) {
      this.dataMovementId = dataMovementId;
      return this;
    }

    public void unsetDataMovementId() {
      this.dataMovementId = null;
    }

    /** Returns true if field dataMovementId is set (has been assigned a value) and false otherwise */
    public boolean isSetDataMovementId() {
      return this.dataMovementId != null;
    }

    public void setDataMovementIdIsSet(boolean value) {
      if (!value) {
        this.dataMovementId = null;
      }
    }

    public void setFieldValue(_Fields field, Object value) {
      switch (field) {
      case AUTHZ_TOKEN:
        if (value == null) {
          unsetAuthzToken();
        } else {
          setAuthzToken((org.apache.airavata.model.security.AuthzToken)value);
        }
        break;

      case DATA_MOVEMENT_ID:
        if (value == null) {
          unsetDataMovementId();
        } else {
          setDataMovementId((String)value);
        }
        break;

      }
    }

    public Object getFieldValue(_Fields field) {
      switch (field) {
      case AUTHZ_TOKEN:
        return getAuthzToken();

      case DATA_MOVEMENT_ID:
        return getDataMovementId();

      }
      throw new IllegalStateException();
    }

    /** Returns true if field corresponding to fieldID is set (has been assigned a value) and false otherwise */
    public boolean isSet(_Fields field) {
      if (field == null) {
        throw new IllegalArgumentException();
      }

      switch (field) {
      case AUTHZ_TOKEN:
        return isSetAuthzToken();
      case DATA_MOVEMENT_ID:
        return isSetDataMovementId();
      }
      throw new IllegalStateException();
    }

    @Override
    public boolean equals(Object that) {
      if (that == null)
        return false;
      if (that instanceof getSCPDataMovement_args)
        return this.equals((getSCPDataMovement_args)that);
      return false;
    }

    public boolean equals(getSCPDataMovement_args that) {
      if (that == null)
        return false;

      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_dataMovementId = true && this.isSetDataMovementId();
      boolean that_present_dataMovementId = true && that.isSetDataMovementId();
      if (this_present_dataMovementId || that_present_dataMovementId) {
        if (!(this_present_dataMovementId && that_present_dataMovementId))
          return false;
        if (!this.dataMovementId.equals(that.dataMovementId))
          return false;
      }

      return true;
    }

    @Override
    public int hashCode() {
      List<Object> list = new ArrayList<Object>();

      boolean present_authzToken = true && (isSetAuthzToken());
      list.add(present_authzToken);
      if (present_authzToken)
        list.add(authzToken);

      boolean present_dataMovementId = true && (isSetDataMovementId());
      list.add(present_dataMovementId);
      if (present_dataMovementId)
        list.add(dataMovementId);

      return list.hashCode();
    }

    @Override
    public int compareTo(getSCPDataMovement_args other) {
      if (!getClass().equals(other.getClass())) {
        return getClass().getName().compareTo(other.getClass().getName());
      }

      int lastComparison = 0;

      lastComparison = 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 = Boolean.valueOf(isSetDataMovementId()).compareTo(other.isSetDataMovementId());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetDataMovementId()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.dataMovementId, other.dataMovementId);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      return 0;
    }

    public _Fields fieldForId(int fieldId) {
      return _Fields.findByThriftId(fieldId);
    }

    public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
      schemes.get(iprot.getScheme()).getScheme().read(iprot, this);
    }

    public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException {
      schemes.get(oprot.getScheme()).getScheme().write(oprot, this);
    }

    @Override
    public String toString() {
      StringBuilder sb = new StringBuilder("getSCPDataMovement_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("dataMovementId:");
      if (this.dataMovementId == null) {
        sb.append("null");
      } else {
        sb.append(this.dataMovementId);
      }
      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 (dataMovementId == null) {
        throw new org.apache.thrift.protocol.TProtocolException("Required field 'dataMovementId' 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, 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 getSCPDataMovement_argsStandardSchemeFactory implements SchemeFactory {
      public getSCPDataMovement_argsStandardScheme getScheme() {
        return new getSCPDataMovement_argsStandardScheme();
      }
    }

    private static class getSCPDataMovement_argsStandardScheme extends StandardScheme<getSCPDataMovement_args> {

      public void read(org.apache.thrift.protocol.TProtocol iprot, getSCPDataMovement_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: // DATA_MOVEMENT_ID
              if (schemeField.type == org.apache.thrift.protocol.TType.STRING) {
                struct.dataMovementId = iprot.readString();
                struct.setDataMovementIdIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            default:
              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
          }
          iprot.readFieldEnd();
        }
        iprot.readStructEnd();

        // check for required fields of primitive type, which can't be checked in the validate method
        struct.validate();
      }

      public void write(org.apache.thrift.protocol.TProtocol oprot, getSCPDataMovement_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.dataMovementId != null) {
          oprot.writeFieldBegin(DATA_MOVEMENT_ID_FIELD_DESC);
          oprot.writeString(struct.dataMovementId);
          oprot.writeFieldEnd();
        }
        oprot.writeFieldStop();
        oprot.writeStructEnd();
      }

    }

    private static class getSCPDataMovement_argsTupleSchemeFactory implements SchemeFactory {
      public getSCPDataMovement_argsTupleScheme getScheme() {
        return new getSCPDataMovement_argsTupleScheme();
      }
    }

    private static class getSCPDataMovement_argsTupleScheme extends TupleScheme<getSCPDataMovement_args> {

      @Override
      public void write(org.apache.thrift.protocol.TProtocol prot, getSCPDataMovement_args struct) throws org.apache.thrift.TException {
        TTupleProtocol oprot = (TTupleProtocol) prot;
        struct.authzToken.write(oprot);
        oprot.writeString(struct.dataMovementId);
      }

      @Override
      public void read(org.apache.thrift.protocol.TProtocol prot, getSCPDataMovement_args struct) throws org.apache.thrift.TException {
        TTupleProtocol iprot = (TTupleProtocol) prot;
        struct.authzToken = new org.apache.airavata.model.security.AuthzToken();
        struct.authzToken.read(iprot);
        struct.setAuthzTokenIsSet(true);
        struct.dataMovementId = iprot.readString();
        struct.setDataMovementIdIsSet(true);
      }
    }

  }

  public static class getSCPDataMovement_result implements org.apache.thrift.TBase<getSCPDataMovement_result, getSCPDataMovement_result._Fields>, java.io.Serializable, Cloneable, Comparable<getSCPDataMovement_result>   {
    private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("getSCPDataMovement_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 IRE_FIELD_DESC = new org.apache.thrift.protocol.TField("ire", org.apache.thrift.protocol.TType.STRUCT, (short)1);
    private static final org.apache.thrift.protocol.TField ACE_FIELD_DESC = new org.apache.thrift.protocol.TField("ace", org.apache.thrift.protocol.TType.STRUCT, (short)2);
    private static final org.apache.thrift.protocol.TField ASE_FIELD_DESC = new org.apache.thrift.protocol.TField("ase", org.apache.thrift.protocol.TType.STRUCT, (short)3);
    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)4);

    private static final Map<Class<? extends IScheme>, SchemeFactory> schemes = new HashMap<Class<? extends IScheme>, SchemeFactory>();
    static {
      schemes.put(StandardScheme.class, new getSCPDataMovement_resultStandardSchemeFactory());
      schemes.put(TupleScheme.class, new getSCPDataMovement_resultTupleSchemeFactory());
    }

    public org.apache.airavata.model.appcatalog.computeresource.SCPDataMovement success; // required
    public org.apache.airavata.model.error.InvalidRequestException ire; // required
    public org.apache.airavata.model.error.AiravataClientException ace; // required
    public org.apache.airavata.model.error.AiravataSystemException ase; // 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"),
      IRE((short)1, "ire"),
      ACE((short)2, "ace"),
      ASE((short)3, "ase"),
      AE((short)4, "ae");

      private static final Map<String, _Fields> byName = new HashMap<String, _Fields>();

      static {
        for (_Fields field : EnumSet.allOf(_Fields.class)) {
          byName.put(field.getFieldName(), field);
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, or null if its not found.
       */
      public static _Fields findByThriftId(int fieldId) {
        switch(fieldId) {
          case 0: // SUCCESS
            return SUCCESS;
          case 1: // IRE
            return IRE;
          case 2: // ACE
            return ACE;
          case 3: // ASE
            return ASE;
          case 4: // 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 IllegalArgumentException("Field " + fieldId + " doesn't exist!");
        return fields;
      }

      /**
       * Find the _Fields constant that matches name, or null if its not found.
       */
      public static _Fields findByName(String name) {
        return byName.get(name);
      }

      private final short _thriftId;
      private final String _fieldName;

      _Fields(short thriftId, String fieldName) {
        _thriftId = thriftId;
        _fieldName = fieldName;
      }

      public short getThriftFieldId() {
        return _thriftId;
      }

      public String getFieldName() {
        return _fieldName;
      }
    }

    // isset id assignments
    public static final Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
    static {
      Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new EnumMap<_Fields, org.apache.thrift.meta_data.FieldMetaData>(_Fields.class);
      tmpMap.put(_Fields.SUCCESS, new org.apache.thrift.meta_data.FieldMetaData("success", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.StructMetaData(org.apache.thrift.protocol.TType.STRUCT, org.apache.airavata.model.appcatalog.computeresource.SCPDataMovement.class)));
      tmpMap.put(_Fields.IRE, new org.apache.thrift.meta_data.FieldMetaData("ire", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRUCT)));
      tmpMap.put(_Fields.ACE, new org.apache.thrift.meta_data.FieldMetaData("ace", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRUCT)));
      tmpMap.put(_Fields.ASE, new org.apache.thrift.meta_data.FieldMetaData("ase", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRUCT)));
      tmpMap.put(_Fields.AE, new org.apache.thrift.meta_data.FieldMetaData("ae", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRUCT)));
      metaDataMap = Collections.unmodifiableMap(tmpMap);
      org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(getSCPDataMovement_result.class, metaDataMap);
    }

    public getSCPDataMovement_result() {
    }

    public getSCPDataMovement_result(
      org.apache.airavata.model.appcatalog.computeresource.SCPDataMovement success,
      org.apache.airavata.model.error.InvalidRequestException ire,
      org.apache.airavata.model.error.AiravataClientException ace,
      org.apache.airavata.model.error.AiravataSystemException ase,
      org.apache.airavata.model.error.AuthorizationException ae)
    {
      this();
      this.success = success;
      this.ire = ire;
      this.ace = ace;
      this.ase = ase;
      this.ae = ae;
    }

    /**
     * Performs a deep copy on <i>other</i>.
     */
    public getSCPDataMovement_result(getSCPDataMovement_result other) {
      if (other.isSetSuccess()) {
        this.success = new org.apache.airavata.model.appcatalog.computeresource.SCPDataMovement(other.success);
      }
      if (other.isSetIre()) {
        this.ire = new org.apache.airavata.model.error.InvalidRequestException(other.ire);
      }
      if (other.isSetAce()) {
        this.ace = new org.apache.airavata.model.error.AiravataClientException(other.ace);
      }
      if (other.isSetAse()) {
        this.ase = new org.apache.airavata.model.error.AiravataSystemException(other.ase);
      }
      if (other.isSetAe()) {
        this.ae = new org.apache.airavata.model.error.AuthorizationException(other.ae);
      }
    }

    public getSCPDataMovement_result deepCopy() {
      return new getSCPDataMovement_result(this);
    }

    @Override
    public void clear() {
      this.success = null;
      this.ire = null;
      this.ace = null;
      this.ase = null;
      this.ae = null;
    }

    public org.apache.airavata.model.appcatalog.computeresource.SCPDataMovement getSuccess() {
      return this.success;
    }

    public getSCPDataMovement_result setSuccess(org.apache.airavata.model.appcatalog.computeresource.SCPDataMovement 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.model.error.InvalidRequestException getIre() {
      return this.ire;
    }

    public getSCPDataMovement_result setIre(org.apache.airavata.model.error.InvalidRequestException ire) {
      this.ire = ire;
      return this;
    }

    public void unsetIre() {
      this.ire = null;
    }

    /** Returns true if field ire is set (has been assigned a value) and false otherwise */
    public boolean isSetIre() {
      return this.ire != null;
    }

    public void setIreIsSet(boolean value) {
      if (!value) {
        this.ire = null;
      }
    }

    public org.apache.airavata.model.error.AiravataClientException getAce() {
      return this.ace;
    }

    public getSCPDataMovement_result setAce(org.apache.airavata.model.error.AiravataClientException ace) {
      this.ace = ace;
      return this;
    }

    public void unsetAce() {
      this.ace = null;
    }

    /** Returns true if field ace is set (has been assigned a value) and false otherwise */
    public boolean isSetAce() {
      return this.ace != null;
    }

    public void setAceIsSet(boolean value) {
      if (!value) {
        this.ace = null;
      }
    }

    public org.apache.airavata.model.error.AiravataSystemException getAse() {
      return this.ase;
    }

    public getSCPDataMovement_result setAse(org.apache.airavata.model.error.AiravataSystemException ase) {
      this.ase = ase;
      return this;
    }

    public void unsetAse() {
      this.ase = null;
    }

    /** Returns true if field ase is set (has been assigned a value) and false otherwise */
    public boolean isSetAse() {
      return this.ase != null;
    }

    public void setAseIsSet(boolean value) {
      if (!value) {
        this.ase = null;
      }
    }

    public org.apache.airavata.model.error.AuthorizationException getAe() {
      return this.ae;
    }

    public getSCPDataMovement_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, Object value) {
      switch (field) {
      case SUCCESS:
        if (value == null) {
          unsetSuccess();
        } else {
          setSuccess((org.apache.airavata.model.appcatalog.computeresource.SCPDataMovement)value);
        }
        break;

      case IRE:
        if (value == null) {
          unsetIre();
        } else {
          setIre((org.apache.airavata.model.error.InvalidRequestException)value);
        }
        break;

      case ACE:
        if (value == null) {
          unsetAce();
        } else {
          setAce((org.apache.airavata.model.error.AiravataClientException)value);
        }
        break;

      case ASE:
        if (value == null) {
          unsetAse();
        } else {
          setAse((org.apache.airavata.model.error.AiravataSystemException)value);
        }
        break;

      case AE:
        if (value == null) {
          unsetAe();
        } else {
          setAe((org.apache.airavata.model.error.AuthorizationException)value);
        }
        break;

      }
    }

    public Object getFieldValue(_Fields field) {
      switch (field) {
      case SUCCESS:
        return getSuccess();

      case IRE:
        return getIre();

      case ACE:
        return getAce();

      case ASE:
        return getAse();

      case AE:
        return getAe();

      }
      throw new IllegalStateException();
    }

    /** Returns true if field corresponding to fieldID is set (has been assigned a value) and false otherwise */
    public boolean isSet(_Fields field) {
      if (field == null) {
        throw new IllegalArgumentException();
      }

      switch (field) {
      case SUCCESS:
        return isSetSuccess();
      case IRE:
        return isSetIre();
      case ACE:
        return isSetAce();
      case ASE:
        return isSetAse();
      case AE:
        return isSetAe();
      }
      throw new IllegalStateException();
    }

    @Override
    public boolean equals(Object that) {
      if (that == null)
        return false;
      if (that instanceof getSCPDataMovement_result)
        return this.equals((getSCPDataMovement_result)that);
      return false;
    }

    public boolean equals(getSCPDataMovement_result that) {
      if (that == null)
        return false;

      boolean this_present_success = true && this.isSetSuccess();
      boolean that_present_success = true && that.isSetSuccess();
      if (this_present_success || that_present_success) {
        if (!(this_present_success && that_present_success))
          return false;
        if (!this.success.equals(that.success))
          return false;
      }

      boolean this_present_ire = true && this.isSetIre();
      boolean that_present_ire = true && that.isSetIre();
      if (this_present_ire || that_present_ire) {
        if (!(this_present_ire && that_present_ire))
          return false;
        if (!this.ire.equals(that.ire))
          return false;
      }

      boolean this_present_ace = true && this.isSetAce();
      boolean that_present_ace = true && that.isSetAce();
      if (this_present_ace || that_present_ace) {
        if (!(this_present_ace && that_present_ace))
          return false;
        if (!this.ace.equals(that.ace))
          return false;
      }

      boolean this_present_ase = true && this.isSetAse();
      boolean that_present_ase = true && that.isSetAse();
      if (this_present_ase || that_present_ase) {
        if (!(this_present_ase && that_present_ase))
          return false;
        if (!this.ase.equals(that.ase))
          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() {
      List<Object> list = new ArrayList<Object>();

      boolean present_success = true && (isSetSuccess());
      list.add(present_success);
      if (present_success)
        list.add(success);

      boolean present_ire = true && (isSetIre());
      list.add(present_ire);
      if (present_ire)
        list.add(ire);

      boolean present_ace = true && (isSetAce());
      list.add(present_ace);
      if (present_ace)
        list.add(ace);

      boolean present_ase = true && (isSetAse());
      list.add(present_ase);
      if (present_ase)
        list.add(ase);

      boolean present_ae = true && (isSetAe());
      list.add(present_ae);
      if (present_ae)
        list.add(ae);

      return list.hashCode();
    }

    @Override
    public int compareTo(getSCPDataMovement_result other) {
      if (!getClass().equals(other.getClass())) {
        return getClass().getName().compareTo(other.getClass().getName());
      }

      int lastComparison = 0;

      lastComparison = Boolean.valueOf(isSetSuccess()).compareTo(other.isSetSuccess());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetSuccess()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.success, other.success);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = Boolean.valueOf(isSetIre()).compareTo(other.isSetIre());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetIre()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.ire, other.ire);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = Boolean.valueOf(isSetAce()).compareTo(other.isSetAce());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetAce()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.ace, other.ace);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = Boolean.valueOf(isSetAse()).compareTo(other.isSetAse());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetAse()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.ase, other.ase);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = 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 {
      schemes.get(iprot.getScheme()).getScheme().read(iprot, this);
    }

    public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException {
      schemes.get(oprot.getScheme()).getScheme().write(oprot, this);
      }

    @Override
    public String toString() {
      StringBuilder sb = new StringBuilder("getSCPDataMovement_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("ire:");
      if (this.ire == null) {
        sb.append("null");
      } else {
        sb.append(this.ire);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("ace:");
      if (this.ace == null) {
        sb.append("null");
      } else {
        sb.append(this.ace);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("ase:");
      if (this.ase == null) {
        sb.append("null");
      } else {
        sb.append(this.ase);
      }
      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, 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 getSCPDataMovement_resultStandardSchemeFactory implements SchemeFactory {
      public getSCPDataMovement_resultStandardScheme getScheme() {
        return new getSCPDataMovement_resultStandardScheme();
      }
    }

    private static class getSCPDataMovement_resultStandardScheme extends StandardScheme<getSCPDataMovement_result> {

      public void read(org.apache.thrift.protocol.TProtocol iprot, getSCPDataMovement_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.appcatalog.computeresource.SCPDataMovement();
                struct.success.read(iprot);
                struct.setSuccessIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 1: // IRE
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.ire = new org.apache.airavata.model.error.InvalidRequestException();
                struct.ire.read(iprot);
                struct.setIreIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 2: // ACE
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.ace = new org.apache.airavata.model.error.AiravataClientException();
                struct.ace.read(iprot);
                struct.setAceIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 3: // ASE
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.ase = new org.apache.airavata.model.error.AiravataSystemException();
                struct.ase.read(iprot);
                struct.setAseIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 4: // 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, getSCPDataMovement_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.ire != null) {
          oprot.writeFieldBegin(IRE_FIELD_DESC);
          struct.ire.write(oprot);
          oprot.writeFieldEnd();
        }
        if (struct.ace != null) {
          oprot.writeFieldBegin(ACE_FIELD_DESC);
          struct.ace.write(oprot);
          oprot.writeFieldEnd();
        }
        if (struct.ase != null) {
          oprot.writeFieldBegin(ASE_FIELD_DESC);
          struct.ase.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 getSCPDataMovement_resultTupleSchemeFactory implements SchemeFactory {
      public getSCPDataMovement_resultTupleScheme getScheme() {
        return new getSCPDataMovement_resultTupleScheme();
      }
    }

    private static class getSCPDataMovement_resultTupleScheme extends TupleScheme<getSCPDataMovement_result> {

      @Override
      public void write(org.apache.thrift.protocol.TProtocol prot, getSCPDataMovement_result struct) throws org.apache.thrift.TException {
        TTupleProtocol oprot = (TTupleProtocol) prot;
        BitSet optionals = new BitSet();
        if (struct.isSetSuccess()) {
          optionals.set(0);
        }
        if (struct.isSetIre()) {
          optionals.set(1);
        }
        if (struct.isSetAce()) {
          optionals.set(2);
        }
        if (struct.isSetAse()) {
          optionals.set(3);
        }
        if (struct.isSetAe()) {
          optionals.set(4);
        }
        oprot.writeBitSet(optionals, 5);
        if (struct.isSetSuccess()) {
          struct.success.write(oprot);
        }
        if (struct.isSetIre()) {
          struct.ire.write(oprot);
        }
        if (struct.isSetAce()) {
          struct.ace.write(oprot);
        }
        if (struct.isSetAse()) {
          struct.ase.write(oprot);
        }
        if (struct.isSetAe()) {
          struct.ae.write(oprot);
        }
      }

      @Override
      public void read(org.apache.thrift.protocol.TProtocol prot, getSCPDataMovement_result struct) throws org.apache.thrift.TException {
        TTupleProtocol iprot = (TTupleProtocol) prot;
        BitSet incoming = iprot.readBitSet(5);
        if (incoming.get(0)) {
          struct.success = new org.apache.airavata.model.appcatalog.computeresource.SCPDataMovement();
          struct.success.read(iprot);
          struct.setSuccessIsSet(true);
        }
        if (incoming.get(1)) {
          struct.ire = new org.apache.airavata.model.error.InvalidRequestException();
          struct.ire.read(iprot);
          struct.setIreIsSet(true);
        }
        if (incoming.get(2)) {
          struct.ace = new org.apache.airavata.model.error.AiravataClientException();
          struct.ace.read(iprot);
          struct.setAceIsSet(true);
        }
        if (incoming.get(3)) {
          struct.ase = new org.apache.airavata.model.error.AiravataSystemException();
          struct.ase.read(iprot);
          struct.setAseIsSet(true);
        }
        if (incoming.get(4)) {
          struct.ae = new org.apache.airavata.model.error.AuthorizationException();
          struct.ae.read(iprot);
          struct.setAeIsSet(true);
        }
      }
    }

  }

  public static class addUnicoreDataMovementDetails_args implements org.apache.thrift.TBase<addUnicoreDataMovementDetails_args, addUnicoreDataMovementDetails_args._Fields>, java.io.Serializable, Cloneable, Comparable<addUnicoreDataMovementDetails_args>   {
    private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("addUnicoreDataMovementDetails_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 COMPUTE_RESOURCE_ID_FIELD_DESC = new org.apache.thrift.protocol.TField("computeResourceId", org.apache.thrift.protocol.TType.STRING, (short)2);
    private static final org.apache.thrift.protocol.TField PRIORITY_ORDER_FIELD_DESC = new org.apache.thrift.protocol.TField("priorityOrder", org.apache.thrift.protocol.TType.I32, (short)3);
    private static final org.apache.thrift.protocol.TField UNICORE_DATA_MOVEMENT_FIELD_DESC = new org.apache.thrift.protocol.TField("unicoreDataMovement", org.apache.thrift.protocol.TType.STRUCT, (short)4);

    private static final Map<Class<? extends IScheme>, SchemeFactory> schemes = new HashMap<Class<? extends IScheme>, SchemeFactory>();
    static {
      schemes.put(StandardScheme.class, new addUnicoreDataMovementDetails_argsStandardSchemeFactory());
      schemes.put(TupleScheme.class, new addUnicoreDataMovementDetails_argsTupleSchemeFactory());
    }

    public org.apache.airavata.model.security.AuthzToken authzToken; // required
    public String computeResourceId; // required
    public int priorityOrder; // required
    public org.apache.airavata.model.appcatalog.computeresource.UnicoreDataMovement unicoreDataMovement; // required

    /** 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"),
      COMPUTE_RESOURCE_ID((short)2, "computeResourceId"),
      PRIORITY_ORDER((short)3, "priorityOrder"),
      UNICORE_DATA_MOVEMENT((short)4, "unicoreDataMovement");

      private static final Map<String, _Fields> byName = new HashMap<String, _Fields>();

      static {
        for (_Fields field : EnumSet.allOf(_Fields.class)) {
          byName.put(field.getFieldName(), field);
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, or null if its not found.
       */
      public static _Fields findByThriftId(int fieldId) {
        switch(fieldId) {
          case 1: // AUTHZ_TOKEN
            return AUTHZ_TOKEN;
          case 2: // COMPUTE_RESOURCE_ID
            return COMPUTE_RESOURCE_ID;
          case 3: // PRIORITY_ORDER
            return PRIORITY_ORDER;
          case 4: // UNICORE_DATA_MOVEMENT
            return UNICORE_DATA_MOVEMENT;
          default:
            return null;
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, throwing an exception
       * if it is not found.
       */
      public static _Fields findByThriftIdOrThrow(int fieldId) {
        _Fields fields = findByThriftId(fieldId);
        if (fields == null) throw new IllegalArgumentException("Field " + fieldId + " doesn't exist!");
        return fields;
      }

      /**
       * Find the _Fields constant that matches name, or null if its not found.
       */
      public static _Fields findByName(String name) {
        return byName.get(name);
      }

      private final short _thriftId;
      private final String _fieldName;

      _Fields(short thriftId, String fieldName) {
        _thriftId = thriftId;
        _fieldName = fieldName;
      }

      public short getThriftFieldId() {
        return _thriftId;
      }

      public String getFieldName() {
        return _fieldName;
      }
    }

    // isset id assignments
    private static final int __PRIORITYORDER_ISSET_ID = 0;
    private byte __isset_bitfield = 0;
    public static final Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
    static {
      Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new EnumMap<_Fields, org.apache.thrift.meta_data.FieldMetaData>(_Fields.class);
      tmpMap.put(_Fields.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.COMPUTE_RESOURCE_ID, new org.apache.thrift.meta_data.FieldMetaData("computeResourceId", org.apache.thrift.TFieldRequirementType.REQUIRED, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING)));
      tmpMap.put(_Fields.PRIORITY_ORDER, new org.apache.thrift.meta_data.FieldMetaData("priorityOrder", org.apache.thrift.TFieldRequirementType.REQUIRED, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.I32)));
      tmpMap.put(_Fields.UNICORE_DATA_MOVEMENT, new org.apache.thrift.meta_data.FieldMetaData("unicoreDataMovement", org.apache.thrift.TFieldRequirementType.REQUIRED, 
          new org.apache.thrift.meta_data.StructMetaData(org.apache.thrift.protocol.TType.STRUCT, org.apache.airavata.model.appcatalog.computeresource.UnicoreDataMovement.class)));
      metaDataMap = Collections.unmodifiableMap(tmpMap);
      org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(addUnicoreDataMovementDetails_args.class, metaDataMap);
    }

    public addUnicoreDataMovementDetails_args() {
    }

    public addUnicoreDataMovementDetails_args(
      org.apache.airavata.model.security.AuthzToken authzToken,
      String computeResourceId,
      int priorityOrder,
      org.apache.airavata.model.appcatalog.computeresource.UnicoreDataMovement unicoreDataMovement)
    {
      this();
      this.authzToken = authzToken;
      this.computeResourceId = computeResourceId;
      this.priorityOrder = priorityOrder;
      setPriorityOrderIsSet(true);
      this.unicoreDataMovement = unicoreDataMovement;
    }

    /**
     * Performs a deep copy on <i>other</i>.
     */
    public addUnicoreDataMovementDetails_args(addUnicoreDataMovementDetails_args other) {
      __isset_bitfield = other.__isset_bitfield;
      if (other.isSetAuthzToken()) {
        this.authzToken = new org.apache.airavata.model.security.AuthzToken(other.authzToken);
      }
      if (other.isSetComputeResourceId()) {
        this.computeResourceId = other.computeResourceId;
      }
      this.priorityOrder = other.priorityOrder;
      if (other.isSetUnicoreDataMovement()) {
        this.unicoreDataMovement = new org.apache.airavata.model.appcatalog.computeresource.UnicoreDataMovement(other.unicoreDataMovement);
      }
    }

    public addUnicoreDataMovementDetails_args deepCopy() {
      return new addUnicoreDataMovementDetails_args(this);
    }

    @Override
    public void clear() {
      this.authzToken = null;
      this.computeResourceId = null;
      setPriorityOrderIsSet(false);
      this.priorityOrder = 0;
      this.unicoreDataMovement = null;
    }

    public org.apache.airavata.model.security.AuthzToken getAuthzToken() {
      return this.authzToken;
    }

    public addUnicoreDataMovementDetails_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 String getComputeResourceId() {
      return this.computeResourceId;
    }

    public addUnicoreDataMovementDetails_args setComputeResourceId(String computeResourceId) {
      this.computeResourceId = computeResourceId;
      return this;
    }

    public void unsetComputeResourceId() {
      this.computeResourceId = null;
    }

    /** Returns true if field computeResourceId is set (has been assigned a value) and false otherwise */
    public boolean isSetComputeResourceId() {
      return this.computeResourceId != null;
    }

    public void setComputeResourceIdIsSet(boolean value) {
      if (!value) {
        this.computeResourceId = null;
      }
    }

    public int getPriorityOrder() {
      return this.priorityOrder;
    }

    public addUnicoreDataMovementDetails_args setPriorityOrder(int priorityOrder) {
      this.priorityOrder = priorityOrder;
      setPriorityOrderIsSet(true);
      return this;
    }

    public void unsetPriorityOrder() {
      __isset_bitfield = EncodingUtils.clearBit(__isset_bitfield, __PRIORITYORDER_ISSET_ID);
    }

    /** Returns true if field priorityOrder is set (has been assigned a value) and false otherwise */
    public boolean isSetPriorityOrder() {
      return EncodingUtils.testBit(__isset_bitfield, __PRIORITYORDER_ISSET_ID);
    }

    public void setPriorityOrderIsSet(boolean value) {
      __isset_bitfield = EncodingUtils.setBit(__isset_bitfield, __PRIORITYORDER_ISSET_ID, value);
    }

    public org.apache.airavata.model.appcatalog.computeresource.UnicoreDataMovement getUnicoreDataMovement() {
      return this.unicoreDataMovement;
    }

    public addUnicoreDataMovementDetails_args setUnicoreDataMovement(org.apache.airavata.model.appcatalog.computeresource.UnicoreDataMovement unicoreDataMovement) {
      this.unicoreDataMovement = unicoreDataMovement;
      return this;
    }

    public void unsetUnicoreDataMovement() {
      this.unicoreDataMovement = null;
    }

    /** Returns true if field unicoreDataMovement is set (has been assigned a value) and false otherwise */
    public boolean isSetUnicoreDataMovement() {
      return this.unicoreDataMovement != null;
    }

    public void setUnicoreDataMovementIsSet(boolean value) {
      if (!value) {
        this.unicoreDataMovement = null;
      }
    }

    public void setFieldValue(_Fields field, Object value) {
      switch (field) {
      case AUTHZ_TOKEN:
        if (value == null) {
          unsetAuthzToken();
        } else {
          setAuthzToken((org.apache.airavata.model.security.AuthzToken)value);
        }
        break;

      case COMPUTE_RESOURCE_ID:
        if (value == null) {
          unsetComputeResourceId();
        } else {
          setComputeResourceId((String)value);
        }
        break;

      case PRIORITY_ORDER:
        if (value == null) {
          unsetPriorityOrder();
        } else {
          setPriorityOrder((Integer)value);
        }
        break;

      case UNICORE_DATA_MOVEMENT:
        if (value == null) {
          unsetUnicoreDataMovement();
        } else {
          setUnicoreDataMovement((org.apache.airavata.model.appcatalog.computeresource.UnicoreDataMovement)value);
        }
        break;

      }
    }

    public Object getFieldValue(_Fields field) {
      switch (field) {
      case AUTHZ_TOKEN:
        return getAuthzToken();

      case COMPUTE_RESOURCE_ID:
        return getComputeResourceId();

      case PRIORITY_ORDER:
        return Integer.valueOf(getPriorityOrder());

      case UNICORE_DATA_MOVEMENT:
        return getUnicoreDataMovement();

      }
      throw new IllegalStateException();
    }

    /** Returns true if field corresponding to fieldID is set (has been assigned a value) and false otherwise */
    public boolean isSet(_Fields field) {
      if (field == null) {
        throw new IllegalArgumentException();
      }

      switch (field) {
      case AUTHZ_TOKEN:
        return isSetAuthzToken();
      case COMPUTE_RESOURCE_ID:
        return isSetComputeResourceId();
      case PRIORITY_ORDER:
        return isSetPriorityOrder();
      case UNICORE_DATA_MOVEMENT:
        return isSetUnicoreDataMovement();
      }
      throw new IllegalStateException();
    }

    @Override
    public boolean equals(Object that) {
      if (that == null)
        return false;
      if (that instanceof addUnicoreDataMovementDetails_args)
        return this.equals((addUnicoreDataMovementDetails_args)that);
      return false;
    }

    public boolean equals(addUnicoreDataMovementDetails_args that) {
      if (that == null)
        return false;

      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_computeResourceId = true && this.isSetComputeResourceId();
      boolean that_present_computeResourceId = true && that.isSetComputeResourceId();
      if (this_present_computeResourceId || that_present_computeResourceId) {
        if (!(this_present_computeResourceId && that_present_computeResourceId))
          return false;
        if (!this.computeResourceId.equals(that.computeResourceId))
          return false;
      }

      boolean this_present_priorityOrder = true;
      boolean that_present_priorityOrder = true;
      if (this_present_priorityOrder || that_present_priorityOrder) {
        if (!(this_present_priorityOrder && that_present_priorityOrder))
          return false;
        if (this.priorityOrder != that.priorityOrder)
          return false;
      }

      boolean this_present_unicoreDataMovement = true && this.isSetUnicoreDataMovement();
      boolean that_present_unicoreDataMovement = true && that.isSetUnicoreDataMovement();
      if (this_present_unicoreDataMovement || that_present_unicoreDataMovement) {
        if (!(this_present_unicoreDataMovement && that_present_unicoreDataMovement))
          return false;
        if (!this.unicoreDataMovement.equals(that.unicoreDataMovement))
          return false;
      }

      return true;
    }

    @Override
    public int hashCode() {
      List<Object> list = new ArrayList<Object>();

      boolean present_authzToken = true && (isSetAuthzToken());
      list.add(present_authzToken);
      if (present_authzToken)
        list.add(authzToken);

      boolean present_computeResourceId = true && (isSetComputeResourceId());
      list.add(present_computeResourceId);
      if (present_computeResourceId)
        list.add(computeResourceId);

      boolean present_priorityOrder = true;
      list.add(present_priorityOrder);
      if (present_priorityOrder)
        list.add(priorityOrder);

      boolean present_unicoreDataMovement = true && (isSetUnicoreDataMovement());
      list.add(present_unicoreDataMovement);
      if (present_unicoreDataMovement)
        list.add(unicoreDataMovement);

      return list.hashCode();
    }

    @Override
    public int compareTo(addUnicoreDataMovementDetails_args other) {
      if (!getClass().equals(other.getClass())) {
        return getClass().getName().compareTo(other.getClass().getName());
      }

      int lastComparison = 0;

      lastComparison = 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 = Boolean.valueOf(isSetComputeResourceId()).compareTo(other.isSetComputeResourceId());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetComputeResourceId()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.computeResourceId, other.computeResourceId);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = Boolean.valueOf(isSetPriorityOrder()).compareTo(other.isSetPriorityOrder());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetPriorityOrder()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.priorityOrder, other.priorityOrder);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = Boolean.valueOf(isSetUnicoreDataMovement()).compareTo(other.isSetUnicoreDataMovement());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetUnicoreDataMovement()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.unicoreDataMovement, other.unicoreDataMovement);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      return 0;
    }

    public _Fields fieldForId(int fieldId) {
      return _Fields.findByThriftId(fieldId);
    }

    public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
      schemes.get(iprot.getScheme()).getScheme().read(iprot, this);
    }

    public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException {
      schemes.get(oprot.getScheme()).getScheme().write(oprot, this);
    }

    @Override
    public String toString() {
      StringBuilder sb = new StringBuilder("addUnicoreDataMovementDetails_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("computeResourceId:");
      if (this.computeResourceId == null) {
        sb.append("null");
      } else {
        sb.append(this.computeResourceId);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("priorityOrder:");
      sb.append(this.priorityOrder);
      first = false;
      if (!first) sb.append(", ");
      sb.append("unicoreDataMovement:");
      if (this.unicoreDataMovement == null) {
        sb.append("null");
      } else {
        sb.append(this.unicoreDataMovement);
      }
      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 (computeResourceId == null) {
        throw new org.apache.thrift.protocol.TProtocolException("Required field 'computeResourceId' was not present! Struct: " + toString());
      }
      // alas, we cannot check 'priorityOrder' because it's a primitive and you chose the non-beans generator.
      if (unicoreDataMovement == null) {
        throw new org.apache.thrift.protocol.TProtocolException("Required field 'unicoreDataMovement' was not present! Struct: " + toString());
      }
      // check for sub-struct validity
      if (authzToken != null) {
        authzToken.validate();
      }
      if (unicoreDataMovement != null) {
        unicoreDataMovement.validate();
      }
    }

    private void writeObject(java.io.ObjectOutputStream out) throws java.io.IOException {
      try {
        write(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(out)));
      } catch (org.apache.thrift.TException te) {
        throw new java.io.IOException(te);
      }
    }

    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, ClassNotFoundException {
      try {
        // 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 addUnicoreDataMovementDetails_argsStandardSchemeFactory implements SchemeFactory {
      public addUnicoreDataMovementDetails_argsStandardScheme getScheme() {
        return new addUnicoreDataMovementDetails_argsStandardScheme();
      }
    }

    private static class addUnicoreDataMovementDetails_argsStandardScheme extends StandardScheme<addUnicoreDataMovementDetails_args> {

      public void read(org.apache.thrift.protocol.TProtocol iprot, addUnicoreDataMovementDetails_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: // COMPUTE_RESOURCE_ID
              if (schemeField.type == org.apache.thrift.protocol.TType.STRING) {
                struct.computeResourceId = iprot.readString();
                struct.setComputeResourceIdIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 3: // PRIORITY_ORDER
              if (schemeField.type == org.apache.thrift.protocol.TType.I32) {
                struct.priorityOrder = iprot.readI32();
                struct.setPriorityOrderIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 4: // UNICORE_DATA_MOVEMENT
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.unicoreDataMovement = new org.apache.airavata.model.appcatalog.computeresource.UnicoreDataMovement();
                struct.unicoreDataMovement.read(iprot);
                struct.setUnicoreDataMovementIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            default:
              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
          }
          iprot.readFieldEnd();
        }
        iprot.readStructEnd();

        // check for required fields of primitive type, which can't be checked in the validate method
        if (!struct.isSetPriorityOrder()) {
          throw new org.apache.thrift.protocol.TProtocolException("Required field 'priorityOrder' was not found in serialized data! Struct: " + toString());
        }
        struct.validate();
      }

      public void write(org.apache.thrift.protocol.TProtocol oprot, addUnicoreDataMovementDetails_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.computeResourceId != null) {
          oprot.writeFieldBegin(COMPUTE_RESOURCE_ID_FIELD_DESC);
          oprot.writeString(struct.computeResourceId);
          oprot.writeFieldEnd();
        }
        oprot.writeFieldBegin(PRIORITY_ORDER_FIELD_DESC);
        oprot.writeI32(struct.priorityOrder);
        oprot.writeFieldEnd();
        if (struct.unicoreDataMovement != null) {
          oprot.writeFieldBegin(UNICORE_DATA_MOVEMENT_FIELD_DESC);
          struct.unicoreDataMovement.write(oprot);
          oprot.writeFieldEnd();
        }
        oprot.writeFieldStop();
        oprot.writeStructEnd();
      }

    }

    private static class addUnicoreDataMovementDetails_argsTupleSchemeFactory implements SchemeFactory {
      public addUnicoreDataMovementDetails_argsTupleScheme getScheme() {
        return new addUnicoreDataMovementDetails_argsTupleScheme();
      }
    }

    private static class addUnicoreDataMovementDetails_argsTupleScheme extends TupleScheme<addUnicoreDataMovementDetails_args> {

      @Override
      public void write(org.apache.thrift.protocol.TProtocol prot, addUnicoreDataMovementDetails_args struct) throws org.apache.thrift.TException {
        TTupleProtocol oprot = (TTupleProtocol) prot;
        struct.authzToken.write(oprot);
        oprot.writeString(struct.computeResourceId);
        oprot.writeI32(struct.priorityOrder);
        struct.unicoreDataMovement.write(oprot);
      }

      @Override
      public void read(org.apache.thrift.protocol.TProtocol prot, addUnicoreDataMovementDetails_args struct) throws org.apache.thrift.TException {
        TTupleProtocol iprot = (TTupleProtocol) prot;
        struct.authzToken = new org.apache.airavata.model.security.AuthzToken();
        struct.authzToken.read(iprot);
        struct.setAuthzTokenIsSet(true);
        struct.computeResourceId = iprot.readString();
        struct.setComputeResourceIdIsSet(true);
        struct.priorityOrder = iprot.readI32();
        struct.setPriorityOrderIsSet(true);
        struct.unicoreDataMovement = new org.apache.airavata.model.appcatalog.computeresource.UnicoreDataMovement();
        struct.unicoreDataMovement.read(iprot);
        struct.setUnicoreDataMovementIsSet(true);
      }
    }

  }

  public static class addUnicoreDataMovementDetails_result implements org.apache.thrift.TBase<addUnicoreDataMovementDetails_result, addUnicoreDataMovementDetails_result._Fields>, java.io.Serializable, Cloneable, Comparable<addUnicoreDataMovementDetails_result>   {
    private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("addUnicoreDataMovementDetails_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 IRE_FIELD_DESC = new org.apache.thrift.protocol.TField("ire", org.apache.thrift.protocol.TType.STRUCT, (short)1);
    private static final org.apache.thrift.protocol.TField ACE_FIELD_DESC = new org.apache.thrift.protocol.TField("ace", org.apache.thrift.protocol.TType.STRUCT, (short)2);
    private static final org.apache.thrift.protocol.TField ASE_FIELD_DESC = new org.apache.thrift.protocol.TField("ase", org.apache.thrift.protocol.TType.STRUCT, (short)3);
    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)4);

    private static final Map<Class<? extends IScheme>, SchemeFactory> schemes = new HashMap<Class<? extends IScheme>, SchemeFactory>();
    static {
      schemes.put(StandardScheme.class, new addUnicoreDataMovementDetails_resultStandardSchemeFactory());
      schemes.put(TupleScheme.class, new addUnicoreDataMovementDetails_resultTupleSchemeFactory());
    }

    public String success; // required
    public org.apache.airavata.model.error.InvalidRequestException ire; // required
    public org.apache.airavata.model.error.AiravataClientException ace; // required
    public org.apache.airavata.model.error.AiravataSystemException ase; // 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"),
      IRE((short)1, "ire"),
      ACE((short)2, "ace"),
      ASE((short)3, "ase"),
      AE((short)4, "ae");

      private static final Map<String, _Fields> byName = new HashMap<String, _Fields>();

      static {
        for (_Fields field : EnumSet.allOf(_Fields.class)) {
          byName.put(field.getFieldName(), field);
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, or null if its not found.
       */
      public static _Fields findByThriftId(int fieldId) {
        switch(fieldId) {
          case 0: // SUCCESS
            return SUCCESS;
          case 1: // IRE
            return IRE;
          case 2: // ACE
            return ACE;
          case 3: // ASE
            return ASE;
          case 4: // 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 IllegalArgumentException("Field " + fieldId + " doesn't exist!");
        return fields;
      }

      /**
       * Find the _Fields constant that matches name, or null if its not found.
       */
      public static _Fields findByName(String name) {
        return byName.get(name);
      }

      private final short _thriftId;
      private final String _fieldName;

      _Fields(short thriftId, String fieldName) {
        _thriftId = thriftId;
        _fieldName = fieldName;
      }

      public short getThriftFieldId() {
        return _thriftId;
      }

      public String getFieldName() {
        return _fieldName;
      }
    }

    // isset id assignments
    public static final Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
    static {
      Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new EnumMap<_Fields, org.apache.thrift.meta_data.FieldMetaData>(_Fields.class);
      tmpMap.put(_Fields.SUCCESS, new org.apache.thrift.meta_data.FieldMetaData("success", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING)));
      tmpMap.put(_Fields.IRE, new org.apache.thrift.meta_data.FieldMetaData("ire", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRUCT)));
      tmpMap.put(_Fields.ACE, new org.apache.thrift.meta_data.FieldMetaData("ace", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRUCT)));
      tmpMap.put(_Fields.ASE, new org.apache.thrift.meta_data.FieldMetaData("ase", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRUCT)));
      tmpMap.put(_Fields.AE, new org.apache.thrift.meta_data.FieldMetaData("ae", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRUCT)));
      metaDataMap = Collections.unmodifiableMap(tmpMap);
      org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(addUnicoreDataMovementDetails_result.class, metaDataMap);
    }

    public addUnicoreDataMovementDetails_result() {
    }

    public addUnicoreDataMovementDetails_result(
      String success,
      org.apache.airavata.model.error.InvalidRequestException ire,
      org.apache.airavata.model.error.AiravataClientException ace,
      org.apache.airavata.model.error.AiravataSystemException ase,
      org.apache.airavata.model.error.AuthorizationException ae)
    {
      this();
      this.success = success;
      this.ire = ire;
      this.ace = ace;
      this.ase = ase;
      this.ae = ae;
    }

    /**
     * Performs a deep copy on <i>other</i>.
     */
    public addUnicoreDataMovementDetails_result(addUnicoreDataMovementDetails_result other) {
      if (other.isSetSuccess()) {
        this.success = other.success;
      }
      if (other.isSetIre()) {
        this.ire = new org.apache.airavata.model.error.InvalidRequestException(other.ire);
      }
      if (other.isSetAce()) {
        this.ace = new org.apache.airavata.model.error.AiravataClientException(other.ace);
      }
      if (other.isSetAse()) {
        this.ase = new org.apache.airavata.model.error.AiravataSystemException(other.ase);
      }
      if (other.isSetAe()) {
        this.ae = new org.apache.airavata.model.error.AuthorizationException(other.ae);
      }
    }

    public addUnicoreDataMovementDetails_result deepCopy() {
      return new addUnicoreDataMovementDetails_result(this);
    }

    @Override
    public void clear() {
      this.success = null;
      this.ire = null;
      this.ace = null;
      this.ase = null;
      this.ae = null;
    }

    public String getSuccess() {
      return this.success;
    }

    public addUnicoreDataMovementDetails_result setSuccess(String success) {
      this.success = success;
      return this;
    }

    public void unsetSuccess() {
      this.success = null;
    }

    /** Returns true if field success is set (has been assigned a value) and false otherwise */
    public boolean isSetSuccess() {
      return this.success != null;
    }

    public void setSuccessIsSet(boolean value) {
      if (!value) {
        this.success = null;
      }
    }

    public org.apache.airavata.model.error.InvalidRequestException getIre() {
      return this.ire;
    }

    public addUnicoreDataMovementDetails_result setIre(org.apache.airavata.model.error.InvalidRequestException ire) {
      this.ire = ire;
      return this;
    }

    public void unsetIre() {
      this.ire = null;
    }

    /** Returns true if field ire is set (has been assigned a value) and false otherwise */
    public boolean isSetIre() {
      return this.ire != null;
    }

    public void setIreIsSet(boolean value) {
      if (!value) {
        this.ire = null;
      }
    }

    public org.apache.airavata.model.error.AiravataClientException getAce() {
      return this.ace;
    }

    public addUnicoreDataMovementDetails_result setAce(org.apache.airavata.model.error.AiravataClientException ace) {
      this.ace = ace;
      return this;
    }

    public void unsetAce() {
      this.ace = null;
    }

    /** Returns true if field ace is set (has been assigned a value) and false otherwise */
    public boolean isSetAce() {
      return this.ace != null;
    }

    public void setAceIsSet(boolean value) {
      if (!value) {
        this.ace = null;
      }
    }

    public org.apache.airavata.model.error.AiravataSystemException getAse() {
      return this.ase;
    }

    public addUnicoreDataMovementDetails_result setAse(org.apache.airavata.model.error.AiravataSystemException ase) {
      this.ase = ase;
      return this;
    }

    public void unsetAse() {
      this.ase = null;
    }

    /** Returns true if field ase is set (has been assigned a value) and false otherwise */
    public boolean isSetAse() {
      return this.ase != null;
    }

    public void setAseIsSet(boolean value) {
      if (!value) {
        this.ase = null;
      }
    }

    public org.apache.airavata.model.error.AuthorizationException getAe() {
      return this.ae;
    }

    public addUnicoreDataMovementDetails_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, Object value) {
      switch (field) {
      case SUCCESS:
        if (value == null) {
          unsetSuccess();
        } else {
          setSuccess((String)value);
        }
        break;

      case IRE:
        if (value == null) {
          unsetIre();
        } else {
          setIre((org.apache.airavata.model.error.InvalidRequestException)value);
        }
        break;

      case ACE:
        if (value == null) {
          unsetAce();
        } else {
          setAce((org.apache.airavata.model.error.AiravataClientException)value);
        }
        break;

      case ASE:
        if (value == null) {
          unsetAse();
        } else {
          setAse((org.apache.airavata.model.error.AiravataSystemException)value);
        }
        break;

      case AE:
        if (value == null) {
          unsetAe();
        } else {
          setAe((org.apache.airavata.model.error.AuthorizationException)value);
        }
        break;

      }
    }

    public Object getFieldValue(_Fields field) {
      switch (field) {
      case SUCCESS:
        return getSuccess();

      case IRE:
        return getIre();

      case ACE:
        return getAce();

      case ASE:
        return getAse();

      case AE:
        return getAe();

      }
      throw new IllegalStateException();
    }

    /** Returns true if field corresponding to fieldID is set (has been assigned a value) and false otherwise */
    public boolean isSet(_Fields field) {
      if (field == null) {
        throw new IllegalArgumentException();
      }

      switch (field) {
      case SUCCESS:
        return isSetSuccess();
      case IRE:
        return isSetIre();
      case ACE:
        return isSetAce();
      case ASE:
        return isSetAse();
      case AE:
        return isSetAe();
      }
      throw new IllegalStateException();
    }

    @Override
    public boolean equals(Object that) {
      if (that == null)
        return false;
      if (that instanceof addUnicoreDataMovementDetails_result)
        return this.equals((addUnicoreDataMovementDetails_result)that);
      return false;
    }

    public boolean equals(addUnicoreDataMovementDetails_result that) {
      if (that == null)
        return false;

      boolean this_present_success = true && this.isSetSuccess();
      boolean that_present_success = true && that.isSetSuccess();
      if (this_present_success || that_present_success) {
        if (!(this_present_success && that_present_success))
          return false;
        if (!this.success.equals(that.success))
          return false;
      }

      boolean this_present_ire = true && this.isSetIre();
      boolean that_present_ire = true && that.isSetIre();
      if (this_present_ire || that_present_ire) {
        if (!(this_present_ire && that_present_ire))
          return false;
        if (!this.ire.equals(that.ire))
          return false;
      }

      boolean this_present_ace = true && this.isSetAce();
      boolean that_present_ace = true && that.isSetAce();
      if (this_present_ace || that_present_ace) {
        if (!(this_present_ace && that_present_ace))
          return false;
        if (!this.ace.equals(that.ace))
          return false;
      }

      boolean this_present_ase = true && this.isSetAse();
      boolean that_present_ase = true && that.isSetAse();
      if (this_present_ase || that_present_ase) {
        if (!(this_present_ase && that_present_ase))
          return false;
        if (!this.ase.equals(that.ase))
          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() {
      List<Object> list = new ArrayList<Object>();

      boolean present_success = true && (isSetSuccess());
      list.add(present_success);
      if (present_success)
        list.add(success);

      boolean present_ire = true && (isSetIre());
      list.add(present_ire);
      if (present_ire)
        list.add(ire);

      boolean present_ace = true && (isSetAce());
      list.add(present_ace);
      if (present_ace)
        list.add(ace);

      boolean present_ase = true && (isSetAse());
      list.add(present_ase);
      if (present_ase)
        list.add(ase);

      boolean present_ae = true && (isSetAe());
      list.add(present_ae);
      if (present_ae)
        list.add(ae);

      return list.hashCode();
    }

    @Override
    public int compareTo(addUnicoreDataMovementDetails_result other) {
      if (!getClass().equals(other.getClass())) {
        return getClass().getName().compareTo(other.getClass().getName());
      }

      int lastComparison = 0;

      lastComparison = Boolean.valueOf(isSetSuccess()).compareTo(other.isSetSuccess());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetSuccess()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.success, other.success);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = Boolean.valueOf(isSetIre()).compareTo(other.isSetIre());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetIre()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.ire, other.ire);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = Boolean.valueOf(isSetAce()).compareTo(other.isSetAce());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetAce()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.ace, other.ace);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = Boolean.valueOf(isSetAse()).compareTo(other.isSetAse());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetAse()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.ase, other.ase);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = 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 {
      schemes.get(iprot.getScheme()).getScheme().read(iprot, this);
    }

    public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException {
      schemes.get(oprot.getScheme()).getScheme().write(oprot, this);
      }

    @Override
    public String toString() {
      StringBuilder sb = new StringBuilder("addUnicoreDataMovementDetails_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("ire:");
      if (this.ire == null) {
        sb.append("null");
      } else {
        sb.append(this.ire);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("ace:");
      if (this.ace == null) {
        sb.append("null");
      } else {
        sb.append(this.ace);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("ase:");
      if (this.ase == null) {
        sb.append("null");
      } else {
        sb.append(this.ase);
      }
      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, 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 addUnicoreDataMovementDetails_resultStandardSchemeFactory implements SchemeFactory {
      public addUnicoreDataMovementDetails_resultStandardScheme getScheme() {
        return new addUnicoreDataMovementDetails_resultStandardScheme();
      }
    }

    private static class addUnicoreDataMovementDetails_resultStandardScheme extends StandardScheme<addUnicoreDataMovementDetails_result> {

      public void read(org.apache.thrift.protocol.TProtocol iprot, addUnicoreDataMovementDetails_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: // IRE
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.ire = new org.apache.airavata.model.error.InvalidRequestException();
                struct.ire.read(iprot);
                struct.setIreIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 2: // ACE
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.ace = new org.apache.airavata.model.error.AiravataClientException();
                struct.ace.read(iprot);
                struct.setAceIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 3: // ASE
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.ase = new org.apache.airavata.model.error.AiravataSystemException();
                struct.ase.read(iprot);
                struct.setAseIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 4: // 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, addUnicoreDataMovementDetails_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.ire != null) {
          oprot.writeFieldBegin(IRE_FIELD_DESC);
          struct.ire.write(oprot);
          oprot.writeFieldEnd();
        }
        if (struct.ace != null) {
          oprot.writeFieldBegin(ACE_FIELD_DESC);
          struct.ace.write(oprot);
          oprot.writeFieldEnd();
        }
        if (struct.ase != null) {
          oprot.writeFieldBegin(ASE_FIELD_DESC);
          struct.ase.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 addUnicoreDataMovementDetails_resultTupleSchemeFactory implements SchemeFactory {
      public addUnicoreDataMovementDetails_resultTupleScheme getScheme() {
        return new addUnicoreDataMovementDetails_resultTupleScheme();
      }
    }

    private static class addUnicoreDataMovementDetails_resultTupleScheme extends TupleScheme<addUnicoreDataMovementDetails_result> {

      @Override
      public void write(org.apache.thrift.protocol.TProtocol prot, addUnicoreDataMovementDetails_result struct) throws org.apache.thrift.TException {
        TTupleProtocol oprot = (TTupleProtocol) prot;
        BitSet optionals = new BitSet();
        if (struct.isSetSuccess()) {
          optionals.set(0);
        }
        if (struct.isSetIre()) {
          optionals.set(1);
        }
        if (struct.isSetAce()) {
          optionals.set(2);
        }
        if (struct.isSetAse()) {
          optionals.set(3);
        }
        if (struct.isSetAe()) {
          optionals.set(4);
        }
        oprot.writeBitSet(optionals, 5);
        if (struct.isSetSuccess()) {
          oprot.writeString(struct.success);
        }
        if (struct.isSetIre()) {
          struct.ire.write(oprot);
        }
        if (struct.isSetAce()) {
          struct.ace.write(oprot);
        }
        if (struct.isSetAse()) {
          struct.ase.write(oprot);
        }
        if (struct.isSetAe()) {
          struct.ae.write(oprot);
        }
      }

      @Override
      public void read(org.apache.thrift.protocol.TProtocol prot, addUnicoreDataMovementDetails_result struct) throws org.apache.thrift.TException {
        TTupleProtocol iprot = (TTupleProtocol) prot;
        BitSet incoming = iprot.readBitSet(5);
        if (incoming.get(0)) {
          struct.success = iprot.readString();
          struct.setSuccessIsSet(true);
        }
        if (incoming.get(1)) {
          struct.ire = new org.apache.airavata.model.error.InvalidRequestException();
          struct.ire.read(iprot);
          struct.setIreIsSet(true);
        }
        if (incoming.get(2)) {
          struct.ace = new org.apache.airavata.model.error.AiravataClientException();
          struct.ace.read(iprot);
          struct.setAceIsSet(true);
        }
        if (incoming.get(3)) {
          struct.ase = new org.apache.airavata.model.error.AiravataSystemException();
          struct.ase.read(iprot);
          struct.setAseIsSet(true);
        }
        if (incoming.get(4)) {
          struct.ae = new org.apache.airavata.model.error.AuthorizationException();
          struct.ae.read(iprot);
          struct.setAeIsSet(true);
        }
      }
    }

  }

  public static class updateUnicoreDataMovementDetails_args implements org.apache.thrift.TBase<updateUnicoreDataMovementDetails_args, updateUnicoreDataMovementDetails_args._Fields>, java.io.Serializable, Cloneable, Comparable<updateUnicoreDataMovementDetails_args>   {
    private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("updateUnicoreDataMovementDetails_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 DATA_MOVEMENT_INTERFACE_ID_FIELD_DESC = new org.apache.thrift.protocol.TField("dataMovementInterfaceId", org.apache.thrift.protocol.TType.STRING, (short)2);
    private static final org.apache.thrift.protocol.TField UNICORE_DATA_MOVEMENT_FIELD_DESC = new org.apache.thrift.protocol.TField("unicoreDataMovement", org.apache.thrift.protocol.TType.STRUCT, (short)3);

    private static final Map<Class<? extends IScheme>, SchemeFactory> schemes = new HashMap<Class<? extends IScheme>, SchemeFactory>();
    static {
      schemes.put(StandardScheme.class, new updateUnicoreDataMovementDetails_argsStandardSchemeFactory());
      schemes.put(TupleScheme.class, new updateUnicoreDataMovementDetails_argsTupleSchemeFactory());
    }

    public org.apache.airavata.model.security.AuthzToken authzToken; // required
    public String dataMovementInterfaceId; // required
    public org.apache.airavata.model.appcatalog.computeresource.UnicoreDataMovement unicoreDataMovement; // required

    /** 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"),
      DATA_MOVEMENT_INTERFACE_ID((short)2, "dataMovementInterfaceId"),
      UNICORE_DATA_MOVEMENT((short)3, "unicoreDataMovement");

      private static final Map<String, _Fields> byName = new HashMap<String, _Fields>();

      static {
        for (_Fields field : EnumSet.allOf(_Fields.class)) {
          byName.put(field.getFieldName(), field);
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, or null if its not found.
       */
      public static _Fields findByThriftId(int fieldId) {
        switch(fieldId) {
          case 1: // AUTHZ_TOKEN
            return AUTHZ_TOKEN;
          case 2: // DATA_MOVEMENT_INTERFACE_ID
            return DATA_MOVEMENT_INTERFACE_ID;
          case 3: // UNICORE_DATA_MOVEMENT
            return UNICORE_DATA_MOVEMENT;
          default:
            return null;
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, throwing an exception
       * if it is not found.
       */
      public static _Fields findByThriftIdOrThrow(int fieldId) {
        _Fields fields = findByThriftId(fieldId);
        if (fields == null) throw new IllegalArgumentException("Field " + fieldId + " doesn't exist!");
        return fields;
      }

      /**
       * Find the _Fields constant that matches name, or null if its not found.
       */
      public static _Fields findByName(String name) {
        return byName.get(name);
      }

      private final short _thriftId;
      private final String _fieldName;

      _Fields(short thriftId, String fieldName) {
        _thriftId = thriftId;
        _fieldName = fieldName;
      }

      public short getThriftFieldId() {
        return _thriftId;
      }

      public String getFieldName() {
        return _fieldName;
      }
    }

    // isset id assignments
    public static final Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
    static {
      Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new EnumMap<_Fields, org.apache.thrift.meta_data.FieldMetaData>(_Fields.class);
      tmpMap.put(_Fields.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.DATA_MOVEMENT_INTERFACE_ID, new org.apache.thrift.meta_data.FieldMetaData("dataMovementInterfaceId", org.apache.thrift.TFieldRequirementType.REQUIRED, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING)));
      tmpMap.put(_Fields.UNICORE_DATA_MOVEMENT, new org.apache.thrift.meta_data.FieldMetaData("unicoreDataMovement", org.apache.thrift.TFieldRequirementType.REQUIRED, 
          new org.apache.thrift.meta_data.StructMetaData(org.apache.thrift.protocol.TType.STRUCT, org.apache.airavata.model.appcatalog.computeresource.UnicoreDataMovement.class)));
      metaDataMap = Collections.unmodifiableMap(tmpMap);
      org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(updateUnicoreDataMovementDetails_args.class, metaDataMap);
    }

    public updateUnicoreDataMovementDetails_args() {
    }

    public updateUnicoreDataMovementDetails_args(
      org.apache.airavata.model.security.AuthzToken authzToken,
      String dataMovementInterfaceId,
      org.apache.airavata.model.appcatalog.computeresource.UnicoreDataMovement unicoreDataMovement)
    {
      this();
      this.authzToken = authzToken;
      this.dataMovementInterfaceId = dataMovementInterfaceId;
      this.unicoreDataMovement = unicoreDataMovement;
    }

    /**
     * Performs a deep copy on <i>other</i>.
     */
    public updateUnicoreDataMovementDetails_args(updateUnicoreDataMovementDetails_args other) {
      if (other.isSetAuthzToken()) {
        this.authzToken = new org.apache.airavata.model.security.AuthzToken(other.authzToken);
      }
      if (other.isSetDataMovementInterfaceId()) {
        this.dataMovementInterfaceId = other.dataMovementInterfaceId;
      }
      if (other.isSetUnicoreDataMovement()) {
        this.unicoreDataMovement = new org.apache.airavata.model.appcatalog.computeresource.UnicoreDataMovement(other.unicoreDataMovement);
      }
    }

    public updateUnicoreDataMovementDetails_args deepCopy() {
      return new updateUnicoreDataMovementDetails_args(this);
    }

    @Override
    public void clear() {
      this.authzToken = null;
      this.dataMovementInterfaceId = null;
      this.unicoreDataMovement = null;
    }

    public org.apache.airavata.model.security.AuthzToken getAuthzToken() {
      return this.authzToken;
    }

    public updateUnicoreDataMovementDetails_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 String getDataMovementInterfaceId() {
      return this.dataMovementInterfaceId;
    }

    public updateUnicoreDataMovementDetails_args setDataMovementInterfaceId(String dataMovementInterfaceId) {
      this.dataMovementInterfaceId = dataMovementInterfaceId;
      return this;
    }

    public void unsetDataMovementInterfaceId() {
      this.dataMovementInterfaceId = null;
    }

    /** Returns true if field dataMovementInterfaceId is set (has been assigned a value) and false otherwise */
    public boolean isSetDataMovementInterfaceId() {
      return this.dataMovementInterfaceId != null;
    }

    public void setDataMovementInterfaceIdIsSet(boolean value) {
      if (!value) {
        this.dataMovementInterfaceId = null;
      }
    }

    public org.apache.airavata.model.appcatalog.computeresource.UnicoreDataMovement getUnicoreDataMovement() {
      return this.unicoreDataMovement;
    }

    public updateUnicoreDataMovementDetails_args setUnicoreDataMovement(org.apache.airavata.model.appcatalog.computeresource.UnicoreDataMovement unicoreDataMovement) {
      this.unicoreDataMovement = unicoreDataMovement;
      return this;
    }

    public void unsetUnicoreDataMovement() {
      this.unicoreDataMovement = null;
    }

    /** Returns true if field unicoreDataMovement is set (has been assigned a value) and false otherwise */
    public boolean isSetUnicoreDataMovement() {
      return this.unicoreDataMovement != null;
    }

    public void setUnicoreDataMovementIsSet(boolean value) {
      if (!value) {
        this.unicoreDataMovement = null;
      }
    }

    public void setFieldValue(_Fields field, Object value) {
      switch (field) {
      case AUTHZ_TOKEN:
        if (value == null) {
          unsetAuthzToken();
        } else {
          setAuthzToken((org.apache.airavata.model.security.AuthzToken)value);
        }
        break;

      case DATA_MOVEMENT_INTERFACE_ID:
        if (value == null) {
          unsetDataMovementInterfaceId();
        } else {
          setDataMovementInterfaceId((String)value);
        }
        break;

      case UNICORE_DATA_MOVEMENT:
        if (value == null) {
          unsetUnicoreDataMovement();
        } else {
          setUnicoreDataMovement((org.apache.airavata.model.appcatalog.computeresource.UnicoreDataMovement)value);
        }
        break;

      }
    }

    public Object getFieldValue(_Fields field) {
      switch (field) {
      case AUTHZ_TOKEN:
        return getAuthzToken();

      case DATA_MOVEMENT_INTERFACE_ID:
        return getDataMovementInterfaceId();

      case UNICORE_DATA_MOVEMENT:
        return getUnicoreDataMovement();

      }
      throw new IllegalStateException();
    }

    /** Returns true if field corresponding to fieldID is set (has been assigned a value) and false otherwise */
    public boolean isSet(_Fields field) {
      if (field == null) {
        throw new IllegalArgumentException();
      }

      switch (field) {
      case AUTHZ_TOKEN:
        return isSetAuthzToken();
      case DATA_MOVEMENT_INTERFACE_ID:
        return isSetDataMovementInterfaceId();
      case UNICORE_DATA_MOVEMENT:
        return isSetUnicoreDataMovement();
      }
      throw new IllegalStateException();
    }

    @Override
    public boolean equals(Object that) {
      if (that == null)
        return false;
      if (that instanceof updateUnicoreDataMovementDetails_args)
        return this.equals((updateUnicoreDataMovementDetails_args)that);
      return false;
    }

    public boolean equals(updateUnicoreDataMovementDetails_args that) {
      if (that == null)
        return false;

      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_dataMovementInterfaceId = true && this.isSetDataMovementInterfaceId();
      boolean that_present_dataMovementInterfaceId = true && that.isSetDataMovementInterfaceId();
      if (this_present_dataMovementInterfaceId || that_present_dataMovementInterfaceId) {
        if (!(this_present_dataMovementInterfaceId && that_present_dataMovementInterfaceId))
          return false;
        if (!this.dataMovementInterfaceId.equals(that.dataMovementInterfaceId))
          return false;
      }

      boolean this_present_unicoreDataMovement = true && this.isSetUnicoreDataMovement();
      boolean that_present_unicoreDataMovement = true && that.isSetUnicoreDataMovement();
      if (this_present_unicoreDataMovement || that_present_unicoreDataMovement) {
        if (!(this_present_unicoreDataMovement && that_present_unicoreDataMovement))
          return false;
        if (!this.unicoreDataMovement.equals(that.unicoreDataMovement))
          return false;
      }

      return true;
    }

    @Override
    public int hashCode() {
      List<Object> list = new ArrayList<Object>();

      boolean present_authzToken = true && (isSetAuthzToken());
      list.add(present_authzToken);
      if (present_authzToken)
        list.add(authzToken);

      boolean present_dataMovementInterfaceId = true && (isSetDataMovementInterfaceId());
      list.add(present_dataMovementInterfaceId);
      if (present_dataMovementInterfaceId)
        list.add(dataMovementInterfaceId);

      boolean present_unicoreDataMovement = true && (isSetUnicoreDataMovement());
      list.add(present_unicoreDataMovement);
      if (present_unicoreDataMovement)
        list.add(unicoreDataMovement);

      return list.hashCode();
    }

    @Override
    public int compareTo(updateUnicoreDataMovementDetails_args other) {
      if (!getClass().equals(other.getClass())) {
        return getClass().getName().compareTo(other.getClass().getName());
      }

      int lastComparison = 0;

      lastComparison = 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 = Boolean.valueOf(isSetDataMovementInterfaceId()).compareTo(other.isSetDataMovementInterfaceId());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetDataMovementInterfaceId()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.dataMovementInterfaceId, other.dataMovementInterfaceId);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = Boolean.valueOf(isSetUnicoreDataMovement()).compareTo(other.isSetUnicoreDataMovement());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetUnicoreDataMovement()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.unicoreDataMovement, other.unicoreDataMovement);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      return 0;
    }

    public _Fields fieldForId(int fieldId) {
      return _Fields.findByThriftId(fieldId);
    }

    public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
      schemes.get(iprot.getScheme()).getScheme().read(iprot, this);
    }

    public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException {
      schemes.get(oprot.getScheme()).getScheme().write(oprot, this);
    }

    @Override
    public String toString() {
      StringBuilder sb = new StringBuilder("updateUnicoreDataMovementDetails_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("dataMovementInterfaceId:");
      if (this.dataMovementInterfaceId == null) {
        sb.append("null");
      } else {
        sb.append(this.dataMovementInterfaceId);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("unicoreDataMovement:");
      if (this.unicoreDataMovement == null) {
        sb.append("null");
      } else {
        sb.append(this.unicoreDataMovement);
      }
      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 (dataMovementInterfaceId == null) {
        throw new org.apache.thrift.protocol.TProtocolException("Required field 'dataMovementInterfaceId' was not present! Struct: " + toString());
      }
      if (unicoreDataMovement == null) {
        throw new org.apache.thrift.protocol.TProtocolException("Required field 'unicoreDataMovement' was not present! Struct: " + toString());
      }
      // check for sub-struct validity
      if (authzToken != null) {
        authzToken.validate();
      }
      if (unicoreDataMovement != null) {
        unicoreDataMovement.validate();
      }
    }

    private void writeObject(java.io.ObjectOutputStream out) throws java.io.IOException {
      try {
        write(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(out)));
      } catch (org.apache.thrift.TException te) {
        throw new java.io.IOException(te);
      }
    }

    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, ClassNotFoundException {
      try {
        read(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(in)));
      } catch (org.apache.thrift.TException te) {
        throw new java.io.IOException(te);
      }
    }

    private static class updateUnicoreDataMovementDetails_argsStandardSchemeFactory implements SchemeFactory {
      public updateUnicoreDataMovementDetails_argsStandardScheme getScheme() {
        return new updateUnicoreDataMovementDetails_argsStandardScheme();
      }
    }

    private static class updateUnicoreDataMovementDetails_argsStandardScheme extends StandardScheme<updateUnicoreDataMovementDetails_args> {

      public void read(org.apache.thrift.protocol.TProtocol iprot, updateUnicoreDataMovementDetails_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: // DATA_MOVEMENT_INTERFACE_ID
              if (schemeField.type == org.apache.thrift.protocol.TType.STRING) {
                struct.dataMovementInterfaceId = iprot.readString();
                struct.setDataMovementInterfaceIdIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 3: // UNICORE_DATA_MOVEMENT
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.unicoreDataMovement = new org.apache.airavata.model.appcatalog.computeresource.UnicoreDataMovement();
                struct.unicoreDataMovement.read(iprot);
                struct.setUnicoreDataMovementIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            default:
              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
          }
          iprot.readFieldEnd();
        }
        iprot.readStructEnd();

        // check for required fields of primitive type, which can't be checked in the validate method
        struct.validate();
      }

      public void write(org.apache.thrift.protocol.TProtocol oprot, updateUnicoreDataMovementDetails_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.dataMovementInterfaceId != null) {
          oprot.writeFieldBegin(DATA_MOVEMENT_INTERFACE_ID_FIELD_DESC);
          oprot.writeString(struct.dataMovementInterfaceId);
          oprot.writeFieldEnd();
        }
        if (struct.unicoreDataMovement != null) {
          oprot.writeFieldBegin(UNICORE_DATA_MOVEMENT_FIELD_DESC);
          struct.unicoreDataMovement.write(oprot);
          oprot.writeFieldEnd();
        }
        oprot.writeFieldStop();
        oprot.writeStructEnd();
      }

    }

    private static class updateUnicoreDataMovementDetails_argsTupleSchemeFactory implements SchemeFactory {
      public updateUnicoreDataMovementDetails_argsTupleScheme getScheme() {
        return new updateUnicoreDataMovementDetails_argsTupleScheme();
      }
    }

    private static class updateUnicoreDataMovementDetails_argsTupleScheme extends TupleScheme<updateUnicoreDataMovementDetails_args> {

      @Override
      public void write(org.apache.thrift.protocol.TProtocol prot, updateUnicoreDataMovementDetails_args struct) throws org.apache.thrift.TException {
        TTupleProtocol oprot = (TTupleProtocol) prot;
        struct.authzToken.write(oprot);
        oprot.writeString(struct.dataMovementInterfaceId);
        struct.unicoreDataMovement.write(oprot);
      }

      @Override
      public void read(org.apache.thrift.protocol.TProtocol prot, updateUnicoreDataMovementDetails_args struct) throws org.apache.thrift.TException {
        TTupleProtocol iprot = (TTupleProtocol) prot;
        struct.authzToken = new org.apache.airavata.model.security.AuthzToken();
        struct.authzToken.read(iprot);
        struct.setAuthzTokenIsSet(true);
        struct.dataMovementInterfaceId = iprot.readString();
        struct.setDataMovementInterfaceIdIsSet(true);
        struct.unicoreDataMovement = new org.apache.airavata.model.appcatalog.computeresource.UnicoreDataMovement();
        struct.unicoreDataMovement.read(iprot);
        struct.setUnicoreDataMovementIsSet(true);
      }
    }

  }

  public static class updateUnicoreDataMovementDetails_result implements org.apache.thrift.TBase<updateUnicoreDataMovementDetails_result, updateUnicoreDataMovementDetails_result._Fields>, java.io.Serializable, Cloneable, Comparable<updateUnicoreDataMovementDetails_result>   {
    private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("updateUnicoreDataMovementDetails_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 IRE_FIELD_DESC = new org.apache.thrift.protocol.TField("ire", org.apache.thrift.protocol.TType.STRUCT, (short)1);
    private static final org.apache.thrift.protocol.TField ACE_FIELD_DESC = new org.apache.thrift.protocol.TField("ace", org.apache.thrift.protocol.TType.STRUCT, (short)2);
    private static final org.apache.thrift.protocol.TField ASE_FIELD_DESC = new org.apache.thrift.protocol.TField("ase", org.apache.thrift.protocol.TType.STRUCT, (short)3);
    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)4);

    private static final Map<Class<? extends IScheme>, SchemeFactory> schemes = new HashMap<Class<? extends IScheme>, SchemeFactory>();
    static {
      schemes.put(StandardScheme.class, new updateUnicoreDataMovementDetails_resultStandardSchemeFactory());
      schemes.put(TupleScheme.class, new updateUnicoreDataMovementDetails_resultTupleSchemeFactory());
    }

    public boolean success; // required
    public org.apache.airavata.model.error.InvalidRequestException ire; // required
    public org.apache.airavata.model.error.AiravataClientException ace; // required
    public org.apache.airavata.model.error.AiravataSystemException ase; // 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"),
      IRE((short)1, "ire"),
      ACE((short)2, "ace"),
      ASE((short)3, "ase"),
      AE((short)4, "ae");

      private static final Map<String, _Fields> byName = new HashMap<String, _Fields>();

      static {
        for (_Fields field : EnumSet.allOf(_Fields.class)) {
          byName.put(field.getFieldName(), field);
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, or null if its not found.
       */
      public static _Fields findByThriftId(int fieldId) {
        switch(fieldId) {
          case 0: // SUCCESS
            return SUCCESS;
          case 1: // IRE
            return IRE;
          case 2: // ACE
            return ACE;
          case 3: // ASE
            return ASE;
          case 4: // 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 IllegalArgumentException("Field " + fieldId + " doesn't exist!");
        return fields;
      }

      /**
       * Find the _Fields constant that matches name, or null if its not found.
       */
      public static _Fields findByName(String name) {
        return byName.get(name);
      }

      private final short _thriftId;
      private final String _fieldName;

      _Fields(short thriftId, String fieldName) {
        _thriftId = thriftId;
        _fieldName = fieldName;
      }

      public short getThriftFieldId() {
        return _thriftId;
      }

      public String getFieldName() {
        return _fieldName;
      }
    }

    // isset id assignments
    private static final int __SUCCESS_ISSET_ID = 0;
    private byte __isset_bitfield = 0;
    public static final Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
    static {
      Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new EnumMap<_Fields, org.apache.thrift.meta_data.FieldMetaData>(_Fields.class);
      tmpMap.put(_Fields.SUCCESS, new org.apache.thrift.meta_data.FieldMetaData("success", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.BOOL)));
      tmpMap.put(_Fields.IRE, new org.apache.thrift.meta_data.FieldMetaData("ire", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRUCT)));
      tmpMap.put(_Fields.ACE, new org.apache.thrift.meta_data.FieldMetaData("ace", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRUCT)));
      tmpMap.put(_Fields.ASE, new org.apache.thrift.meta_data.FieldMetaData("ase", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRUCT)));
      tmpMap.put(_Fields.AE, new org.apache.thrift.meta_data.FieldMetaData("ae", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRUCT)));
      metaDataMap = Collections.unmodifiableMap(tmpMap);
      org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(updateUnicoreDataMovementDetails_result.class, metaDataMap);
    }

    public updateUnicoreDataMovementDetails_result() {
    }

    public updateUnicoreDataMovementDetails_result(
      boolean success,
      org.apache.airavata.model.error.InvalidRequestException ire,
      org.apache.airavata.model.error.AiravataClientException ace,
      org.apache.airavata.model.error.AiravataSystemException ase,
      org.apache.airavata.model.error.AuthorizationException ae)
    {
      this();
      this.success = success;
      setSuccessIsSet(true);
      this.ire = ire;
      this.ace = ace;
      this.ase = ase;
      this.ae = ae;
    }

    /**
     * Performs a deep copy on <i>other</i>.
     */
    public updateUnicoreDataMovementDetails_result(updateUnicoreDataMovementDetails_result other) {
      __isset_bitfield = other.__isset_bitfield;
      this.success = other.success;
      if (other.isSetIre()) {
        this.ire = new org.apache.airavata.model.error.InvalidRequestException(other.ire);
      }
      if (other.isSetAce()) {
        this.ace = new org.apache.airavata.model.error.AiravataClientException(other.ace);
      }
      if (other.isSetAse()) {
        this.ase = new org.apache.airavata.model.error.AiravataSystemException(other.ase);
      }
      if (other.isSetAe()) {
        this.ae = new org.apache.airavata.model.error.AuthorizationException(other.ae);
      }
    }

    public updateUnicoreDataMovementDetails_result deepCopy() {
      return new updateUnicoreDataMovementDetails_result(this);
    }

    @Override
    public void clear() {
      setSuccessIsSet(false);
      this.success = false;
      this.ire = null;
      this.ace = null;
      this.ase = null;
      this.ae = null;
    }

    public boolean isSuccess() {
      return this.success;
    }

    public updateUnicoreDataMovementDetails_result setSuccess(boolean success) {
      this.success = success;
      setSuccessIsSet(true);
      return this;
    }

    public void unsetSuccess() {
      __isset_bitfield = EncodingUtils.clearBit(__isset_bitfield, __SUCCESS_ISSET_ID);
    }

    /** Returns true if field success is set (has been assigned a value) and false otherwise */
    public boolean isSetSuccess() {
      return EncodingUtils.testBit(__isset_bitfield, __SUCCESS_ISSET_ID);
    }

    public void setSuccessIsSet(boolean value) {
      __isset_bitfield = EncodingUtils.setBit(__isset_bitfield, __SUCCESS_ISSET_ID, value);
    }

    public org.apache.airavata.model.error.InvalidRequestException getIre() {
      return this.ire;
    }

    public updateUnicoreDataMovementDetails_result setIre(org.apache.airavata.model.error.InvalidRequestException ire) {
      this.ire = ire;
      return this;
    }

    public void unsetIre() {
      this.ire = null;
    }

    /** Returns true if field ire is set (has been assigned a value) and false otherwise */
    public boolean isSetIre() {
      return this.ire != null;
    }

    public void setIreIsSet(boolean value) {
      if (!value) {
        this.ire = null;
      }
    }

    public org.apache.airavata.model.error.AiravataClientException getAce() {
      return this.ace;
    }

    public updateUnicoreDataMovementDetails_result setAce(org.apache.airavata.model.error.AiravataClientException ace) {
      this.ace = ace;
      return this;
    }

    public void unsetAce() {
      this.ace = null;
    }

    /** Returns true if field ace is set (has been assigned a value) and false otherwise */
    public boolean isSetAce() {
      return this.ace != null;
    }

    public void setAceIsSet(boolean value) {
      if (!value) {
        this.ace = null;
      }
    }

    public org.apache.airavata.model.error.AiravataSystemException getAse() {
      return this.ase;
    }

    public updateUnicoreDataMovementDetails_result setAse(org.apache.airavata.model.error.AiravataSystemException ase) {
      this.ase = ase;
      return this;
    }

    public void unsetAse() {
      this.ase = null;
    }

    /** Returns true if field ase is set (has been assigned a value) and false otherwise */
    public boolean isSetAse() {
      return this.ase != null;
    }

    public void setAseIsSet(boolean value) {
      if (!value) {
        this.ase = null;
      }
    }

    public org.apache.airavata.model.error.AuthorizationException getAe() {
      return this.ae;
    }

    public updateUnicoreDataMovementDetails_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, Object value) {
      switch (field) {
      case SUCCESS:
        if (value == null) {
          unsetSuccess();
        } else {
          setSuccess((Boolean)value);
        }
        break;

      case IRE:
        if (value == null) {
          unsetIre();
        } else {
          setIre((org.apache.airavata.model.error.InvalidRequestException)value);
        }
        break;

      case ACE:
        if (value == null) {
          unsetAce();
        } else {
          setAce((org.apache.airavata.model.error.AiravataClientException)value);
        }
        break;

      case ASE:
        if (value == null) {
          unsetAse();
        } else {
          setAse((org.apache.airavata.model.error.AiravataSystemException)value);
        }
        break;

      case AE:
        if (value == null) {
          unsetAe();
        } else {
          setAe((org.apache.airavata.model.error.AuthorizationException)value);
        }
        break;

      }
    }

    public Object getFieldValue(_Fields field) {
      switch (field) {
      case SUCCESS:
        return Boolean.valueOf(isSuccess());

      case IRE:
        return getIre();

      case ACE:
        return getAce();

      case ASE:
        return getAse();

      case AE:
        return getAe();

      }
      throw new IllegalStateException();
    }

    /** Returns true if field corresponding to fieldID is set (has been assigned a value) and false otherwise */
    public boolean isSet(_Fields field) {
      if (field == null) {
        throw new IllegalArgumentException();
      }

      switch (field) {
      case SUCCESS:
        return isSetSuccess();
      case IRE:
        return isSetIre();
      case ACE:
        return isSetAce();
      case ASE:
        return isSetAse();
      case AE:
        return isSetAe();
      }
      throw new IllegalStateException();
    }

    @Override
    public boolean equals(Object that) {
      if (that == null)
        return false;
      if (that instanceof updateUnicoreDataMovementDetails_result)
        return this.equals((updateUnicoreDataMovementDetails_result)that);
      return false;
    }

    public boolean equals(updateUnicoreDataMovementDetails_result that) {
      if (that == null)
        return false;

      boolean this_present_success = true;
      boolean that_present_success = true;
      if (this_present_success || that_present_success) {
        if (!(this_present_success && that_present_success))
          return false;
        if (this.success != that.success)
          return false;
      }

      boolean this_present_ire = true && this.isSetIre();
      boolean that_present_ire = true && that.isSetIre();
      if (this_present_ire || that_present_ire) {
        if (!(this_present_ire && that_present_ire))
          return false;
        if (!this.ire.equals(that.ire))
          return false;
      }

      boolean this_present_ace = true && this.isSetAce();
      boolean that_present_ace = true && that.isSetAce();
      if (this_present_ace || that_present_ace) {
        if (!(this_present_ace && that_present_ace))
          return false;
        if (!this.ace.equals(that.ace))
          return false;
      }

      boolean this_present_ase = true && this.isSetAse();
      boolean that_present_ase = true && that.isSetAse();
      if (this_present_ase || that_present_ase) {
        if (!(this_present_ase && that_present_ase))
          return false;
        if (!this.ase.equals(that.ase))
          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() {
      List<Object> list = new ArrayList<Object>();

      boolean present_success = true;
      list.add(present_success);
      if (present_success)
        list.add(success);

      boolean present_ire = true && (isSetIre());
      list.add(present_ire);
      if (present_ire)
        list.add(ire);

      boolean present_ace = true && (isSetAce());
      list.add(present_ace);
      if (present_ace)
        list.add(ace);

      boolean present_ase = true && (isSetAse());
      list.add(present_ase);
      if (present_ase)
        list.add(ase);

      boolean present_ae = true && (isSetAe());
      list.add(present_ae);
      if (present_ae)
        list.add(ae);

      return list.hashCode();
    }

    @Override
    public int compareTo(updateUnicoreDataMovementDetails_result other) {
      if (!getClass().equals(other.getClass())) {
        return getClass().getName().compareTo(other.getClass().getName());
      }

      int lastComparison = 0;

      lastComparison = Boolean.valueOf(isSetSuccess()).compareTo(other.isSetSuccess());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetSuccess()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.success, other.success);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = Boolean.valueOf(isSetIre()).compareTo(other.isSetIre());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetIre()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.ire, other.ire);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = Boolean.valueOf(isSetAce()).compareTo(other.isSetAce());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetAce()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.ace, other.ace);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = Boolean.valueOf(isSetAse()).compareTo(other.isSetAse());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetAse()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.ase, other.ase);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = 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 {
      schemes.get(iprot.getScheme()).getScheme().read(iprot, this);
    }

    public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException {
      schemes.get(oprot.getScheme()).getScheme().write(oprot, this);
      }

    @Override
    public String toString() {
      StringBuilder sb = new StringBuilder("updateUnicoreDataMovementDetails_result(");
      boolean first = true;

      sb.append("success:");
      sb.append(this.success);
      first = false;
      if (!first) sb.append(", ");
      sb.append("ire:");
      if (this.ire == null) {
        sb.append("null");
      } else {
        sb.append(this.ire);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("ace:");
      if (this.ace == null) {
        sb.append("null");
      } else {
        sb.append(this.ace);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("ase:");
      if (this.ase == null) {
        sb.append("null");
      } else {
        sb.append(this.ase);
      }
      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, 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 updateUnicoreDataMovementDetails_resultStandardSchemeFactory implements SchemeFactory {
      public updateUnicoreDataMovementDetails_resultStandardScheme getScheme() {
        return new updateUnicoreDataMovementDetails_resultStandardScheme();
      }
    }

    private static class updateUnicoreDataMovementDetails_resultStandardScheme extends StandardScheme<updateUnicoreDataMovementDetails_result> {

      public void read(org.apache.thrift.protocol.TProtocol iprot, updateUnicoreDataMovementDetails_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: // IRE
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.ire = new org.apache.airavata.model.error.InvalidRequestException();
                struct.ire.read(iprot);
                struct.setIreIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 2: // ACE
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.ace = new org.apache.airavata.model.error.AiravataClientException();
                struct.ace.read(iprot);
                struct.setAceIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 3: // ASE
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.ase = new org.apache.airavata.model.error.AiravataSystemException();
                struct.ase.read(iprot);
                struct.setAseIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 4: // 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, updateUnicoreDataMovementDetails_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.ire != null) {
          oprot.writeFieldBegin(IRE_FIELD_DESC);
          struct.ire.write(oprot);
          oprot.writeFieldEnd();
        }
        if (struct.ace != null) {
          oprot.writeFieldBegin(ACE_FIELD_DESC);
          struct.ace.write(oprot);
          oprot.writeFieldEnd();
        }
        if (struct.ase != null) {
          oprot.writeFieldBegin(ASE_FIELD_DESC);
          struct.ase.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 updateUnicoreDataMovementDetails_resultTupleSchemeFactory implements SchemeFactory {
      public updateUnicoreDataMovementDetails_resultTupleScheme getScheme() {
        return new updateUnicoreDataMovementDetails_resultTupleScheme();
      }
    }

    private static class updateUnicoreDataMovementDetails_resultTupleScheme extends TupleScheme<updateUnicoreDataMovementDetails_result> {

      @Override
      public void write(org.apache.thrift.protocol.TProtocol prot, updateUnicoreDataMovementDetails_result struct) throws org.apache.thrift.TException {
        TTupleProtocol oprot = (TTupleProtocol) prot;
        BitSet optionals = new BitSet();
        if (struct.isSetSuccess()) {
          optionals.set(0);
        }
        if (struct.isSetIre()) {
          optionals.set(1);
        }
        if (struct.isSetAce()) {
          optionals.set(2);
        }
        if (struct.isSetAse()) {
          optionals.set(3);
        }
        if (struct.isSetAe()) {
          optionals.set(4);
        }
        oprot.writeBitSet(optionals, 5);
        if (struct.isSetSuccess()) {
          oprot.writeBool(struct.success);
        }
        if (struct.isSetIre()) {
          struct.ire.write(oprot);
        }
        if (struct.isSetAce()) {
          struct.ace.write(oprot);
        }
        if (struct.isSetAse()) {
          struct.ase.write(oprot);
        }
        if (struct.isSetAe()) {
          struct.ae.write(oprot);
        }
      }

      @Override
      public void read(org.apache.thrift.protocol.TProtocol prot, updateUnicoreDataMovementDetails_result struct) throws org.apache.thrift.TException {
        TTupleProtocol iprot = (TTupleProtocol) prot;
        BitSet incoming = iprot.readBitSet(5);
        if (incoming.get(0)) {
          struct.success = iprot.readBool();
          struct.setSuccessIsSet(true);
        }
        if (incoming.get(1)) {
          struct.ire = new org.apache.airavata.model.error.InvalidRequestException();
          struct.ire.read(iprot);
          struct.setIreIsSet(true);
        }
        if (incoming.get(2)) {
          struct.ace = new org.apache.airavata.model.error.AiravataClientException();
          struct.ace.read(iprot);
          struct.setAceIsSet(true);
        }
        if (incoming.get(3)) {
          struct.ase = new org.apache.airavata.model.error.AiravataSystemException();
          struct.ase.read(iprot);
          struct.setAseIsSet(true);
        }
        if (incoming.get(4)) {
          struct.ae = new org.apache.airavata.model.error.AuthorizationException();
          struct.ae.read(iprot);
          struct.setAeIsSet(true);
        }
      }
    }

  }

  public static class getUnicoreDataMovement_args implements org.apache.thrift.TBase<getUnicoreDataMovement_args, getUnicoreDataMovement_args._Fields>, java.io.Serializable, Cloneable, Comparable<getUnicoreDataMovement_args>   {
    private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("getUnicoreDataMovement_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 DATA_MOVEMENT_ID_FIELD_DESC = new org.apache.thrift.protocol.TField("dataMovementId", org.apache.thrift.protocol.TType.STRING, (short)2);

    private static final Map<Class<? extends IScheme>, SchemeFactory> schemes = new HashMap<Class<? extends IScheme>, SchemeFactory>();
    static {
      schemes.put(StandardScheme.class, new getUnicoreDataMovement_argsStandardSchemeFactory());
      schemes.put(TupleScheme.class, new getUnicoreDataMovement_argsTupleSchemeFactory());
    }

    public org.apache.airavata.model.security.AuthzToken authzToken; // required
    public String dataMovementId; // required

    /** 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"),
      DATA_MOVEMENT_ID((short)2, "dataMovementId");

      private static final Map<String, _Fields> byName = new HashMap<String, _Fields>();

      static {
        for (_Fields field : EnumSet.allOf(_Fields.class)) {
          byName.put(field.getFieldName(), field);
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, or null if its not found.
       */
      public static _Fields findByThriftId(int fieldId) {
        switch(fieldId) {
          case 1: // AUTHZ_TOKEN
            return AUTHZ_TOKEN;
          case 2: // DATA_MOVEMENT_ID
            return DATA_MOVEMENT_ID;
          default:
            return null;
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, throwing an exception
       * if it is not found.
       */
      public static _Fields findByThriftIdOrThrow(int fieldId) {
        _Fields fields = findByThriftId(fieldId);
        if (fields == null) throw new IllegalArgumentException("Field " + fieldId + " doesn't exist!");
        return fields;
      }

      /**
       * Find the _Fields constant that matches name, or null if its not found.
       */
      public static _Fields findByName(String name) {
        return byName.get(name);
      }

      private final short _thriftId;
      private final String _fieldName;

      _Fields(short thriftId, String fieldName) {
        _thriftId = thriftId;
        _fieldName = fieldName;
      }

      public short getThriftFieldId() {
        return _thriftId;
      }

      public String getFieldName() {
        return _fieldName;
      }
    }

    // isset id assignments
    public static final Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
    static {
      Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new EnumMap<_Fields, org.apache.thrift.meta_data.FieldMetaData>(_Fields.class);
      tmpMap.put(_Fields.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.DATA_MOVEMENT_ID, new org.apache.thrift.meta_data.FieldMetaData("dataMovementId", org.apache.thrift.TFieldRequirementType.REQUIRED, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING)));
      metaDataMap = Collections.unmodifiableMap(tmpMap);
      org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(getUnicoreDataMovement_args.class, metaDataMap);
    }

    public getUnicoreDataMovement_args() {
    }

    public getUnicoreDataMovement_args(
      org.apache.airavata.model.security.AuthzToken authzToken,
      String dataMovementId)
    {
      this();
      this.authzToken = authzToken;
      this.dataMovementId = dataMovementId;
    }

    /**
     * Performs a deep copy on <i>other</i>.
     */
    public getUnicoreDataMovement_args(getUnicoreDataMovement_args other) {
      if (other.isSetAuthzToken()) {
        this.authzToken = new org.apache.airavata.model.security.AuthzToken(other.authzToken);
      }
      if (other.isSetDataMovementId()) {
        this.dataMovementId = other.dataMovementId;
      }
    }

    public getUnicoreDataMovement_args deepCopy() {
      return new getUnicoreDataMovement_args(this);
    }

    @Override
    public void clear() {
      this.authzToken = null;
      this.dataMovementId = null;
    }

    public org.apache.airavata.model.security.AuthzToken getAuthzToken() {
      return this.authzToken;
    }

    public getUnicoreDataMovement_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 String getDataMovementId() {
      return this.dataMovementId;
    }

    public getUnicoreDataMovement_args setDataMovementId(String dataMovementId) {
      this.dataMovementId = dataMovementId;
      return this;
    }

    public void unsetDataMovementId() {
      this.dataMovementId = null;
    }

    /** Returns true if field dataMovementId is set (has been assigned a value) and false otherwise */
    public boolean isSetDataMovementId() {
      return this.dataMovementId != null;
    }

    public void setDataMovementIdIsSet(boolean value) {
      if (!value) {
        this.dataMovementId = null;
      }
    }

    public void setFieldValue(_Fields field, Object value) {
      switch (field) {
      case AUTHZ_TOKEN:
        if (value == null) {
          unsetAuthzToken();
        } else {
          setAuthzToken((org.apache.airavata.model.security.AuthzToken)value);
        }
        break;

      case DATA_MOVEMENT_ID:
        if (value == null) {
          unsetDataMovementId();
        } else {
          setDataMovementId((String)value);
        }
        break;

      }
    }

    public Object getFieldValue(_Fields field) {
      switch (field) {
      case AUTHZ_TOKEN:
        return getAuthzToken();

      case DATA_MOVEMENT_ID:
        return getDataMovementId();

      }
      throw new IllegalStateException();
    }

    /** Returns true if field corresponding to fieldID is set (has been assigned a value) and false otherwise */
    public boolean isSet(_Fields field) {
      if (field == null) {
        throw new IllegalArgumentException();
      }

      switch (field) {
      case AUTHZ_TOKEN:
        return isSetAuthzToken();
      case DATA_MOVEMENT_ID:
        return isSetDataMovementId();
      }
      throw new IllegalStateException();
    }

    @Override
    public boolean equals(Object that) {
      if (that == null)
        return false;
      if (that instanceof getUnicoreDataMovement_args)
        return this.equals((getUnicoreDataMovement_args)that);
      return false;
    }

    public boolean equals(getUnicoreDataMovement_args that) {
      if (that == null)
        return false;

      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_dataMovementId = true && this.isSetDataMovementId();
      boolean that_present_dataMovementId = true && that.isSetDataMovementId();
      if (this_present_dataMovementId || that_present_dataMovementId) {
        if (!(this_present_dataMovementId && that_present_dataMovementId))
          return false;
        if (!this.dataMovementId.equals(that.dataMovementId))
          return false;
      }

      return true;
    }

    @Override
    public int hashCode() {
      List<Object> list = new ArrayList<Object>();

      boolean present_authzToken = true && (isSetAuthzToken());
      list.add(present_authzToken);
      if (present_authzToken)
        list.add(authzToken);

      boolean present_dataMovementId = true && (isSetDataMovementId());
      list.add(present_dataMovementId);
      if (present_dataMovementId)
        list.add(dataMovementId);

      return list.hashCode();
    }

    @Override
    public int compareTo(getUnicoreDataMovement_args other) {
      if (!getClass().equals(other.getClass())) {
        return getClass().getName().compareTo(other.getClass().getName());
      }

      int lastComparison = 0;

      lastComparison = 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 = Boolean.valueOf(isSetDataMovementId()).compareTo(other.isSetDataMovementId());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetDataMovementId()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.dataMovementId, other.dataMovementId);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      return 0;
    }

    public _Fields fieldForId(int fieldId) {
      return _Fields.findByThriftId(fieldId);
    }

    public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
      schemes.get(iprot.getScheme()).getScheme().read(iprot, this);
    }

    public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException {
      schemes.get(oprot.getScheme()).getScheme().write(oprot, this);
    }

    @Override
    public String toString() {
      StringBuilder sb = new StringBuilder("getUnicoreDataMovement_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("dataMovementId:");
      if (this.dataMovementId == null) {
        sb.append("null");
      } else {
        sb.append(this.dataMovementId);
      }
      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 (dataMovementId == null) {
        throw new org.apache.thrift.protocol.TProtocolException("Required field 'dataMovementId' 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, 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 getUnicoreDataMovement_argsStandardSchemeFactory implements SchemeFactory {
      public getUnicoreDataMovement_argsStandardScheme getScheme() {
        return new getUnicoreDataMovement_argsStandardScheme();
      }
    }

    private static class getUnicoreDataMovement_argsStandardScheme extends StandardScheme<getUnicoreDataMovement_args> {

      public void read(org.apache.thrift.protocol.TProtocol iprot, getUnicoreDataMovement_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: // DATA_MOVEMENT_ID
              if (schemeField.type == org.apache.thrift.protocol.TType.STRING) {
                struct.dataMovementId = iprot.readString();
                struct.setDataMovementIdIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            default:
              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
          }
          iprot.readFieldEnd();
        }
        iprot.readStructEnd();

        // check for required fields of primitive type, which can't be checked in the validate method
        struct.validate();
      }

      public void write(org.apache.thrift.protocol.TProtocol oprot, getUnicoreDataMovement_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.dataMovementId != null) {
          oprot.writeFieldBegin(DATA_MOVEMENT_ID_FIELD_DESC);
          oprot.writeString(struct.dataMovementId);
          oprot.writeFieldEnd();
        }
        oprot.writeFieldStop();
        oprot.writeStructEnd();
      }

    }

    private static class getUnicoreDataMovement_argsTupleSchemeFactory implements SchemeFactory {
      public getUnicoreDataMovement_argsTupleScheme getScheme() {
        return new getUnicoreDataMovement_argsTupleScheme();
      }
    }

    private static class getUnicoreDataMovement_argsTupleScheme extends TupleScheme<getUnicoreDataMovement_args> {

      @Override
      public void write(org.apache.thrift.protocol.TProtocol prot, getUnicoreDataMovement_args struct) throws org.apache.thrift.TException {
        TTupleProtocol oprot = (TTupleProtocol) prot;
        struct.authzToken.write(oprot);
        oprot.writeString(struct.dataMovementId);
      }

      @Override
      public void read(org.apache.thrift.protocol.TProtocol prot, getUnicoreDataMovement_args struct) throws org.apache.thrift.TException {
        TTupleProtocol iprot = (TTupleProtocol) prot;
        struct.authzToken = new org.apache.airavata.model.security.AuthzToken();
        struct.authzToken.read(iprot);
        struct.setAuthzTokenIsSet(true);
        struct.dataMovementId = iprot.readString();
        struct.setDataMovementIdIsSet(true);
      }
    }

  }

  public static class getUnicoreDataMovement_result implements org.apache.thrift.TBase<getUnicoreDataMovement_result, getUnicoreDataMovement_result._Fields>, java.io.Serializable, Cloneable, Comparable<getUnicoreDataMovement_result>   {
    private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("getUnicoreDataMovement_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 IRE_FIELD_DESC = new org.apache.thrift.protocol.TField("ire", org.apache.thrift.protocol.TType.STRUCT, (short)1);
    private static final org.apache.thrift.protocol.TField ACE_FIELD_DESC = new org.apache.thrift.protocol.TField("ace", org.apache.thrift.protocol.TType.STRUCT, (short)2);
    private static final org.apache.thrift.protocol.TField ASE_FIELD_DESC = new org.apache.thrift.protocol.TField("ase", org.apache.thrift.protocol.TType.STRUCT, (short)3);
    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)4);

    private static final Map<Class<? extends IScheme>, SchemeFactory> schemes = new HashMap<Class<? extends IScheme>, SchemeFactory>();
    static {
      schemes.put(StandardScheme.class, new getUnicoreDataMovement_resultStandardSchemeFactory());
      schemes.put(TupleScheme.class, new getUnicoreDataMovement_resultTupleSchemeFactory());
    }

    public org.apache.airavata.model.appcatalog.computeresource.UnicoreDataMovement success; // required
    public org.apache.airavata.model.error.InvalidRequestException ire; // required
    public org.apache.airavata.model.error.AiravataClientException ace; // required
    public org.apache.airavata.model.error.AiravataSystemException ase; // 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"),
      IRE((short)1, "ire"),
      ACE((short)2, "ace"),
      ASE((short)3, "ase"),
      AE((short)4, "ae");

      private static final Map<String, _Fields> byName = new HashMap<String, _Fields>();

      static {
        for (_Fields field : EnumSet.allOf(_Fields.class)) {
          byName.put(field.getFieldName(), field);
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, or null if its not found.
       */
      public static _Fields findByThriftId(int fieldId) {
        switch(fieldId) {
          case 0: // SUCCESS
            return SUCCESS;
          case 1: // IRE
            return IRE;
          case 2: // ACE
            return ACE;
          case 3: // ASE
            return ASE;
          case 4: // 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 IllegalArgumentException("Field " + fieldId + " doesn't exist!");
        return fields;
      }

      /**
       * Find the _Fields constant that matches name, or null if its not found.
       */
      public static _Fields findByName(String name) {
        return byName.get(name);
      }

      private final short _thriftId;
      private final String _fieldName;

      _Fields(short thriftId, String fieldName) {
        _thriftId = thriftId;
        _fieldName = fieldName;
      }

      public short getThriftFieldId() {
        return _thriftId;
      }

      public String getFieldName() {
        return _fieldName;
      }
    }

    // isset id assignments
    public static final Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
    static {
      Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new EnumMap<_Fields, org.apache.thrift.meta_data.FieldMetaData>(_Fields.class);
      tmpMap.put(_Fields.SUCCESS, new org.apache.thrift.meta_data.FieldMetaData("success", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.StructMetaData(org.apache.thrift.protocol.TType.STRUCT, org.apache.airavata.model.appcatalog.computeresource.UnicoreDataMovement.class)));
      tmpMap.put(_Fields.IRE, new org.apache.thrift.meta_data.FieldMetaData("ire", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRUCT)));
      tmpMap.put(_Fields.ACE, new org.apache.thrift.meta_data.FieldMetaData("ace", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRUCT)));
      tmpMap.put(_Fields.ASE, new org.apache.thrift.meta_data.FieldMetaData("ase", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRUCT)));
      tmpMap.put(_Fields.AE, new org.apache.thrift.meta_data.FieldMetaData("ae", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRUCT)));
      metaDataMap = Collections.unmodifiableMap(tmpMap);
      org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(getUnicoreDataMovement_result.class, metaDataMap);
    }

    public getUnicoreDataMovement_result() {
    }

    public getUnicoreDataMovement_result(
      org.apache.airavata.model.appcatalog.computeresource.UnicoreDataMovement success,
      org.apache.airavata.model.error.InvalidRequestException ire,
      org.apache.airavata.model.error.AiravataClientException ace,
      org.apache.airavata.model.error.AiravataSystemException ase,
      org.apache.airavata.model.error.AuthorizationException ae)
    {
      this();
      this.success = success;
      this.ire = ire;
      this.ace = ace;
      this.ase = ase;
      this.ae = ae;
    }

    /**
     * Performs a deep copy on <i>other</i>.
     */
    public getUnicoreDataMovement_result(getUnicoreDataMovement_result other) {
      if (other.isSetSuccess()) {
        this.success = new org.apache.airavata.model.appcatalog.computeresource.UnicoreDataMovement(other.success);
      }
      if (other.isSetIre()) {
        this.ire = new org.apache.airavata.model.error.InvalidRequestException(other.ire);
      }
      if (other.isSetAce()) {
        this.ace = new org.apache.airavata.model.error.AiravataClientException(other.ace);
      }
      if (other.isSetAse()) {
        this.ase = new org.apache.airavata.model.error.AiravataSystemException(other.ase);
      }
      if (other.isSetAe()) {
        this.ae = new org.apache.airavata.model.error.AuthorizationException(other.ae);
      }
    }

    public getUnicoreDataMovement_result deepCopy() {
      return new getUnicoreDataMovement_result(this);
    }

    @Override
    public void clear() {
      this.success = null;
      this.ire = null;
      this.ace = null;
      this.ase = null;
      this.ae = null;
    }

    public org.apache.airavata.model.appcatalog.computeresource.UnicoreDataMovement getSuccess() {
      return this.success;
    }

    public getUnicoreDataMovement_result setSuccess(org.apache.airavata.model.appcatalog.computeresource.UnicoreDataMovement 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.model.error.InvalidRequestException getIre() {
      return this.ire;
    }

    public getUnicoreDataMovement_result setIre(org.apache.airavata.model.error.InvalidRequestException ire) {
      this.ire = ire;
      return this;
    }

    public void unsetIre() {
      this.ire = null;
    }

    /** Returns true if field ire is set (has been assigned a value) and false otherwise */
    public boolean isSetIre() {
      return this.ire != null;
    }

    public void setIreIsSet(boolean value) {
      if (!value) {
        this.ire = null;
      }
    }

    public org.apache.airavata.model.error.AiravataClientException getAce() {
      return this.ace;
    }

    public getUnicoreDataMovement_result setAce(org.apache.airavata.model.error.AiravataClientException ace) {
      this.ace = ace;
      return this;
    }

    public void unsetAce() {
      this.ace = null;
    }

    /** Returns true if field ace is set (has been assigned a value) and false otherwise */
    public boolean isSetAce() {
      return this.ace != null;
    }

    public void setAceIsSet(boolean value) {
      if (!value) {
        this.ace = null;
      }
    }

    public org.apache.airavata.model.error.AiravataSystemException getAse() {
      return this.ase;
    }

    public getUnicoreDataMovement_result setAse(org.apache.airavata.model.error.AiravataSystemException ase) {
      this.ase = ase;
      return this;
    }

    public void unsetAse() {
      this.ase = null;
    }

    /** Returns true if field ase is set (has been assigned a value) and false otherwise */
    public boolean isSetAse() {
      return this.ase != null;
    }

    public void setAseIsSet(boolean value) {
      if (!value) {
        this.ase = null;
      }
    }

    public org.apache.airavata.model.error.AuthorizationException getAe() {
      return this.ae;
    }

    public getUnicoreDataMovement_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, Object value) {
      switch (field) {
      case SUCCESS:
        if (value == null) {
          unsetSuccess();
        } else {
          setSuccess((org.apache.airavata.model.appcatalog.computeresource.UnicoreDataMovement)value);
        }
        break;

      case IRE:
        if (value == null) {
          unsetIre();
        } else {
          setIre((org.apache.airavata.model.error.InvalidRequestException)value);
        }
        break;

      case ACE:
        if (value == null) {
          unsetAce();
        } else {
          setAce((org.apache.airavata.model.error.AiravataClientException)value);
        }
        break;

      case ASE:
        if (value == null) {
          unsetAse();
        } else {
          setAse((org.apache.airavata.model.error.AiravataSystemException)value);
        }
        break;

      case AE:
        if (value == null) {
          unsetAe();
        } else {
          setAe((org.apache.airavata.model.error.AuthorizationException)value);
        }
        break;

      }
    }

    public Object getFieldValue(_Fields field) {
      switch (field) {
      case SUCCESS:
        return getSuccess();

      case IRE:
        return getIre();

      case ACE:
        return getAce();

      case ASE:
        return getAse();

      case AE:
        return getAe();

      }
      throw new IllegalStateException();
    }

    /** Returns true if field corresponding to fieldID is set (has been assigned a value) and false otherwise */
    public boolean isSet(_Fields field) {
      if (field == null) {
        throw new IllegalArgumentException();
      }

      switch (field) {
      case SUCCESS:
        return isSetSuccess();
      case IRE:
        return isSetIre();
      case ACE:
        return isSetAce();
      case ASE:
        return isSetAse();
      case AE:
        return isSetAe();
      }
      throw new IllegalStateException();
    }

    @Override
    public boolean equals(Object that) {
      if (that == null)
        return false;
      if (that instanceof getUnicoreDataMovement_result)
        return this.equals((getUnicoreDataMovement_result)that);
      return false;
    }

    public boolean equals(getUnicoreDataMovement_result that) {
      if (that == null)
        return false;

      boolean this_present_success = true && this.isSetSuccess();
      boolean that_present_success = true && that.isSetSuccess();
      if (this_present_success || that_present_success) {
        if (!(this_present_success && that_present_success))
          return false;
        if (!this.success.equals(that.success))
          return false;
      }

      boolean this_present_ire = true && this.isSetIre();
      boolean that_present_ire = true && that.isSetIre();
      if (this_present_ire || that_present_ire) {
        if (!(this_present_ire && that_present_ire))
          return false;
        if (!this.ire.equals(that.ire))
          return false;
      }

      boolean this_present_ace = true && this.isSetAce();
      boolean that_present_ace = true && that.isSetAce();
      if (this_present_ace || that_present_ace) {
        if (!(this_present_ace && that_present_ace))
          return false;
        if (!this.ace.equals(that.ace))
          return false;
      }

      boolean this_present_ase = true && this.isSetAse();
      boolean that_present_ase = true && that.isSetAse();
      if (this_present_ase || that_present_ase) {
        if (!(this_present_ase && that_present_ase))
          return false;
        if (!this.ase.equals(that.ase))
          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() {
      List<Object> list = new ArrayList<Object>();

      boolean present_success = true && (isSetSuccess());
      list.add(present_success);
      if (present_success)
        list.add(success);

      boolean present_ire = true && (isSetIre());
      list.add(present_ire);
      if (present_ire)
        list.add(ire);

      boolean present_ace = true && (isSetAce());
      list.add(present_ace);
      if (present_ace)
        list.add(ace);

      boolean present_ase = true && (isSetAse());
      list.add(present_ase);
      if (present_ase)
        list.add(ase);

      boolean present_ae = true && (isSetAe());
      list.add(present_ae);
      if (present_ae)
        list.add(ae);

      return list.hashCode();
    }

    @Override
    public int compareTo(getUnicoreDataMovement_result other) {
      if (!getClass().equals(other.getClass())) {
        return getClass().getName().compareTo(other.getClass().getName());
      }

      int lastComparison = 0;

      lastComparison = Boolean.valueOf(isSetSuccess()).compareTo(other.isSetSuccess());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetSuccess()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.success, other.success);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = Boolean.valueOf(isSetIre()).compareTo(other.isSetIre());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetIre()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.ire, other.ire);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = Boolean.valueOf(isSetAce()).compareTo(other.isSetAce());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetAce()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.ace, other.ace);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = Boolean.valueOf(isSetAse()).compareTo(other.isSetAse());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetAse()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.ase, other.ase);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = 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 {
      schemes.get(iprot.getScheme()).getScheme().read(iprot, this);
    }

    public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException {
      schemes.get(oprot.getScheme()).getScheme().write(oprot, this);
      }

    @Override
    public String toString() {
      StringBuilder sb = new StringBuilder("getUnicoreDataMovement_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("ire:");
      if (this.ire == null) {
        sb.append("null");
      } else {
        sb.append(this.ire);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("ace:");
      if (this.ace == null) {
        sb.append("null");
      } else {
        sb.append(this.ace);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("ase:");
      if (this.ase == null) {
        sb.append("null");
      } else {
        sb.append(this.ase);
      }
      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, 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 getUnicoreDataMovement_resultStandardSchemeFactory implements SchemeFactory {
      public getUnicoreDataMovement_resultStandardScheme getScheme() {
        return new getUnicoreDataMovement_resultStandardScheme();
      }
    }

    private static class getUnicoreDataMovement_resultStandardScheme extends StandardScheme<getUnicoreDataMovement_result> {

      public void read(org.apache.thrift.protocol.TProtocol iprot, getUnicoreDataMovement_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.appcatalog.computeresource.UnicoreDataMovement();
                struct.success.read(iprot);
                struct.setSuccessIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 1: // IRE
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.ire = new org.apache.airavata.model.error.InvalidRequestException();
                struct.ire.read(iprot);
                struct.setIreIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 2: // ACE
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.ace = new org.apache.airavata.model.error.AiravataClientException();
                struct.ace.read(iprot);
                struct.setAceIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 3: // ASE
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.ase = new org.apache.airavata.model.error.AiravataSystemException();
                struct.ase.read(iprot);
                struct.setAseIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 4: // 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, getUnicoreDataMovement_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.ire != null) {
          oprot.writeFieldBegin(IRE_FIELD_DESC);
          struct.ire.write(oprot);
          oprot.writeFieldEnd();
        }
        if (struct.ace != null) {
          oprot.writeFieldBegin(ACE_FIELD_DESC);
          struct.ace.write(oprot);
          oprot.writeFieldEnd();
        }
        if (struct.ase != null) {
          oprot.writeFieldBegin(ASE_FIELD_DESC);
          struct.ase.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 getUnicoreDataMovement_resultTupleSchemeFactory implements SchemeFactory {
      public getUnicoreDataMovement_resultTupleScheme getScheme() {
        return new getUnicoreDataMovement_resultTupleScheme();
      }
    }

    private static class getUnicoreDataMovement_resultTupleScheme extends TupleScheme<getUnicoreDataMovement_result> {

      @Override
      public void write(org.apache.thrift.protocol.TProtocol prot, getUnicoreDataMovement_result struct) throws org.apache.thrift.TException {
        TTupleProtocol oprot = (TTupleProtocol) prot;
        BitSet optionals = new BitSet();
        if (struct.isSetSuccess()) {
          optionals.set(0);
        }
        if (struct.isSetIre()) {
          optionals.set(1);
        }
        if (struct.isSetAce()) {
          optionals.set(2);
        }
        if (struct.isSetAse()) {
          optionals.set(3);
        }
        if (struct.isSetAe()) {
          optionals.set(4);
        }
        oprot.writeBitSet(optionals, 5);
        if (struct.isSetSuccess()) {
          struct.success.write(oprot);
        }
        if (struct.isSetIre()) {
          struct.ire.write(oprot);
        }
        if (struct.isSetAce()) {
          struct.ace.write(oprot);
        }
        if (struct.isSetAse()) {
          struct.ase.write(oprot);
        }
        if (struct.isSetAe()) {
          struct.ae.write(oprot);
        }
      }

      @Override
      public void read(org.apache.thrift.protocol.TProtocol prot, getUnicoreDataMovement_result struct) throws org.apache.thrift.TException {
        TTupleProtocol iprot = (TTupleProtocol) prot;
        BitSet incoming = iprot.readBitSet(5);
        if (incoming.get(0)) {
          struct.success = new org.apache.airavata.model.appcatalog.computeresource.UnicoreDataMovement();
          struct.success.read(iprot);
          struct.setSuccessIsSet(true);
        }
        if (incoming.get(1)) {
          struct.ire = new org.apache.airavata.model.error.InvalidRequestException();
          struct.ire.read(iprot);
          struct.setIreIsSet(true);
        }
        if (incoming.get(2)) {
          struct.ace = new org.apache.airavata.model.error.AiravataClientException();
          struct.ace.read(iprot);
          struct.setAceIsSet(true);
        }
        if (incoming.get(3)) {
          struct.ase = new org.apache.airavata.model.error.AiravataSystemException();
          struct.ase.read(iprot);
          struct.setAseIsSet(true);
        }
        if (incoming.get(4)) {
          struct.ae = new org.apache.airavata.model.error.AuthorizationException();
          struct.ae.read(iprot);
          struct.setAeIsSet(true);
        }
      }
    }

  }

  public static class addGridFTPDataMovementDetails_args implements org.apache.thrift.TBase<addGridFTPDataMovementDetails_args, addGridFTPDataMovementDetails_args._Fields>, java.io.Serializable, Cloneable, Comparable<addGridFTPDataMovementDetails_args>   {
    private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("addGridFTPDataMovementDetails_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 COMPUTE_RESOURCE_ID_FIELD_DESC = new org.apache.thrift.protocol.TField("computeResourceId", org.apache.thrift.protocol.TType.STRING, (short)2);
    private static final org.apache.thrift.protocol.TField PRIORITY_ORDER_FIELD_DESC = new org.apache.thrift.protocol.TField("priorityOrder", org.apache.thrift.protocol.TType.I32, (short)3);
    private static final org.apache.thrift.protocol.TField GRID_FTPDATA_MOVEMENT_FIELD_DESC = new org.apache.thrift.protocol.TField("gridFTPDataMovement", org.apache.thrift.protocol.TType.STRUCT, (short)4);

    private static final Map<Class<? extends IScheme>, SchemeFactory> schemes = new HashMap<Class<? extends IScheme>, SchemeFactory>();
    static {
      schemes.put(StandardScheme.class, new addGridFTPDataMovementDetails_argsStandardSchemeFactory());
      schemes.put(TupleScheme.class, new addGridFTPDataMovementDetails_argsTupleSchemeFactory());
    }

    public org.apache.airavata.model.security.AuthzToken authzToken; // required
    public String computeResourceId; // required
    public int priorityOrder; // required
    public org.apache.airavata.model.appcatalog.computeresource.GridFTPDataMovement gridFTPDataMovement; // required

    /** 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"),
      COMPUTE_RESOURCE_ID((short)2, "computeResourceId"),
      PRIORITY_ORDER((short)3, "priorityOrder"),
      GRID_FTPDATA_MOVEMENT((short)4, "gridFTPDataMovement");

      private static final Map<String, _Fields> byName = new HashMap<String, _Fields>();

      static {
        for (_Fields field : EnumSet.allOf(_Fields.class)) {
          byName.put(field.getFieldName(), field);
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, or null if its not found.
       */
      public static _Fields findByThriftId(int fieldId) {
        switch(fieldId) {
          case 1: // AUTHZ_TOKEN
            return AUTHZ_TOKEN;
          case 2: // COMPUTE_RESOURCE_ID
            return COMPUTE_RESOURCE_ID;
          case 3: // PRIORITY_ORDER
            return PRIORITY_ORDER;
          case 4: // GRID_FTPDATA_MOVEMENT
            return GRID_FTPDATA_MOVEMENT;
          default:
            return null;
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, throwing an exception
       * if it is not found.
       */
      public static _Fields findByThriftIdOrThrow(int fieldId) {
        _Fields fields = findByThriftId(fieldId);
        if (fields == null) throw new IllegalArgumentException("Field " + fieldId + " doesn't exist!");
        return fields;
      }

      /**
       * Find the _Fields constant that matches name, or null if its not found.
       */
      public static _Fields findByName(String name) {
        return byName.get(name);
      }

      private final short _thriftId;
      private final String _fieldName;

      _Fields(short thriftId, String fieldName) {
        _thriftId = thriftId;
        _fieldName = fieldName;
      }

      public short getThriftFieldId() {
        return _thriftId;
      }

      public String getFieldName() {
        return _fieldName;
      }
    }

    // isset id assignments
    private static final int __PRIORITYORDER_ISSET_ID = 0;
    private byte __isset_bitfield = 0;
    public static final Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
    static {
      Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new EnumMap<_Fields, org.apache.thrift.meta_data.FieldMetaData>(_Fields.class);
      tmpMap.put(_Fields.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.COMPUTE_RESOURCE_ID, new org.apache.thrift.meta_data.FieldMetaData("computeResourceId", org.apache.thrift.TFieldRequirementType.REQUIRED, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING)));
      tmpMap.put(_Fields.PRIORITY_ORDER, new org.apache.thrift.meta_data.FieldMetaData("priorityOrder", org.apache.thrift.TFieldRequirementType.REQUIRED, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.I32)));
      tmpMap.put(_Fields.GRID_FTPDATA_MOVEMENT, new org.apache.thrift.meta_data.FieldMetaData("gridFTPDataMovement", org.apache.thrift.TFieldRequirementType.REQUIRED, 
          new org.apache.thrift.meta_data.StructMetaData(org.apache.thrift.protocol.TType.STRUCT, org.apache.airavata.model.appcatalog.computeresource.GridFTPDataMovement.class)));
      metaDataMap = Collections.unmodifiableMap(tmpMap);
      org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(addGridFTPDataMovementDetails_args.class, metaDataMap);
    }

    public addGridFTPDataMovementDetails_args() {
    }

    public addGridFTPDataMovementDetails_args(
      org.apache.airavata.model.security.AuthzToken authzToken,
      String computeResourceId,
      int priorityOrder,
      org.apache.airavata.model.appcatalog.computeresource.GridFTPDataMovement gridFTPDataMovement)
    {
      this();
      this.authzToken = authzToken;
      this.computeResourceId = computeResourceId;
      this.priorityOrder = priorityOrder;
      setPriorityOrderIsSet(true);
      this.gridFTPDataMovement = gridFTPDataMovement;
    }

    /**
     * Performs a deep copy on <i>other</i>.
     */
    public addGridFTPDataMovementDetails_args(addGridFTPDataMovementDetails_args other) {
      __isset_bitfield = other.__isset_bitfield;
      if (other.isSetAuthzToken()) {
        this.authzToken = new org.apache.airavata.model.security.AuthzToken(other.authzToken);
      }
      if (other.isSetComputeResourceId()) {
        this.computeResourceId = other.computeResourceId;
      }
      this.priorityOrder = other.priorityOrder;
      if (other.isSetGridFTPDataMovement()) {
        this.gridFTPDataMovement = new org.apache.airavata.model.appcatalog.computeresource.GridFTPDataMovement(other.gridFTPDataMovement);
      }
    }

    public addGridFTPDataMovementDetails_args deepCopy() {
      return new addGridFTPDataMovementDetails_args(this);
    }

    @Override
    public void clear() {
      this.authzToken = null;
      this.computeResourceId = null;
      setPriorityOrderIsSet(false);
      this.priorityOrder = 0;
      this.gridFTPDataMovement = null;
    }

    public org.apache.airavata.model.security.AuthzToken getAuthzToken() {
      return this.authzToken;
    }

    public addGridFTPDataMovementDetails_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 String getComputeResourceId() {
      return this.computeResourceId;
    }

    public addGridFTPDataMovementDetails_args setComputeResourceId(String computeResourceId) {
      this.computeResourceId = computeResourceId;
      return this;
    }

    public void unsetComputeResourceId() {
      this.computeResourceId = null;
    }

    /** Returns true if field computeResourceId is set (has been assigned a value) and false otherwise */
    public boolean isSetComputeResourceId() {
      return this.computeResourceId != null;
    }

    public void setComputeResourceIdIsSet(boolean value) {
      if (!value) {
        this.computeResourceId = null;
      }
    }

    public int getPriorityOrder() {
      return this.priorityOrder;
    }

    public addGridFTPDataMovementDetails_args setPriorityOrder(int priorityOrder) {
      this.priorityOrder = priorityOrder;
      setPriorityOrderIsSet(true);
      return this;
    }

    public void unsetPriorityOrder() {
      __isset_bitfield = EncodingUtils.clearBit(__isset_bitfield, __PRIORITYORDER_ISSET_ID);
    }

    /** Returns true if field priorityOrder is set (has been assigned a value) and false otherwise */
    public boolean isSetPriorityOrder() {
      return EncodingUtils.testBit(__isset_bitfield, __PRIORITYORDER_ISSET_ID);
    }

    public void setPriorityOrderIsSet(boolean value) {
      __isset_bitfield = EncodingUtils.setBit(__isset_bitfield, __PRIORITYORDER_ISSET_ID, value);
    }

    public org.apache.airavata.model.appcatalog.computeresource.GridFTPDataMovement getGridFTPDataMovement() {
      return this.gridFTPDataMovement;
    }

    public addGridFTPDataMovementDetails_args setGridFTPDataMovement(org.apache.airavata.model.appcatalog.computeresource.GridFTPDataMovement gridFTPDataMovement) {
      this.gridFTPDataMovement = gridFTPDataMovement;
      return this;
    }

    public void unsetGridFTPDataMovement() {
      this.gridFTPDataMovement = null;
    }

    /** Returns true if field gridFTPDataMovement is set (has been assigned a value) and false otherwise */
    public boolean isSetGridFTPDataMovement() {
      return this.gridFTPDataMovement != null;
    }

    public void setGridFTPDataMovementIsSet(boolean value) {
      if (!value) {
        this.gridFTPDataMovement = null;
      }
    }

    public void setFieldValue(_Fields field, Object value) {
      switch (field) {
      case AUTHZ_TOKEN:
        if (value == null) {
          unsetAuthzToken();
        } else {
          setAuthzToken((org.apache.airavata.model.security.AuthzToken)value);
        }
        break;

      case COMPUTE_RESOURCE_ID:
        if (value == null) {
          unsetComputeResourceId();
        } else {
          setComputeResourceId((String)value);
        }
        break;

      case PRIORITY_ORDER:
        if (value == null) {
          unsetPriorityOrder();
        } else {
          setPriorityOrder((Integer)value);
        }
        break;

      case GRID_FTPDATA_MOVEMENT:
        if (value == null) {
          unsetGridFTPDataMovement();
        } else {
          setGridFTPDataMovement((org.apache.airavata.model.appcatalog.computeresource.GridFTPDataMovement)value);
        }
        break;

      }
    }

    public Object getFieldValue(_Fields field) {
      switch (field) {
      case AUTHZ_TOKEN:
        return getAuthzToken();

      case COMPUTE_RESOURCE_ID:
        return getComputeResourceId();

      case PRIORITY_ORDER:
        return Integer.valueOf(getPriorityOrder());

      case GRID_FTPDATA_MOVEMENT:
        return getGridFTPDataMovement();

      }
      throw new IllegalStateException();
    }

    /** Returns true if field corresponding to fieldID is set (has been assigned a value) and false otherwise */
    public boolean isSet(_Fields field) {
      if (field == null) {
        throw new IllegalArgumentException();
      }

      switch (field) {
      case AUTHZ_TOKEN:
        return isSetAuthzToken();
      case COMPUTE_RESOURCE_ID:
        return isSetComputeResourceId();
      case PRIORITY_ORDER:
        return isSetPriorityOrder();
      case GRID_FTPDATA_MOVEMENT:
        return isSetGridFTPDataMovement();
      }
      throw new IllegalStateException();
    }

    @Override
    public boolean equals(Object that) {
      if (that == null)
        return false;
      if (that instanceof addGridFTPDataMovementDetails_args)
        return this.equals((addGridFTPDataMovementDetails_args)that);
      return false;
    }

    public boolean equals(addGridFTPDataMovementDetails_args that) {
      if (that == null)
        return false;

      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_computeResourceId = true && this.isSetComputeResourceId();
      boolean that_present_computeResourceId = true && that.isSetComputeResourceId();
      if (this_present_computeResourceId || that_present_computeResourceId) {
        if (!(this_present_computeResourceId && that_present_computeResourceId))
          return false;
        if (!this.computeResourceId.equals(that.computeResourceId))
          return false;
      }

      boolean this_present_priorityOrder = true;
      boolean that_present_priorityOrder = true;
      if (this_present_priorityOrder || that_present_priorityOrder) {
        if (!(this_present_priorityOrder && that_present_priorityOrder))
          return false;
        if (this.priorityOrder != that.priorityOrder)
          return false;
      }

      boolean this_present_gridFTPDataMovement = true && this.isSetGridFTPDataMovement();
      boolean that_present_gridFTPDataMovement = true && that.isSetGridFTPDataMovement();
      if (this_present_gridFTPDataMovement || that_present_gridFTPDataMovement) {
        if (!(this_present_gridFTPDataMovement && that_present_gridFTPDataMovement))
          return false;
        if (!this.gridFTPDataMovement.equals(that.gridFTPDataMovement))
          return false;
      }

      return true;
    }

    @Override
    public int hashCode() {
      List<Object> list = new ArrayList<Object>();

      boolean present_authzToken = true && (isSetAuthzToken());
      list.add(present_authzToken);
      if (present_authzToken)
        list.add(authzToken);

      boolean present_computeResourceId = true && (isSetComputeResourceId());
      list.add(present_computeResourceId);
      if (present_computeResourceId)
        list.add(computeResourceId);

      boolean present_priorityOrder = true;
      list.add(present_priorityOrder);
      if (present_priorityOrder)
        list.add(priorityOrder);

      boolean present_gridFTPDataMovement = true && (isSetGridFTPDataMovement());
      list.add(present_gridFTPDataMovement);
      if (present_gridFTPDataMovement)
        list.add(gridFTPDataMovement);

      return list.hashCode();
    }

    @Override
    public int compareTo(addGridFTPDataMovementDetails_args other) {
      if (!getClass().equals(other.getClass())) {
        return getClass().getName().compareTo(other.getClass().getName());
      }

      int lastComparison = 0;

      lastComparison = 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 = Boolean.valueOf(isSetComputeResourceId()).compareTo(other.isSetComputeResourceId());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetComputeResourceId()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.computeResourceId, other.computeResourceId);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = Boolean.valueOf(isSetPriorityOrder()).compareTo(other.isSetPriorityOrder());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetPriorityOrder()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.priorityOrder, other.priorityOrder);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = Boolean.valueOf(isSetGridFTPDataMovement()).compareTo(other.isSetGridFTPDataMovement());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetGridFTPDataMovement()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.gridFTPDataMovement, other.gridFTPDataMovement);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      return 0;
    }

    public _Fields fieldForId(int fieldId) {
      return _Fields.findByThriftId(fieldId);
    }

    public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
      schemes.get(iprot.getScheme()).getScheme().read(iprot, this);
    }

    public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException {
      schemes.get(oprot.getScheme()).getScheme().write(oprot, this);
    }

    @Override
    public String toString() {
      StringBuilder sb = new StringBuilder("addGridFTPDataMovementDetails_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("computeResourceId:");
      if (this.computeResourceId == null) {
        sb.append("null");
      } else {
        sb.append(this.computeResourceId);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("priorityOrder:");
      sb.append(this.priorityOrder);
      first = false;
      if (!first) sb.append(", ");
      sb.append("gridFTPDataMovement:");
      if (this.gridFTPDataMovement == null) {
        sb.append("null");
      } else {
        sb.append(this.gridFTPDataMovement);
      }
      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 (computeResourceId == null) {
        throw new org.apache.thrift.protocol.TProtocolException("Required field 'computeResourceId' was not present! Struct: " + toString());
      }
      // alas, we cannot check 'priorityOrder' because it's a primitive and you chose the non-beans generator.
      if (gridFTPDataMovement == null) {
        throw new org.apache.thrift.protocol.TProtocolException("Required field 'gridFTPDataMovement' was not present! Struct: " + toString());
      }
      // check for sub-struct validity
      if (authzToken != null) {
        authzToken.validate();
      }
      if (gridFTPDataMovement != null) {
        gridFTPDataMovement.validate();
      }
    }

    private void writeObject(java.io.ObjectOutputStream out) throws java.io.IOException {
      try {
        write(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(out)));
      } catch (org.apache.thrift.TException te) {
        throw new java.io.IOException(te);
      }
    }

    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, ClassNotFoundException {
      try {
        // 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 addGridFTPDataMovementDetails_argsStandardSchemeFactory implements SchemeFactory {
      public addGridFTPDataMovementDetails_argsStandardScheme getScheme() {
        return new addGridFTPDataMovementDetails_argsStandardScheme();
      }
    }

    private static class addGridFTPDataMovementDetails_argsStandardScheme extends StandardScheme<addGridFTPDataMovementDetails_args> {

      public void read(org.apache.thrift.protocol.TProtocol iprot, addGridFTPDataMovementDetails_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: // COMPUTE_RESOURCE_ID
              if (schemeField.type == org.apache.thrift.protocol.TType.STRING) {
                struct.computeResourceId = iprot.readString();
                struct.setComputeResourceIdIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 3: // PRIORITY_ORDER
              if (schemeField.type == org.apache.thrift.protocol.TType.I32) {
                struct.priorityOrder = iprot.readI32();
                struct.setPriorityOrderIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 4: // GRID_FTPDATA_MOVEMENT
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.gridFTPDataMovement = new org.apache.airavata.model.appcatalog.computeresource.GridFTPDataMovement();
                struct.gridFTPDataMovement.read(iprot);
                struct.setGridFTPDataMovementIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            default:
              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
          }
          iprot.readFieldEnd();
        }
        iprot.readStructEnd();

        // check for required fields of primitive type, which can't be checked in the validate method
        if (!struct.isSetPriorityOrder()) {
          throw new org.apache.thrift.protocol.TProtocolException("Required field 'priorityOrder' was not found in serialized data! Struct: " + toString());
        }
        struct.validate();
      }

      public void write(org.apache.thrift.protocol.TProtocol oprot, addGridFTPDataMovementDetails_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.computeResourceId != null) {
          oprot.writeFieldBegin(COMPUTE_RESOURCE_ID_FIELD_DESC);
          oprot.writeString(struct.computeResourceId);
          oprot.writeFieldEnd();
        }
        oprot.writeFieldBegin(PRIORITY_ORDER_FIELD_DESC);
        oprot.writeI32(struct.priorityOrder);
        oprot.writeFieldEnd();
        if (struct.gridFTPDataMovement != null) {
          oprot.writeFieldBegin(GRID_FTPDATA_MOVEMENT_FIELD_DESC);
          struct.gridFTPDataMovement.write(oprot);
          oprot.writeFieldEnd();
        }
        oprot.writeFieldStop();
        oprot.writeStructEnd();
      }

    }

    private static class addGridFTPDataMovementDetails_argsTupleSchemeFactory implements SchemeFactory {
      public addGridFTPDataMovementDetails_argsTupleScheme getScheme() {
        return new addGridFTPDataMovementDetails_argsTupleScheme();
      }
    }

    private static class addGridFTPDataMovementDetails_argsTupleScheme extends TupleScheme<addGridFTPDataMovementDetails_args> {

      @Override
      public void write(org.apache.thrift.protocol.TProtocol prot, addGridFTPDataMovementDetails_args struct) throws org.apache.thrift.TException {
        TTupleProtocol oprot = (TTupleProtocol) prot;
        struct.authzToken.write(oprot);
        oprot.writeString(struct.computeResourceId);
        oprot.writeI32(struct.priorityOrder);
        struct.gridFTPDataMovement.write(oprot);
      }

      @Override
      public void read(org.apache.thrift.protocol.TProtocol prot, addGridFTPDataMovementDetails_args struct) throws org.apache.thrift.TException {
        TTupleProtocol iprot = (TTupleProtocol) prot;
        struct.authzToken = new org.apache.airavata.model.security.AuthzToken();
        struct.authzToken.read(iprot);
        struct.setAuthzTokenIsSet(true);
        struct.computeResourceId = iprot.readString();
        struct.setComputeResourceIdIsSet(true);
        struct.priorityOrder = iprot.readI32();
        struct.setPriorityOrderIsSet(true);
        struct.gridFTPDataMovement = new org.apache.airavata.model.appcatalog.computeresource.GridFTPDataMovement();
        struct.gridFTPDataMovement.read(iprot);
        struct.setGridFTPDataMovementIsSet(true);
      }
    }

  }

  public static class addGridFTPDataMovementDetails_result implements org.apache.thrift.TBase<addGridFTPDataMovementDetails_result, addGridFTPDataMovementDetails_result._Fields>, java.io.Serializable, Cloneable, Comparable<addGridFTPDataMovementDetails_result>   {
    private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("addGridFTPDataMovementDetails_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 IRE_FIELD_DESC = new org.apache.thrift.protocol.TField("ire", org.apache.thrift.protocol.TType.STRUCT, (short)1);
    private static final org.apache.thrift.protocol.TField ACE_FIELD_DESC = new org.apache.thrift.protocol.TField("ace", org.apache.thrift.protocol.TType.STRUCT, (short)2);
    private static final org.apache.thrift.protocol.TField ASE_FIELD_DESC = new org.apache.thrift.protocol.TField("ase", org.apache.thrift.protocol.TType.STRUCT, (short)3);
    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)4);

    private static final Map<Class<? extends IScheme>, SchemeFactory> schemes = new HashMap<Class<? extends IScheme>, SchemeFactory>();
    static {
      schemes.put(StandardScheme.class, new addGridFTPDataMovementDetails_resultStandardSchemeFactory());
      schemes.put(TupleScheme.class, new addGridFTPDataMovementDetails_resultTupleSchemeFactory());
    }

    public String success; // required
    public org.apache.airavata.model.error.InvalidRequestException ire; // required
    public org.apache.airavata.model.error.AiravataClientException ace; // required
    public org.apache.airavata.model.error.AiravataSystemException ase; // 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"),
      IRE((short)1, "ire"),
      ACE((short)2, "ace"),
      ASE((short)3, "ase"),
      AE((short)4, "ae");

      private static final Map<String, _Fields> byName = new HashMap<String, _Fields>();

      static {
        for (_Fields field : EnumSet.allOf(_Fields.class)) {
          byName.put(field.getFieldName(), field);
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, or null if its not found.
       */
      public static _Fields findByThriftId(int fieldId) {
        switch(fieldId) {
          case 0: // SUCCESS
            return SUCCESS;
          case 1: // IRE
            return IRE;
          case 2: // ACE
            return ACE;
          case 3: // ASE
            return ASE;
          case 4: // 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 IllegalArgumentException("Field " + fieldId + " doesn't exist!");
        return fields;
      }

      /**
       * Find the _Fields constant that matches name, or null if its not found.
       */
      public static _Fields findByName(String name) {
        return byName.get(name);
      }

      private final short _thriftId;
      private final String _fieldName;

      _Fields(short thriftId, String fieldName) {
        _thriftId = thriftId;
        _fieldName = fieldName;
      }

      public short getThriftFieldId() {
        return _thriftId;
      }

      public String getFieldName() {
        return _fieldName;
      }
    }

    // isset id assignments
    public static final Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
    static {
      Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new EnumMap<_Fields, org.apache.thrift.meta_data.FieldMetaData>(_Fields.class);
      tmpMap.put(_Fields.SUCCESS, new org.apache.thrift.meta_data.FieldMetaData("success", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING)));
      tmpMap.put(_Fields.IRE, new org.apache.thrift.meta_data.FieldMetaData("ire", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRUCT)));
      tmpMap.put(_Fields.ACE, new org.apache.thrift.meta_data.FieldMetaData("ace", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRUCT)));
      tmpMap.put(_Fields.ASE, new org.apache.thrift.meta_data.FieldMetaData("ase", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRUCT)));
      tmpMap.put(_Fields.AE, new org.apache.thrift.meta_data.FieldMetaData("ae", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRUCT)));
      metaDataMap = Collections.unmodifiableMap(tmpMap);
      org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(addGridFTPDataMovementDetails_result.class, metaDataMap);
    }

    public addGridFTPDataMovementDetails_result() {
    }

    public addGridFTPDataMovementDetails_result(
      String success,
      org.apache.airavata.model.error.InvalidRequestException ire,
      org.apache.airavata.model.error.AiravataClientException ace,
      org.apache.airavata.model.error.AiravataSystemException ase,
      org.apache.airavata.model.error.AuthorizationException ae)
    {
      this();
      this.success = success;
      this.ire = ire;
      this.ace = ace;
      this.ase = ase;
      this.ae = ae;
    }

    /**
     * Performs a deep copy on <i>other</i>.
     */
    public addGridFTPDataMovementDetails_result(addGridFTPDataMovementDetails_result other) {
      if (other.isSetSuccess()) {
        this.success = other.success;
      }
      if (other.isSetIre()) {
        this.ire = new org.apache.airavata.model.error.InvalidRequestException(other.ire);
      }
      if (other.isSetAce()) {
        this.ace = new org.apache.airavata.model.error.AiravataClientException(other.ace);
      }
      if (other.isSetAse()) {
        this.ase = new org.apache.airavata.model.error.AiravataSystemException(other.ase);
      }
      if (other.isSetAe()) {
        this.ae = new org.apache.airavata.model.error.AuthorizationException(other.ae);
      }
    }

    public addGridFTPDataMovementDetails_result deepCopy() {
      return new addGridFTPDataMovementDetails_result(this);
    }

    @Override
    public void clear() {
      this.success = null;
      this.ire = null;
      this.ace = null;
      this.ase = null;
      this.ae = null;
    }

    public String getSuccess() {
      return this.success;
    }

    public addGridFTPDataMovementDetails_result setSuccess(String success) {
      this.success = success;
      return this;
    }

    public void unsetSuccess() {
      this.success = null;
    }

    /** Returns true if field success is set (has been assigned a value) and false otherwise */
    public boolean isSetSuccess() {
      return this.success != null;
    }

    public void setSuccessIsSet(boolean value) {
      if (!value) {
        this.success = null;
      }
    }

    public org.apache.airavata.model.error.InvalidRequestException getIre() {
      return this.ire;
    }

    public addGridFTPDataMovementDetails_result setIre(org.apache.airavata.model.error.InvalidRequestException ire) {
      this.ire = ire;
      return this;
    }

    public void unsetIre() {
      this.ire = null;
    }

    /** Returns true if field ire is set (has been assigned a value) and false otherwise */
    public boolean isSetIre() {
      return this.ire != null;
    }

    public void setIreIsSet(boolean value) {
      if (!value) {
        this.ire = null;
      }
    }

    public org.apache.airavata.model.error.AiravataClientException getAce() {
      return this.ace;
    }

    public addGridFTPDataMovementDetails_result setAce(org.apache.airavata.model.error.AiravataClientException ace) {
      this.ace = ace;
      return this;
    }

    public void unsetAce() {
      this.ace = null;
    }

    /** Returns true if field ace is set (has been assigned a value) and false otherwise */
    public boolean isSetAce() {
      return this.ace != null;
    }

    public void setAceIsSet(boolean value) {
      if (!value) {
        this.ace = null;
      }
    }

    public org.apache.airavata.model.error.AiravataSystemException getAse() {
      return this.ase;
    }

    public addGridFTPDataMovementDetails_result setAse(org.apache.airavata.model.error.AiravataSystemException ase) {
      this.ase = ase;
      return this;
    }

    public void unsetAse() {
      this.ase = null;
    }

    /** Returns true if field ase is set (has been assigned a value) and false otherwise */
    public boolean isSetAse() {
      return this.ase != null;
    }

    public void setAseIsSet(boolean value) {
      if (!value) {
        this.ase = null;
      }
    }

    public org.apache.airavata.model.error.AuthorizationException getAe() {
      return this.ae;
    }

    public addGridFTPDataMovementDetails_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, Object value) {
      switch (field) {
      case SUCCESS:
        if (value == null) {
          unsetSuccess();
        } else {
          setSuccess((String)value);
        }
        break;

      case IRE:
        if (value == null) {
          unsetIre();
        } else {
          setIre((org.apache.airavata.model.error.InvalidRequestException)value);
        }
        break;

      case ACE:
        if (value == null) {
          unsetAce();
        } else {
          setAce((org.apache.airavata.model.error.AiravataClientException)value);
        }
        break;

      case ASE:
        if (value == null) {
          unsetAse();
        } else {
          setAse((org.apache.airavata.model.error.AiravataSystemException)value);
        }
        break;

      case AE:
        if (value == null) {
          unsetAe();
        } else {
          setAe((org.apache.airavata.model.error.AuthorizationException)value);
        }
        break;

      }
    }

    public Object getFieldValue(_Fields field) {
      switch (field) {
      case SUCCESS:
        return getSuccess();

      case IRE:
        return getIre();

      case ACE:
        return getAce();

      case ASE:
        return getAse();

      case AE:
        return getAe();

      }
      throw new IllegalStateException();
    }

    /** Returns true if field corresponding to fieldID is set (has been assigned a value) and false otherwise */
    public boolean isSet(_Fields field) {
      if (field == null) {
        throw new IllegalArgumentException();
      }

      switch (field) {
      case SUCCESS:
        return isSetSuccess();
      case IRE:
        return isSetIre();
      case ACE:
        return isSetAce();
      case ASE:
        return isSetAse();
      case AE:
        return isSetAe();
      }
      throw new IllegalStateException();
    }

    @Override
    public boolean equals(Object that) {
      if (that == null)
        return false;
      if (that instanceof addGridFTPDataMovementDetails_result)
        return this.equals((addGridFTPDataMovementDetails_result)that);
      return false;
    }

    public boolean equals(addGridFTPDataMovementDetails_result that) {
      if (that == null)
        return false;

      boolean this_present_success = true && this.isSetSuccess();
      boolean that_present_success = true && that.isSetSuccess();
      if (this_present_success || that_present_success) {
        if (!(this_present_success && that_present_success))
          return false;
        if (!this.success.equals(that.success))
          return false;
      }

      boolean this_present_ire = true && this.isSetIre();
      boolean that_present_ire = true && that.isSetIre();
      if (this_present_ire || that_present_ire) {
        if (!(this_present_ire && that_present_ire))
          return false;
        if (!this.ire.equals(that.ire))
          return false;
      }

      boolean this_present_ace = true && this.isSetAce();
      boolean that_present_ace = true && that.isSetAce();
      if (this_present_ace || that_present_ace) {
        if (!(this_present_ace && that_present_ace))
          return false;
        if (!this.ace.equals(that.ace))
          return false;
      }

      boolean this_present_ase = true && this.isSetAse();
      boolean that_present_ase = true && that.isSetAse();
      if (this_present_ase || that_present_ase) {
        if (!(this_present_ase && that_present_ase))
          return false;
        if (!this.ase.equals(that.ase))
          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() {
      List<Object> list = new ArrayList<Object>();

      boolean present_success = true && (isSetSuccess());
      list.add(present_success);
      if (present_success)
        list.add(success);

      boolean present_ire = true && (isSetIre());
      list.add(present_ire);
      if (present_ire)
        list.add(ire);

      boolean present_ace = true && (isSetAce());
      list.add(present_ace);
      if (present_ace)
        list.add(ace);

      boolean present_ase = true && (isSetAse());
      list.add(present_ase);
      if (present_ase)
        list.add(ase);

      boolean present_ae = true && (isSetAe());
      list.add(present_ae);
      if (present_ae)
        list.add(ae);

      return list.hashCode();
    }

    @Override
    public int compareTo(addGridFTPDataMovementDetails_result other) {
      if (!getClass().equals(other.getClass())) {
        return getClass().getName().compareTo(other.getClass().getName());
      }

      int lastComparison = 0;

      lastComparison = Boolean.valueOf(isSetSuccess()).compareTo(other.isSetSuccess());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetSuccess()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.success, other.success);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = Boolean.valueOf(isSetIre()).compareTo(other.isSetIre());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetIre()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.ire, other.ire);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = Boolean.valueOf(isSetAce()).compareTo(other.isSetAce());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetAce()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.ace, other.ace);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = Boolean.valueOf(isSetAse()).compareTo(other.isSetAse());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetAse()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.ase, other.ase);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = 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 {
      schemes.get(iprot.getScheme()).getScheme().read(iprot, this);
    }

    public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException {
      schemes.get(oprot.getScheme()).getScheme().write(oprot, this);
      }

    @Override
    public String toString() {
      StringBuilder sb = new StringBuilder("addGridFTPDataMovementDetails_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("ire:");
      if (this.ire == null) {
        sb.append("null");
      } else {
        sb.append(this.ire);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("ace:");
      if (this.ace == null) {
        sb.append("null");
      } else {
        sb.append(this.ace);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("ase:");
      if (this.ase == null) {
        sb.append("null");
      } else {
        sb.append(this.ase);
      }
      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, 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 addGridFTPDataMovementDetails_resultStandardSchemeFactory implements SchemeFactory {
      public addGridFTPDataMovementDetails_resultStandardScheme getScheme() {
        return new addGridFTPDataMovementDetails_resultStandardScheme();
      }
    }

    private static class addGridFTPDataMovementDetails_resultStandardScheme extends StandardScheme<addGridFTPDataMovementDetails_result> {

      public void read(org.apache.thrift.protocol.TProtocol iprot, addGridFTPDataMovementDetails_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: // IRE
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.ire = new org.apache.airavata.model.error.InvalidRequestException();
                struct.ire.read(iprot);
                struct.setIreIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 2: // ACE
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.ace = new org.apache.airavata.model.error.AiravataClientException();
                struct.ace.read(iprot);
                struct.setAceIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 3: // ASE
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.ase = new org.apache.airavata.model.error.AiravataSystemException();
                struct.ase.read(iprot);
                struct.setAseIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 4: // 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, addGridFTPDataMovementDetails_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.ire != null) {
          oprot.writeFieldBegin(IRE_FIELD_DESC);
          struct.ire.write(oprot);
          oprot.writeFieldEnd();
        }
        if (struct.ace != null) {
          oprot.writeFieldBegin(ACE_FIELD_DESC);
          struct.ace.write(oprot);
          oprot.writeFieldEnd();
        }
        if (struct.ase != null) {
          oprot.writeFieldBegin(ASE_FIELD_DESC);
          struct.ase.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 addGridFTPDataMovementDetails_resultTupleSchemeFactory implements SchemeFactory {
      public addGridFTPDataMovementDetails_resultTupleScheme getScheme() {
        return new addGridFTPDataMovementDetails_resultTupleScheme();
      }
    }

    private static class addGridFTPDataMovementDetails_resultTupleScheme extends TupleScheme<addGridFTPDataMovementDetails_result> {

      @Override
      public void write(org.apache.thrift.protocol.TProtocol prot, addGridFTPDataMovementDetails_result struct) throws org.apache.thrift.TException {
        TTupleProtocol oprot = (TTupleProtocol) prot;
        BitSet optionals = new BitSet();
        if (struct.isSetSuccess()) {
          optionals.set(0);
        }
        if (struct.isSetIre()) {
          optionals.set(1);
        }
        if (struct.isSetAce()) {
          optionals.set(2);
        }
        if (struct.isSetAse()) {
          optionals.set(3);
        }
        if (struct.isSetAe()) {
          optionals.set(4);
        }
        oprot.writeBitSet(optionals, 5);
        if (struct.isSetSuccess()) {
          oprot.writeString(struct.success);
        }
        if (struct.isSetIre()) {
          struct.ire.write(oprot);
        }
        if (struct.isSetAce()) {
          struct.ace.write(oprot);
        }
        if (struct.isSetAse()) {
          struct.ase.write(oprot);
        }
        if (struct.isSetAe()) {
          struct.ae.write(oprot);
        }
      }

      @Override
      public void read(org.apache.thrift.protocol.TProtocol prot, addGridFTPDataMovementDetails_result struct) throws org.apache.thrift.TException {
        TTupleProtocol iprot = (TTupleProtocol) prot;
        BitSet incoming = iprot.readBitSet(5);
        if (incoming.get(0)) {
          struct.success = iprot.readString();
          struct.setSuccessIsSet(true);
        }
        if (incoming.get(1)) {
          struct.ire = new org.apache.airavata.model.error.InvalidRequestException();
          struct.ire.read(iprot);
          struct.setIreIsSet(true);
        }
        if (incoming.get(2)) {
          struct.ace = new org.apache.airavata.model.error.AiravataClientException();
          struct.ace.read(iprot);
          struct.setAceIsSet(true);
        }
        if (incoming.get(3)) {
          struct.ase = new org.apache.airavata.model.error.AiravataSystemException();
          struct.ase.read(iprot);
          struct.setAseIsSet(true);
        }
        if (incoming.get(4)) {
          struct.ae = new org.apache.airavata.model.error.AuthorizationException();
          struct.ae.read(iprot);
          struct.setAeIsSet(true);
        }
      }
    }

  }

  public static class updateGridFTPDataMovementDetails_args implements org.apache.thrift.TBase<updateGridFTPDataMovementDetails_args, updateGridFTPDataMovementDetails_args._Fields>, java.io.Serializable, Cloneable, Comparable<updateGridFTPDataMovementDetails_args>   {
    private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("updateGridFTPDataMovementDetails_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 DATA_MOVEMENT_INTERFACE_ID_FIELD_DESC = new org.apache.thrift.protocol.TField("dataMovementInterfaceId", org.apache.thrift.protocol.TType.STRING, (short)2);
    private static final org.apache.thrift.protocol.TField GRID_FTPDATA_MOVEMENT_FIELD_DESC = new org.apache.thrift.protocol.TField("gridFTPDataMovement", org.apache.thrift.protocol.TType.STRUCT, (short)3);

    private static final Map<Class<? extends IScheme>, SchemeFactory> schemes = new HashMap<Class<? extends IScheme>, SchemeFactory>();
    static {
      schemes.put(StandardScheme.class, new updateGridFTPDataMovementDetails_argsStandardSchemeFactory());
      schemes.put(TupleScheme.class, new updateGridFTPDataMovementDetails_argsTupleSchemeFactory());
    }

    public org.apache.airavata.model.security.AuthzToken authzToken; // required
    public String dataMovementInterfaceId; // required
    public org.apache.airavata.model.appcatalog.computeresource.GridFTPDataMovement gridFTPDataMovement; // required

    /** 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"),
      DATA_MOVEMENT_INTERFACE_ID((short)2, "dataMovementInterfaceId"),
      GRID_FTPDATA_MOVEMENT((short)3, "gridFTPDataMovement");

      private static final Map<String, _Fields> byName = new HashMap<String, _Fields>();

      static {
        for (_Fields field : EnumSet.allOf(_Fields.class)) {
          byName.put(field.getFieldName(), field);
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, or null if its not found.
       */
      public static _Fields findByThriftId(int fieldId) {
        switch(fieldId) {
          case 1: // AUTHZ_TOKEN
            return AUTHZ_TOKEN;
          case 2: // DATA_MOVEMENT_INTERFACE_ID
            return DATA_MOVEMENT_INTERFACE_ID;
          case 3: // GRID_FTPDATA_MOVEMENT
            return GRID_FTPDATA_MOVEMENT;
          default:
            return null;
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, throwing an exception
       * if it is not found.
       */
      public static _Fields findByThriftIdOrThrow(int fieldId) {
        _Fields fields = findByThriftId(fieldId);
        if (fields == null) throw new IllegalArgumentException("Field " + fieldId + " doesn't exist!");
        return fields;
      }

      /**
       * Find the _Fields constant that matches name, or null if its not found.
       */
      public static _Fields findByName(String name) {
        return byName.get(name);
      }

      private final short _thriftId;
      private final String _fieldName;

      _Fields(short thriftId, String fieldName) {
        _thriftId = thriftId;
        _fieldName = fieldName;
      }

      public short getThriftFieldId() {
        return _thriftId;
      }

      public String getFieldName() {
        return _fieldName;
      }
    }

    // isset id assignments
    public static final Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
    static {
      Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new EnumMap<_Fields, org.apache.thrift.meta_data.FieldMetaData>(_Fields.class);
      tmpMap.put(_Fields.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.DATA_MOVEMENT_INTERFACE_ID, new org.apache.thrift.meta_data.FieldMetaData("dataMovementInterfaceId", org.apache.thrift.TFieldRequirementType.REQUIRED, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING)));
      tmpMap.put(_Fields.GRID_FTPDATA_MOVEMENT, new org.apache.thrift.meta_data.FieldMetaData("gridFTPDataMovement", org.apache.thrift.TFieldRequirementType.REQUIRED, 
          new org.apache.thrift.meta_data.StructMetaData(org.apache.thrift.protocol.TType.STRUCT, org.apache.airavata.model.appcatalog.computeresource.GridFTPDataMovement.class)));
      metaDataMap = Collections.unmodifiableMap(tmpMap);
      org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(updateGridFTPDataMovementDetails_args.class, metaDataMap);
    }

    public updateGridFTPDataMovementDetails_args() {
    }

    public updateGridFTPDataMovementDetails_args(
      org.apache.airavata.model.security.AuthzToken authzToken,
      String dataMovementInterfaceId,
      org.apache.airavata.model.appcatalog.computeresource.GridFTPDataMovement gridFTPDataMovement)
    {
      this();
      this.authzToken = authzToken;
      this.dataMovementInterfaceId = dataMovementInterfaceId;
      this.gridFTPDataMovement = gridFTPDataMovement;
    }

    /**
     * Performs a deep copy on <i>other</i>.
     */
    public updateGridFTPDataMovementDetails_args(updateGridFTPDataMovementDetails_args other) {
      if (other.isSetAuthzToken()) {
        this.authzToken = new org.apache.airavata.model.security.AuthzToken(other.authzToken);
      }
      if (other.isSetDataMovementInterfaceId()) {
        this.dataMovementInterfaceId = other.dataMovementInterfaceId;
      }
      if (other.isSetGridFTPDataMovement()) {
        this.gridFTPDataMovement = new org.apache.airavata.model.appcatalog.computeresource.GridFTPDataMovement(other.gridFTPDataMovement);
      }
    }

    public updateGridFTPDataMovementDetails_args deepCopy() {
      return new updateGridFTPDataMovementDetails_args(this);
    }

    @Override
    public void clear() {
      this.authzToken = null;
      this.dataMovementInterfaceId = null;
      this.gridFTPDataMovement = null;
    }

    public org.apache.airavata.model.security.AuthzToken getAuthzToken() {
      return this.authzToken;
    }

    public updateGridFTPDataMovementDetails_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 String getDataMovementInterfaceId() {
      return this.dataMovementInterfaceId;
    }

    public updateGridFTPDataMovementDetails_args setDataMovementInterfaceId(String dataMovementInterfaceId) {
      this.dataMovementInterfaceId = dataMovementInterfaceId;
      return this;
    }

    public void unsetDataMovementInterfaceId() {
      this.dataMovementInterfaceId = null;
    }

    /** Returns true if field dataMovementInterfaceId is set (has been assigned a value) and false otherwise */
    public boolean isSetDataMovementInterfaceId() {
      return this.dataMovementInterfaceId != null;
    }

    public void setDataMovementInterfaceIdIsSet(boolean value) {
      if (!value) {
        this.dataMovementInterfaceId = null;
      }
    }

    public org.apache.airavata.model.appcatalog.computeresource.GridFTPDataMovement getGridFTPDataMovement() {
      return this.gridFTPDataMovement;
    }

    public updateGridFTPDataMovementDetails_args setGridFTPDataMovement(org.apache.airavata.model.appcatalog.computeresource.GridFTPDataMovement gridFTPDataMovement) {
      this.gridFTPDataMovement = gridFTPDataMovement;
      return this;
    }

    public void unsetGridFTPDataMovement() {
      this.gridFTPDataMovement = null;
    }

    /** Returns true if field gridFTPDataMovement is set (has been assigned a value) and false otherwise */
    public boolean isSetGridFTPDataMovement() {
      return this.gridFTPDataMovement != null;
    }

    public void setGridFTPDataMovementIsSet(boolean value) {
      if (!value) {
        this.gridFTPDataMovement = null;
      }
    }

    public void setFieldValue(_Fields field, Object value) {
      switch (field) {
      case AUTHZ_TOKEN:
        if (value == null) {
          unsetAuthzToken();
        } else {
          setAuthzToken((org.apache.airavata.model.security.AuthzToken)value);
        }
        break;

      case DATA_MOVEMENT_INTERFACE_ID:
        if (value == null) {
          unsetDataMovementInterfaceId();
        } else {
          setDataMovementInterfaceId((String)value);
        }
        break;

      case GRID_FTPDATA_MOVEMENT:
        if (value == null) {
          unsetGridFTPDataMovement();
        } else {
          setGridFTPDataMovement((org.apache.airavata.model.appcatalog.computeresource.GridFTPDataMovement)value);
        }
        break;

      }
    }

    public Object getFieldValue(_Fields field) {
      switch (field) {
      case AUTHZ_TOKEN:
        return getAuthzToken();

      case DATA_MOVEMENT_INTERFACE_ID:
        return getDataMovementInterfaceId();

      case GRID_FTPDATA_MOVEMENT:
        return getGridFTPDataMovement();

      }
      throw new IllegalStateException();
    }

    /** Returns true if field corresponding to fieldID is set (has been assigned a value) and false otherwise */
    public boolean isSet(_Fields field) {
      if (field == null) {
        throw new IllegalArgumentException();
      }

      switch (field) {
      case AUTHZ_TOKEN:
        return isSetAuthzToken();
      case DATA_MOVEMENT_INTERFACE_ID:
        return isSetDataMovementInterfaceId();
      case GRID_FTPDATA_MOVEMENT:
        return isSetGridFTPDataMovement();
      }
      throw new IllegalStateException();
    }

    @Override
    public boolean equals(Object that) {
      if (that == null)
        return false;
      if (that instanceof updateGridFTPDataMovementDetails_args)
        return this.equals((updateGridFTPDataMovementDetails_args)that);
      return false;
    }

    public boolean equals(updateGridFTPDataMovementDetails_args that) {
      if (that == null)
        return false;

      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_dataMovementInterfaceId = true && this.isSetDataMovementInterfaceId();
      boolean that_present_dataMovementInterfaceId = true && that.isSetDataMovementInterfaceId();
      if (this_present_dataMovementInterfaceId || that_present_dataMovementInterfaceId) {
        if (!(this_present_dataMovementInterfaceId && that_present_dataMovementInterfaceId))
          return false;
        if (!this.dataMovementInterfaceId.equals(that.dataMovementInterfaceId))
          return false;
      }

      boolean this_present_gridFTPDataMovement = true && this.isSetGridFTPDataMovement();
      boolean that_present_gridFTPDataMovement = true && that.isSetGridFTPDataMovement();
      if (this_present_gridFTPDataMovement || that_present_gridFTPDataMovement) {
        if (!(this_present_gridFTPDataMovement && that_present_gridFTPDataMovement))
          return false;
        if (!this.gridFTPDataMovement.equals(that.gridFTPDataMovement))
          return false;
      }

      return true;
    }

    @Override
    public int hashCode() {
      List<Object> list = new ArrayList<Object>();

      boolean present_authzToken = true && (isSetAuthzToken());
      list.add(present_authzToken);
      if (present_authzToken)
        list.add(authzToken);

      boolean present_dataMovementInterfaceId = true && (isSetDataMovementInterfaceId());
      list.add(present_dataMovementInterfaceId);
      if (present_dataMovementInterfaceId)
        list.add(dataMovementInterfaceId);

      boolean present_gridFTPDataMovement = true && (isSetGridFTPDataMovement());
      list.add(present_gridFTPDataMovement);
      if (present_gridFTPDataMovement)
        list.add(gridFTPDataMovement);

      return list.hashCode();
    }

    @Override
    public int compareTo(updateGridFTPDataMovementDetails_args other) {
      if (!getClass().equals(other.getClass())) {
        return getClass().getName().compareTo(other.getClass().getName());
      }

      int lastComparison = 0;

      lastComparison = 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 = Boolean.valueOf(isSetDataMovementInterfaceId()).compareTo(other.isSetDataMovementInterfaceId());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetDataMovementInterfaceId()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.dataMovementInterfaceId, other.dataMovementInterfaceId);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = Boolean.valueOf(isSetGridFTPDataMovement()).compareTo(other.isSetGridFTPDataMovement());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetGridFTPDataMovement()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.gridFTPDataMovement, other.gridFTPDataMovement);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      return 0;
    }

    public _Fields fieldForId(int fieldId) {
      return _Fields.findByThriftId(fieldId);
    }

    public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
      schemes.get(iprot.getScheme()).getScheme().read(iprot, this);
    }

    public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException {
      schemes.get(oprot.getScheme()).getScheme().write(oprot, this);
    }

    @Override
    public String toString() {
      StringBuilder sb = new StringBuilder("updateGridFTPDataMovementDetails_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("dataMovementInterfaceId:");
      if (this.dataMovementInterfaceId == null) {
        sb.append("null");
      } else {
        sb.append(this.dataMovementInterfaceId);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("gridFTPDataMovement:");
      if (this.gridFTPDataMovement == null) {
        sb.append("null");
      } else {
        sb.append(this.gridFTPDataMovement);
      }
      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 (dataMovementInterfaceId == null) {
        throw new org.apache.thrift.protocol.TProtocolException("Required field 'dataMovementInterfaceId' was not present! Struct: " + toString());
      }
      if (gridFTPDataMovement == null) {
        throw new org.apache.thrift.protocol.TProtocolException("Required field 'gridFTPDataMovement' was not present! Struct: " + toString());
      }
      // check for sub-struct validity
      if (authzToken != null) {
        authzToken.validate();
      }
      if (gridFTPDataMovement != null) {
        gridFTPDataMovement.validate();
      }
    }

    private void writeObject(java.io.ObjectOutputStream out) throws java.io.IOException {
      try {
        write(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(out)));
      } catch (org.apache.thrift.TException te) {
        throw new java.io.IOException(te);
      }
    }

    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, ClassNotFoundException {
      try {
        read(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(in)));
      } catch (org.apache.thrift.TException te) {
        throw new java.io.IOException(te);
      }
    }

    private static class updateGridFTPDataMovementDetails_argsStandardSchemeFactory implements SchemeFactory {
      public updateGridFTPDataMovementDetails_argsStandardScheme getScheme() {
        return new updateGridFTPDataMovementDetails_argsStandardScheme();
      }
    }

    private static class updateGridFTPDataMovementDetails_argsStandardScheme extends StandardScheme<updateGridFTPDataMovementDetails_args> {

      public void read(org.apache.thrift.protocol.TProtocol iprot, updateGridFTPDataMovementDetails_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: // DATA_MOVEMENT_INTERFACE_ID
              if (schemeField.type == org.apache.thrift.protocol.TType.STRING) {
                struct.dataMovementInterfaceId = iprot.readString();
                struct.setDataMovementInterfaceIdIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 3: // GRID_FTPDATA_MOVEMENT
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.gridFTPDataMovement = new org.apache.airavata.model.appcatalog.computeresource.GridFTPDataMovement();
                struct.gridFTPDataMovement.read(iprot);
                struct.setGridFTPDataMovementIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            default:
              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
          }
          iprot.readFieldEnd();
        }
        iprot.readStructEnd();

        // check for required fields of primitive type, which can't be checked in the validate method
        struct.validate();
      }

      public void write(org.apache.thrift.protocol.TProtocol oprot, updateGridFTPDataMovementDetails_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.dataMovementInterfaceId != null) {
          oprot.writeFieldBegin(DATA_MOVEMENT_INTERFACE_ID_FIELD_DESC);
          oprot.writeString(struct.dataMovementInterfaceId);
          oprot.writeFieldEnd();
        }
        if (struct.gridFTPDataMovement != null) {
          oprot.writeFieldBegin(GRID_FTPDATA_MOVEMENT_FIELD_DESC);
          struct.gridFTPDataMovement.write(oprot);
          oprot.writeFieldEnd();
        }
        oprot.writeFieldStop();
        oprot.writeStructEnd();
      }

    }

    private static class updateGridFTPDataMovementDetails_argsTupleSchemeFactory implements SchemeFactory {
      public updateGridFTPDataMovementDetails_argsTupleScheme getScheme() {
        return new updateGridFTPDataMovementDetails_argsTupleScheme();
      }
    }

    private static class updateGridFTPDataMovementDetails_argsTupleScheme extends TupleScheme<updateGridFTPDataMovementDetails_args> {

      @Override
      public void write(org.apache.thrift.protocol.TProtocol prot, updateGridFTPDataMovementDetails_args struct) throws org.apache.thrift.TException {
        TTupleProtocol oprot = (TTupleProtocol) prot;
        struct.authzToken.write(oprot);
        oprot.writeString(struct.dataMovementInterfaceId);
        struct.gridFTPDataMovement.write(oprot);
      }

      @Override
      public void read(org.apache.thrift.protocol.TProtocol prot, updateGridFTPDataMovementDetails_args struct) throws org.apache.thrift.TException {
        TTupleProtocol iprot = (TTupleProtocol) prot;
        struct.authzToken = new org.apache.airavata.model.security.AuthzToken();
        struct.authzToken.read(iprot);
        struct.setAuthzTokenIsSet(true);
        struct.dataMovementInterfaceId = iprot.readString();
        struct.setDataMovementInterfaceIdIsSet(true);
        struct.gridFTPDataMovement = new org.apache.airavata.model.appcatalog.computeresource.GridFTPDataMovement();
        struct.gridFTPDataMovement.read(iprot);
        struct.setGridFTPDataMovementIsSet(true);
      }
    }

  }

  public static class updateGridFTPDataMovementDetails_result implements org.apache.thrift.TBase<updateGridFTPDataMovementDetails_result, updateGridFTPDataMovementDetails_result._Fields>, java.io.Serializable, Cloneable, Comparable<updateGridFTPDataMovementDetails_result>   {
    private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("updateGridFTPDataMovementDetails_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 IRE_FIELD_DESC = new org.apache.thrift.protocol.TField("ire", org.apache.thrift.protocol.TType.STRUCT, (short)1);
    private static final org.apache.thrift.protocol.TField ACE_FIELD_DESC = new org.apache.thrift.protocol.TField("ace", org.apache.thrift.protocol.TType.STRUCT, (short)2);
    private static final org.apache.thrift.protocol.TField ASE_FIELD_DESC = new org.apache.thrift.protocol.TField("ase", org.apache.thrift.protocol.TType.STRUCT, (short)3);
    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)4);

    private static final Map<Class<? extends IScheme>, SchemeFactory> schemes = new HashMap<Class<? extends IScheme>, SchemeFactory>();
    static {
      schemes.put(StandardScheme.class, new updateGridFTPDataMovementDetails_resultStandardSchemeFactory());
      schemes.put(TupleScheme.class, new updateGridFTPDataMovementDetails_resultTupleSchemeFactory());
    }

    public boolean success; // required
    public org.apache.airavata.model.error.InvalidRequestException ire; // required
    public org.apache.airavata.model.error.AiravataClientException ace; // required
    public org.apache.airavata.model.error.AiravataSystemException ase; // 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"),
      IRE((short)1, "ire"),
      ACE((short)2, "ace"),
      ASE((short)3, "ase"),
      AE((short)4, "ae");

      private static final Map<String, _Fields> byName = new HashMap<String, _Fields>();

      static {
        for (_Fields field : EnumSet.allOf(_Fields.class)) {
          byName.put(field.getFieldName(), field);
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, or null if its not found.
       */
      public static _Fields findByThriftId(int fieldId) {
        switch(fieldId) {
          case 0: // SUCCESS
            return SUCCESS;
          case 1: // IRE
            return IRE;
          case 2: // ACE
            return ACE;
          case 3: // ASE
            return ASE;
          case 4: // 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 IllegalArgumentException("Field " + fieldId + " doesn't exist!");
        return fields;
      }

      /**
       * Find the _Fields constant that matches name, or null if its not found.
       */
      public static _Fields findByName(String name) {
        return byName.get(name);
      }

      private final short _thriftId;
      private final String _fieldName;

      _Fields(short thriftId, String fieldName) {
        _thriftId = thriftId;
        _fieldName = fieldName;
      }

      public short getThriftFieldId() {
        return _thriftId;
      }

      public String getFieldName() {
        return _fieldName;
      }
    }

    // isset id assignments
    private static final int __SUCCESS_ISSET_ID = 0;
    private byte __isset_bitfield = 0;
    public static final Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
    static {
      Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new EnumMap<_Fields, org.apache.thrift.meta_data.FieldMetaData>(_Fields.class);
      tmpMap.put(_Fields.SUCCESS, new org.apache.thrift.meta_data.FieldMetaData("success", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.BOOL)));
      tmpMap.put(_Fields.IRE, new org.apache.thrift.meta_data.FieldMetaData("ire", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRUCT)));
      tmpMap.put(_Fields.ACE, new org.apache.thrift.meta_data.FieldMetaData("ace", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRUCT)));
      tmpMap.put(_Fields.ASE, new org.apache.thrift.meta_data.FieldMetaData("ase", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRUCT)));
      tmpMap.put(_Fields.AE, new org.apache.thrift.meta_data.FieldMetaData("ae", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRUCT)));
      metaDataMap = Collections.unmodifiableMap(tmpMap);
      org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(updateGridFTPDataMovementDetails_result.class, metaDataMap);
    }

    public updateGridFTPDataMovementDetails_result() {
    }

    public updateGridFTPDataMovementDetails_result(
      boolean success,
      org.apache.airavata.model.error.InvalidRequestException ire,
      org.apache.airavata.model.error.AiravataClientException ace,
      org.apache.airavata.model.error.AiravataSystemException ase,
      org.apache.airavata.model.error.AuthorizationException ae)
    {
      this();
      this.success = success;
      setSuccessIsSet(true);
      this.ire = ire;
      this.ace = ace;
      this.ase = ase;
      this.ae = ae;
    }

    /**
     * Performs a deep copy on <i>other</i>.
     */
    public updateGridFTPDataMovementDetails_result(updateGridFTPDataMovementDetails_result other) {
      __isset_bitfield = other.__isset_bitfield;
      this.success = other.success;
      if (other.isSetIre()) {
        this.ire = new org.apache.airavata.model.error.InvalidRequestException(other.ire);
      }
      if (other.isSetAce()) {
        this.ace = new org.apache.airavata.model.error.AiravataClientException(other.ace);
      }
      if (other.isSetAse()) {
        this.ase = new org.apache.airavata.model.error.AiravataSystemException(other.ase);
      }
      if (other.isSetAe()) {
        this.ae = new org.apache.airavata.model.error.AuthorizationException(other.ae);
      }
    }

    public updateGridFTPDataMovementDetails_result deepCopy() {
      return new updateGridFTPDataMovementDetails_result(this);
    }

    @Override
    public void clear() {
      setSuccessIsSet(false);
      this.success = false;
      this.ire = null;
      this.ace = null;
      this.ase = null;
      this.ae = null;
    }

    public boolean isSuccess() {
      return this.success;
    }

    public updateGridFTPDataMovementDetails_result setSuccess(boolean success) {
      this.success = success;
      setSuccessIsSet(true);
      return this;
    }

    public void unsetSuccess() {
      __isset_bitfield = EncodingUtils.clearBit(__isset_bitfield, __SUCCESS_ISSET_ID);
    }

    /** Returns true if field success is set (has been assigned a value) and false otherwise */
    public boolean isSetSuccess() {
      return EncodingUtils.testBit(__isset_bitfield, __SUCCESS_ISSET_ID);
    }

    public void setSuccessIsSet(boolean value) {
      __isset_bitfield = EncodingUtils.setBit(__isset_bitfield, __SUCCESS_ISSET_ID, value);
    }

    public org.apache.airavata.model.error.InvalidRequestException getIre() {
      return this.ire;
    }

    public updateGridFTPDataMovementDetails_result setIre(org.apache.airavata.model.error.InvalidRequestException ire) {
      this.ire = ire;
      return this;
    }

    public void unsetIre() {
      this.ire = null;
    }

    /** Returns true if field ire is set (has been assigned a value) and false otherwise */
    public boolean isSetIre() {
      return this.ire != null;
    }

    public void setIreIsSet(boolean value) {
      if (!value) {
        this.ire = null;
      }
    }

    public org.apache.airavata.model.error.AiravataClientException getAce() {
      return this.ace;
    }

    public updateGridFTPDataMovementDetails_result setAce(org.apache.airavata.model.error.AiravataClientException ace) {
      this.ace = ace;
      return this;
    }

    public void unsetAce() {
      this.ace = null;
    }

    /** Returns true if field ace is set (has been assigned a value) and false otherwise */
    public boolean isSetAce() {
      return this.ace != null;
    }

    public void setAceIsSet(boolean value) {
      if (!value) {
        this.ace = null;
      }
    }

    public org.apache.airavata.model.error.AiravataSystemException getAse() {
      return this.ase;
    }

    public updateGridFTPDataMovementDetails_result setAse(org.apache.airavata.model.error.AiravataSystemException ase) {
      this.ase = ase;
      return this;
    }

    public void unsetAse() {
      this.ase = null;
    }

    /** Returns true if field ase is set (has been assigned a value) and false otherwise */
    public boolean isSetAse() {
      return this.ase != null;
    }

    public void setAseIsSet(boolean value) {
      if (!value) {
        this.ase = null;
      }
    }

    public org.apache.airavata.model.error.AuthorizationException getAe() {
      return this.ae;
    }

    public updateGridFTPDataMovementDetails_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, Object value) {
      switch (field) {
      case SUCCESS:
        if (value == null) {
          unsetSuccess();
        } else {
          setSuccess((Boolean)value);
        }
        break;

      case IRE:
        if (value == null) {
          unsetIre();
        } else {
          setIre((org.apache.airavata.model.error.InvalidRequestException)value);
        }
        break;

      case ACE:
        if (value == null) {
          unsetAce();
        } else {
          setAce((org.apache.airavata.model.error.AiravataClientException)value);
        }
        break;

      case ASE:
        if (value == null) {
          unsetAse();
        } else {
          setAse((org.apache.airavata.model.error.AiravataSystemException)value);
        }
        break;

      case AE:
        if (value == null) {
          unsetAe();
        } else {
          setAe((org.apache.airavata.model.error.AuthorizationException)value);
        }
        break;

      }
    }

    public Object getFieldValue(_Fields field) {
      switch (field) {
      case SUCCESS:
        return Boolean.valueOf(isSuccess());

      case IRE:
        return getIre();

      case ACE:
        return getAce();

      case ASE:
        return getAse();

      case AE:
        return getAe();

      }
      throw new IllegalStateException();
    }

    /** Returns true if field corresponding to fieldID is set (has been assigned a value) and false otherwise */
    public boolean isSet(_Fields field) {
      if (field == null) {
        throw new IllegalArgumentException();
      }

      switch (field) {
      case SUCCESS:
        return isSetSuccess();
      case IRE:
        return isSetIre();
      case ACE:
        return isSetAce();
      case ASE:
        return isSetAse();
      case AE:
        return isSetAe();
      }
      throw new IllegalStateException();
    }

    @Override
    public boolean equals(Object that) {
      if (that == null)
        return false;
      if (that instanceof updateGridFTPDataMovementDetails_result)
        return this.equals((updateGridFTPDataMovementDetails_result)that);
      return false;
    }

    public boolean equals(updateGridFTPDataMovementDetails_result that) {
      if (that == null)
        return false;

      boolean this_present_success = true;
      boolean that_present_success = true;
      if (this_present_success || that_present_success) {
        if (!(this_present_success && that_present_success))
          return false;
        if (this.success != that.success)
          return false;
      }

      boolean this_present_ire = true && this.isSetIre();
      boolean that_present_ire = true && that.isSetIre();
      if (this_present_ire || that_present_ire) {
        if (!(this_present_ire && that_present_ire))
          return false;
        if (!this.ire.equals(that.ire))
          return false;
      }

      boolean this_present_ace = true && this.isSetAce();
      boolean that_present_ace = true && that.isSetAce();
      if (this_present_ace || that_present_ace) {
        if (!(this_present_ace && that_present_ace))
          return false;
        if (!this.ace.equals(that.ace))
          return false;
      }

      boolean this_present_ase = true && this.isSetAse();
      boolean that_present_ase = true && that.isSetAse();
      if (this_present_ase || that_present_ase) {
        if (!(this_present_ase && that_present_ase))
          return false;
        if (!this.ase.equals(that.ase))
          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() {
      List<Object> list = new ArrayList<Object>();

      boolean present_success = true;
      list.add(present_success);
      if (present_success)
        list.add(success);

      boolean present_ire = true && (isSetIre());
      list.add(present_ire);
      if (present_ire)
        list.add(ire);

      boolean present_ace = true && (isSetAce());
      list.add(present_ace);
      if (present_ace)
        list.add(ace);

      boolean present_ase = true && (isSetAse());
      list.add(present_ase);
      if (present_ase)
        list.add(ase);

      boolean present_ae = true && (isSetAe());
      list.add(present_ae);
      if (present_ae)
        list.add(ae);

      return list.hashCode();
    }

    @Override
    public int compareTo(updateGridFTPDataMovementDetails_result other) {
      if (!getClass().equals(other.getClass())) {
        return getClass().getName().compareTo(other.getClass().getName());
      }

      int lastComparison = 0;

      lastComparison = Boolean.valueOf(isSetSuccess()).compareTo(other.isSetSuccess());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetSuccess()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.success, other.success);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = Boolean.valueOf(isSetIre()).compareTo(other.isSetIre());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetIre()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.ire, other.ire);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = Boolean.valueOf(isSetAce()).compareTo(other.isSetAce());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetAce()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.ace, other.ace);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = Boolean.valueOf(isSetAse()).compareTo(other.isSetAse());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetAse()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.ase, other.ase);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = 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 {
      schemes.get(iprot.getScheme()).getScheme().read(iprot, this);
    }

    public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException {
      schemes.get(oprot.getScheme()).getScheme().write(oprot, this);
      }

    @Override
    public String toString() {
      StringBuilder sb = new StringBuilder("updateGridFTPDataMovementDetails_result(");
      boolean first = true;

      sb.append("success:");
      sb.append(this.success);
      first = false;
      if (!first) sb.append(", ");
      sb.append("ire:");
      if (this.ire == null) {
        sb.append("null");
      } else {
        sb.append(this.ire);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("ace:");
      if (this.ace == null) {
        sb.append("null");
      } else {
        sb.append(this.ace);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("ase:");
      if (this.ase == null) {
        sb.append("null");
      } else {
        sb.append(this.ase);
      }
      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, 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 updateGridFTPDataMovementDetails_resultStandardSchemeFactory implements SchemeFactory {
      public updateGridFTPDataMovementDetails_resultStandardScheme getScheme() {
        return new updateGridFTPDataMovementDetails_resultStandardScheme();
      }
    }

    private static class updateGridFTPDataMovementDetails_resultStandardScheme extends StandardScheme<updateGridFTPDataMovementDetails_result> {

      public void read(org.apache.thrift.protocol.TProtocol iprot, updateGridFTPDataMovementDetails_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: // IRE
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.ire = new org.apache.airavata.model.error.InvalidRequestException();
                struct.ire.read(iprot);
                struct.setIreIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 2: // ACE
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.ace = new org.apache.airavata.model.error.AiravataClientException();
                struct.ace.read(iprot);
                struct.setAceIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 3: // ASE
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.ase = new org.apache.airavata.model.error.AiravataSystemException();
                struct.ase.read(iprot);
                struct.setAseIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 4: // 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, updateGridFTPDataMovementDetails_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.ire != null) {
          oprot.writeFieldBegin(IRE_FIELD_DESC);
          struct.ire.write(oprot);
          oprot.writeFieldEnd();
        }
        if (struct.ace != null) {
          oprot.writeFieldBegin(ACE_FIELD_DESC);
          struct.ace.write(oprot);
          oprot.writeFieldEnd();
        }
        if (struct.ase != null) {
          oprot.writeFieldBegin(ASE_FIELD_DESC);
          struct.ase.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 updateGridFTPDataMovementDetails_resultTupleSchemeFactory implements SchemeFactory {
      public updateGridFTPDataMovementDetails_resultTupleScheme getScheme() {
        return new updateGridFTPDataMovementDetails_resultTupleScheme();
      }
    }

    private static class updateGridFTPDataMovementDetails_resultTupleScheme extends TupleScheme<updateGridFTPDataMovementDetails_result> {

      @Override
      public void write(org.apache.thrift.protocol.TProtocol prot, updateGridFTPDataMovementDetails_result struct) throws org.apache.thrift.TException {
        TTupleProtocol oprot = (TTupleProtocol) prot;
        BitSet optionals = new BitSet();
        if (struct.isSetSuccess()) {
          optionals.set(0);
        }
        if (struct.isSetIre()) {
          optionals.set(1);
        }
        if (struct.isSetAce()) {
          optionals.set(2);
        }
        if (struct.isSetAse()) {
          optionals.set(3);
        }
        if (struct.isSetAe()) {
          optionals.set(4);
        }
        oprot.writeBitSet(optionals, 5);
        if (struct.isSetSuccess()) {
          oprot.writeBool(struct.success);
        }
        if (struct.isSetIre()) {
          struct.ire.write(oprot);
        }
        if (struct.isSetAce()) {
          struct.ace.write(oprot);
        }
        if (struct.isSetAse()) {
          struct.ase.write(oprot);
        }
        if (struct.isSetAe()) {
          struct.ae.write(oprot);
        }
      }

      @Override
      public void read(org.apache.thrift.protocol.TProtocol prot, updateGridFTPDataMovementDetails_result struct) throws org.apache.thrift.TException {
        TTupleProtocol iprot = (TTupleProtocol) prot;
        BitSet incoming = iprot.readBitSet(5);
        if (incoming.get(0)) {
          struct.success = iprot.readBool();
          struct.setSuccessIsSet(true);
        }
        if (incoming.get(1)) {
          struct.ire = new org.apache.airavata.model.error.InvalidRequestException();
          struct.ire.read(iprot);
          struct.setIreIsSet(true);
        }
        if (incoming.get(2)) {
          struct.ace = new org.apache.airavata.model.error.AiravataClientException();
          struct.ace.read(iprot);
          struct.setAceIsSet(true);
        }
        if (incoming.get(3)) {
          struct.ase = new org.apache.airavata.model.error.AiravataSystemException();
          struct.ase.read(iprot);
          struct.setAseIsSet(true);
        }
        if (incoming.get(4)) {
          struct.ae = new org.apache.airavata.model.error.AuthorizationException();
          struct.ae.read(iprot);
          struct.setAeIsSet(true);
        }
      }
    }

  }

  public static class getGridFTPDataMovement_args implements org.apache.thrift.TBase<getGridFTPDataMovement_args, getGridFTPDataMovement_args._Fields>, java.io.Serializable, Cloneable, Comparable<getGridFTPDataMovement_args>   {
    private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("getGridFTPDataMovement_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 DATA_MOVEMENT_ID_FIELD_DESC = new org.apache.thrift.protocol.TField("dataMovementId", org.apache.thrift.protocol.TType.STRING, (short)2);

    private static final Map<Class<? extends IScheme>, SchemeFactory> schemes = new HashMap<Class<? extends IScheme>, SchemeFactory>();
    static {
      schemes.put(StandardScheme.class, new getGridFTPDataMovement_argsStandardSchemeFactory());
      schemes.put(TupleScheme.class, new getGridFTPDataMovement_argsTupleSchemeFactory());
    }

    public org.apache.airavata.model.security.AuthzToken authzToken; // required
    public String dataMovementId; // required

    /** 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"),
      DATA_MOVEMENT_ID((short)2, "dataMovementId");

      private static final Map<String, _Fields> byName = new HashMap<String, _Fields>();

      static {
        for (_Fields field : EnumSet.allOf(_Fields.class)) {
          byName.put(field.getFieldName(), field);
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, or null if its not found.
       */
      public static _Fields findByThriftId(int fieldId) {
        switch(fieldId) {
          case 1: // AUTHZ_TOKEN
            return AUTHZ_TOKEN;
          case 2: // DATA_MOVEMENT_ID
            return DATA_MOVEMENT_ID;
          default:
            return null;
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, throwing an exception
       * if it is not found.
       */
      public static _Fields findByThriftIdOrThrow(int fieldId) {
        _Fields fields = findByThriftId(fieldId);
        if (fields == null) throw new IllegalArgumentException("Field " + fieldId + " doesn't exist!");
        return fields;
      }

      /**
       * Find the _Fields constant that matches name, or null if its not found.
       */
      public static _Fields findByName(String name) {
        return byName.get(name);
      }

      private final short _thriftId;
      private final String _fieldName;

      _Fields(short thriftId, String fieldName) {
        _thriftId = thriftId;
        _fieldName = fieldName;
      }

      public short getThriftFieldId() {
        return _thriftId;
      }

      public String getFieldName() {
        return _fieldName;
      }
    }

    // isset id assignments
    public static final Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
    static {
      Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new EnumMap<_Fields, org.apache.thrift.meta_data.FieldMetaData>(_Fields.class);
      tmpMap.put(_Fields.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.DATA_MOVEMENT_ID, new org.apache.thrift.meta_data.FieldMetaData("dataMovementId", org.apache.thrift.TFieldRequirementType.REQUIRED, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING)));
      metaDataMap = Collections.unmodifiableMap(tmpMap);
      org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(getGridFTPDataMovement_args.class, metaDataMap);
    }

    public getGridFTPDataMovement_args() {
    }

    public getGridFTPDataMovement_args(
      org.apache.airavata.model.security.AuthzToken authzToken,
      String dataMovementId)
    {
      this();
      this.authzToken = authzToken;
      this.dataMovementId = dataMovementId;
    }

    /**
     * Performs a deep copy on <i>other</i>.
     */
    public getGridFTPDataMovement_args(getGridFTPDataMovement_args other) {
      if (other.isSetAuthzToken()) {
        this.authzToken = new org.apache.airavata.model.security.AuthzToken(other.authzToken);
      }
      if (other.isSetDataMovementId()) {
        this.dataMovementId = other.dataMovementId;
      }
    }

    public getGridFTPDataMovement_args deepCopy() {
      return new getGridFTPDataMovement_args(this);
    }

    @Override
    public void clear() {
      this.authzToken = null;
      this.dataMovementId = null;
    }

    public org.apache.airavata.model.security.AuthzToken getAuthzToken() {
      return this.authzToken;
    }

    public getGridFTPDataMovement_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 String getDataMovementId() {
      return this.dataMovementId;
    }

    public getGridFTPDataMovement_args setDataMovementId(String dataMovementId) {
      this.dataMovementId = dataMovementId;
      return this;
    }

    public void unsetDataMovementId() {
      this.dataMovementId = null;
    }

    /** Returns true if field dataMovementId is set (has been assigned a value) and false otherwise */
    public boolean isSetDataMovementId() {
      return this.dataMovementId != null;
    }

    public void setDataMovementIdIsSet(boolean value) {
      if (!value) {
        this.dataMovementId = null;
      }
    }

    public void setFieldValue(_Fields field, Object value) {
      switch (field) {
      case AUTHZ_TOKEN:
        if (value == null) {
          unsetAuthzToken();
        } else {
          setAuthzToken((org.apache.airavata.model.security.AuthzToken)value);
        }
        break;

      case DATA_MOVEMENT_ID:
        if (value == null) {
          unsetDataMovementId();
        } else {
          setDataMovementId((String)value);
        }
        break;

      }
    }

    public Object getFieldValue(_Fields field) {
      switch (field) {
      case AUTHZ_TOKEN:
        return getAuthzToken();

      case DATA_MOVEMENT_ID:
        return getDataMovementId();

      }
      throw new IllegalStateException();
    }

    /** Returns true if field corresponding to fieldID is set (has been assigned a value) and false otherwise */
    public boolean isSet(_Fields field) {
      if (field == null) {
        throw new IllegalArgumentException();
      }

      switch (field) {
      case AUTHZ_TOKEN:
        return isSetAuthzToken();
      case DATA_MOVEMENT_ID:
        return isSetDataMovementId();
      }
      throw new IllegalStateException();
    }

    @Override
    public boolean equals(Object that) {
      if (that == null)
        return false;
      if (that instanceof getGridFTPDataMovement_args)
        return this.equals((getGridFTPDataMovement_args)that);
      return false;
    }

    public boolean equals(getGridFTPDataMovement_args that) {
      if (that == null)
        return false;

      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_dataMovementId = true && this.isSetDataMovementId();
      boolean that_present_dataMovementId = true && that.isSetDataMovementId();
      if (this_present_dataMovementId || that_present_dataMovementId) {
        if (!(this_present_dataMovementId && that_present_dataMovementId))
          return false;
        if (!this.dataMovementId.equals(that.dataMovementId))
          return false;
      }

      return true;
    }

    @Override
    public int hashCode() {
      List<Object> list = new ArrayList<Object>();

      boolean present_authzToken = true && (isSetAuthzToken());
      list.add(present_authzToken);
      if (present_authzToken)
        list.add(authzToken);

      boolean present_dataMovementId = true && (isSetDataMovementId());
      list.add(present_dataMovementId);
      if (present_dataMovementId)
        list.add(dataMovementId);

      return list.hashCode();
    }

    @Override
    public int compareTo(getGridFTPDataMovement_args other) {
      if (!getClass().equals(other.getClass())) {
        return getClass().getName().compareTo(other.getClass().getName());
      }

      int lastComparison = 0;

      lastComparison = 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 = Boolean.valueOf(isSetDataMovementId()).compareTo(other.isSetDataMovementId());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetDataMovementId()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.dataMovementId, other.dataMovementId);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      return 0;
    }

    public _Fields fieldForId(int fieldId) {
      return _Fields.findByThriftId(fieldId);
    }

    public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
      schemes.get(iprot.getScheme()).getScheme().read(iprot, this);
    }

    public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException {
      schemes.get(oprot.getScheme()).getScheme().write(oprot, this);
    }

    @Override
    public String toString() {
      StringBuilder sb = new StringBuilder("getGridFTPDataMovement_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("dataMovementId:");
      if (this.dataMovementId == null) {
        sb.append("null");
      } else {
        sb.append(this.dataMovementId);
      }
      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 (dataMovementId == null) {
        throw new org.apache.thrift.protocol.TProtocolException("Required field 'dataMovementId' 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, 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 getGridFTPDataMovement_argsStandardSchemeFactory implements SchemeFactory {
      public getGridFTPDataMovement_argsStandardScheme getScheme() {
        return new getGridFTPDataMovement_argsStandardScheme();
      }
    }

    private static class getGridFTPDataMovement_argsStandardScheme extends StandardScheme<getGridFTPDataMovement_args> {

      public void read(org.apache.thrift.protocol.TProtocol iprot, getGridFTPDataMovement_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: // DATA_MOVEMENT_ID
              if (schemeField.type == org.apache.thrift.protocol.TType.STRING) {
                struct.dataMovementId = iprot.readString();
                struct.setDataMovementIdIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            default:
              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
          }
          iprot.readFieldEnd();
        }
        iprot.readStructEnd();

        // check for required fields of primitive type, which can't be checked in the validate method
        struct.validate();
      }

      public void write(org.apache.thrift.protocol.TProtocol oprot, getGridFTPDataMovement_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.dataMovementId != null) {
          oprot.writeFieldBegin(DATA_MOVEMENT_ID_FIELD_DESC);
          oprot.writeString(struct.dataMovementId);
          oprot.writeFieldEnd();
        }
        oprot.writeFieldStop();
        oprot.writeStructEnd();
      }

    }

    private static class getGridFTPDataMovement_argsTupleSchemeFactory implements SchemeFactory {
      public getGridFTPDataMovement_argsTupleScheme getScheme() {
        return new getGridFTPDataMovement_argsTupleScheme();
      }
    }

    private static class getGridFTPDataMovement_argsTupleScheme extends TupleScheme<getGridFTPDataMovement_args> {

      @Override
      public void write(org.apache.thrift.protocol.TProtocol prot, getGridFTPDataMovement_args struct) throws org.apache.thrift.TException {
        TTupleProtocol oprot = (TTupleProtocol) prot;
        struct.authzToken.write(oprot);
        oprot.writeString(struct.dataMovementId);
      }

      @Override
      public void read(org.apache.thrift.protocol.TProtocol prot, getGridFTPDataMovement_args struct) throws org.apache.thrift.TException {
        TTupleProtocol iprot = (TTupleProtocol) prot;
        struct.authzToken = new org.apache.airavata.model.security.AuthzToken();
        struct.authzToken.read(iprot);
        struct.setAuthzTokenIsSet(true);
        struct.dataMovementId = iprot.readString();
        struct.setDataMovementIdIsSet(true);
      }
    }

  }

  public static class getGridFTPDataMovement_result implements org.apache.thrift.TBase<getGridFTPDataMovement_result, getGridFTPDataMovement_result._Fields>, java.io.Serializable, Cloneable, Comparable<getGridFTPDataMovement_result>   {
    private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("getGridFTPDataMovement_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 IRE_FIELD_DESC = new org.apache.thrift.protocol.TField("ire", org.apache.thrift.protocol.TType.STRUCT, (short)1);
    private static final org.apache.thrift.protocol.TField ACE_FIELD_DESC = new org.apache.thrift.protocol.TField("ace", org.apache.thrift.protocol.TType.STRUCT, (short)2);
    private static final org.apache.thrift.protocol.TField ASE_FIELD_DESC = new org.apache.thrift.protocol.TField("ase", org.apache.thrift.protocol.TType.STRUCT, (short)3);
    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)4);

    private static final Map<Class<? extends IScheme>, SchemeFactory> schemes = new HashMap<Class<? extends IScheme>, SchemeFactory>();
    static {
      schemes.put(StandardScheme.class, new getGridFTPDataMovement_resultStandardSchemeFactory());
      schemes.put(TupleScheme.class, new getGridFTPDataMovement_resultTupleSchemeFactory());
    }

    public org.apache.airavata.model.appcatalog.computeresource.GridFTPDataMovement success; // required
    public org.apache.airavata.model.error.InvalidRequestException ire; // required
    public org.apache.airavata.model.error.AiravataClientException ace; // required
    public org.apache.airavata.model.error.AiravataSystemException ase; // 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"),
      IRE((short)1, "ire"),
      ACE((short)2, "ace"),
      ASE((short)3, "ase"),
      AE((short)4, "ae");

      private static final Map<String, _Fields> byName = new HashMap<String, _Fields>();

      static {
        for (_Fields field : EnumSet.allOf(_Fields.class)) {
          byName.put(field.getFieldName(), field);
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, or null if its not found.
       */
      public static _Fields findByThriftId(int fieldId) {
        switch(fieldId) {
          case 0: // SUCCESS
            return SUCCESS;
          case 1: // IRE
            return IRE;
          case 2: // ACE
            return ACE;
          case 3: // ASE
            return ASE;
          case 4: // 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 IllegalArgumentException("Field " + fieldId + " doesn't exist!");
        return fields;
      }

      /**
       * Find the _Fields constant that matches name, or null if its not found.
       */
      public static _Fields findByName(String name) {
        return byName.get(name);
      }

      private final short _thriftId;
      private final String _fieldName;

      _Fields(short thriftId, String fieldName) {
        _thriftId = thriftId;
        _fieldName = fieldName;
      }

      public short getThriftFieldId() {
        return _thriftId;
      }

      public String getFieldName() {
        return _fieldName;
      }
    }

    // isset id assignments
    public static final Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
    static {
      Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new EnumMap<_Fields, org.apache.thrift.meta_data.FieldMetaData>(_Fields.class);
      tmpMap.put(_Fields.SUCCESS, new org.apache.thrift.meta_data.FieldMetaData("success", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.StructMetaData(org.apache.thrift.protocol.TType.STRUCT, org.apache.airavata.model.appcatalog.computeresource.GridFTPDataMovement.class)));
      tmpMap.put(_Fields.IRE, new org.apache.thrift.meta_data.FieldMetaData("ire", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRUCT)));
      tmpMap.put(_Fields.ACE, new org.apache.thrift.meta_data.FieldMetaData("ace", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRUCT)));
      tmpMap.put(_Fields.ASE, new org.apache.thrift.meta_data.FieldMetaData("ase", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRUCT)));
      tmpMap.put(_Fields.AE, new org.apache.thrift.meta_data.FieldMetaData("ae", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRUCT)));
      metaDataMap = Collections.unmodifiableMap(tmpMap);
      org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(getGridFTPDataMovement_result.class, metaDataMap);
    }

    public getGridFTPDataMovement_result() {
    }

    public getGridFTPDataMovement_result(
      org.apache.airavata.model.appcatalog.computeresource.GridFTPDataMovement success,
      org.apache.airavata.model.error.InvalidRequestException ire,
      org.apache.airavata.model.error.AiravataClientException ace,
      org.apache.airavata.model.error.AiravataSystemException ase,
      org.apache.airavata.model.error.AuthorizationException ae)
    {
      this();
      this.success = success;
      this.ire = ire;
      this.ace = ace;
      this.ase = ase;
      this.ae = ae;
    }

    /**
     * Performs a deep copy on <i>other</i>.
     */
    public getGridFTPDataMovement_result(getGridFTPDataMovement_result other) {
      if (other.isSetSuccess()) {
        this.success = new org.apache.airavata.model.appcatalog.computeresource.GridFTPDataMovement(other.success);
      }
      if (other.isSetIre()) {
        this.ire = new org.apache.airavata.model.error.InvalidRequestException(other.ire);
      }
      if (other.isSetAce()) {
        this.ace = new org.apache.airavata.model.error.AiravataClientException(other.ace);
      }
      if (other.isSetAse()) {
        this.ase = new org.apache.airavata.model.error.AiravataSystemException(other.ase);
      }
      if (other.isSetAe()) {
        this.ae = new org.apache.airavata.model.error.AuthorizationException(other.ae);
      }
    }

    public getGridFTPDataMovement_result deepCopy() {
      return new getGridFTPDataMovement_result(this);
    }

    @Override
    public void clear() {
      this.success = null;
      this.ire = null;
      this.ace = null;
      this.ase = null;
      this.ae = null;
    }

    public org.apache.airavata.model.appcatalog.computeresource.GridFTPDataMovement getSuccess() {
      return this.success;
    }

    public getGridFTPDataMovement_result setSuccess(org.apache.airavata.model.appcatalog.computeresource.GridFTPDataMovement 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.model.error.InvalidRequestException getIre() {
      return this.ire;
    }

    public getGridFTPDataMovement_result setIre(org.apache.airavata.model.error.InvalidRequestException ire) {
      this.ire = ire;
      return this;
    }

    public void unsetIre() {
      this.ire = null;
    }

    /** Returns true if field ire is set (has been assigned a value) and false otherwise */
    public boolean isSetIre() {
      return this.ire != null;
    }

    public void setIreIsSet(boolean value) {
      if (!value) {
        this.ire = null;
      }
    }

    public org.apache.airavata.model.error.AiravataClientException getAce() {
      return this.ace;
    }

    public getGridFTPDataMovement_result setAce(org.apache.airavata.model.error.AiravataClientException ace) {
      this.ace = ace;
      return this;
    }

    public void unsetAce() {
      this.ace = null;
    }

    /** Returns true if field ace is set (has been assigned a value) and false otherwise */
    public boolean isSetAce() {
      return this.ace != null;
    }

    public void setAceIsSet(boolean value) {
      if (!value) {
        this.ace = null;
      }
    }

    public org.apache.airavata.model.error.AiravataSystemException getAse() {
      return this.ase;
    }

    public getGridFTPDataMovement_result setAse(org.apache.airavata.model.error.AiravataSystemException ase) {
      this.ase = ase;
      return this;
    }

    public void unsetAse() {
      this.ase = null;
    }

    /** Returns true if field ase is set (has been assigned a value) and false otherwise */
    public boolean isSetAse() {
      return this.ase != null;
    }

    public void setAseIsSet(boolean value) {
      if (!value) {
        this.ase = null;
      }
    }

    public org.apache.airavata.model.error.AuthorizationException getAe() {
      return this.ae;
    }

    public getGridFTPDataMovement_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, Object value) {
      switch (field) {
      case SUCCESS:
        if (value == null) {
          unsetSuccess();
        } else {
          setSuccess((org.apache.airavata.model.appcatalog.computeresource.GridFTPDataMovement)value);
        }
        break;

      case IRE:
        if (value == null) {
          unsetIre();
        } else {
          setIre((org.apache.airavata.model.error.InvalidRequestException)value);
        }
        break;

      case ACE:
        if (value == null) {
          unsetAce();
        } else {
          setAce((org.apache.airavata.model.error.AiravataClientException)value);
        }
        break;

      case ASE:
        if (value == null) {
          unsetAse();
        } else {
          setAse((org.apache.airavata.model.error.AiravataSystemException)value);
        }
        break;

      case AE:
        if (value == null) {
          unsetAe();
        } else {
          setAe((org.apache.airavata.model.error.AuthorizationException)value);
        }
        break;

      }
    }

    public Object getFieldValue(_Fields field) {
      switch (field) {
      case SUCCESS:
        return getSuccess();

      case IRE:
        return getIre();

      case ACE:
        return getAce();

      case ASE:
        return getAse();

      case AE:
        return getAe();

      }
      throw new IllegalStateException();
    }

    /** Returns true if field corresponding to fieldID is set (has been assigned a value) and false otherwise */
    public boolean isSet(_Fields field) {
      if (field == null) {
        throw new IllegalArgumentException();
      }

      switch (field) {
      case SUCCESS:
        return isSetSuccess();
      case IRE:
        return isSetIre();
      case ACE:
        return isSetAce();
      case ASE:
        return isSetAse();
      case AE:
        return isSetAe();
      }
      throw new IllegalStateException();
    }

    @Override
    public boolean equals(Object that) {
      if (that == null)
        return false;
      if (that instanceof getGridFTPDataMovement_result)
        return this.equals((getGridFTPDataMovement_result)that);
      return false;
    }

    public boolean equals(getGridFTPDataMovement_result that) {
      if (that == null)
        return false;

      boolean this_present_success = true && this.isSetSuccess();
      boolean that_present_success = true && that.isSetSuccess();
      if (this_present_success || that_present_success) {
        if (!(this_present_success && that_present_success))
          return false;
        if (!this.success.equals(that.success))
          return false;
      }

      boolean this_present_ire = true && this.isSetIre();
      boolean that_present_ire = true && that.isSetIre();
      if (this_present_ire || that_present_ire) {
        if (!(this_present_ire && that_present_ire))
          return false;
        if (!this.ire.equals(that.ire))
          return false;
      }

      boolean this_present_ace = true && this.isSetAce();
      boolean that_present_ace = true && that.isSetAce();
      if (this_present_ace || that_present_ace) {
        if (!(this_present_ace && that_present_ace))
          return false;
        if (!this.ace.equals(that.ace))
          return false;
      }

      boolean this_present_ase = true && this.isSetAse();
      boolean that_present_ase = true && that.isSetAse();
      if (this_present_ase || that_present_ase) {
        if (!(this_present_ase && that_present_ase))
          return false;
        if (!this.ase.equals(that.ase))
          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() {
      List<Object> list = new ArrayList<Object>();

      boolean present_success = true && (isSetSuccess());
      list.add(present_success);
      if (present_success)
        list.add(success);

      boolean present_ire = true && (isSetIre());
      list.add(present_ire);
      if (present_ire)
        list.add(ire);

      boolean present_ace = true && (isSetAce());
      list.add(present_ace);
      if (present_ace)
        list.add(ace);

      boolean present_ase = true && (isSetAse());
      list.add(present_ase);
      if (present_ase)
        list.add(ase);

      boolean present_ae = true && (isSetAe());
      list.add(present_ae);
      if (present_ae)
        list.add(ae);

      return list.hashCode();
    }

    @Override
    public int compareTo(getGridFTPDataMovement_result other) {
      if (!getClass().equals(other.getClass())) {
        return getClass().getName().compareTo(other.getClass().getName());
      }

      int lastComparison = 0;

      lastComparison = Boolean.valueOf(isSetSuccess()).compareTo(other.isSetSuccess());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetSuccess()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.success, other.success);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = Boolean.valueOf(isSetIre()).compareTo(other.isSetIre());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetIre()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.ire, other.ire);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = Boolean.valueOf(isSetAce()).compareTo(other.isSetAce());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetAce()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.ace, other.ace);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = Boolean.valueOf(isSetAse()).compareTo(other.isSetAse());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetAse()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.ase, other.ase);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = 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 {
      schemes.get(iprot.getScheme()).getScheme().read(iprot, this);
    }

    public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException {
      schemes.get(oprot.getScheme()).getScheme().write(oprot, this);
      }

    @Override
    public String toString() {
      StringBuilder sb = new StringBuilder("getGridFTPDataMovement_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("ire:");
      if (this.ire == null) {
        sb.append("null");
      } else {
        sb.append(this.ire);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("ace:");
      if (this.ace == null) {
        sb.append("null");
      } else {
        sb.append(this.ace);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("ase:");
      if (this.ase == null) {
        sb.append("null");
      } else {
        sb.append(this.ase);
      }
      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, 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 getGridFTPDataMovement_resultStandardSchemeFactory implements SchemeFactory {
      public getGridFTPDataMovement_resultStandardScheme getScheme() {
        return new getGridFTPDataMovement_resultStandardScheme();
      }
    }

    private static class getGridFTPDataMovement_resultStandardScheme extends StandardScheme<getGridFTPDataMovement_result> {

      public void read(org.apache.thrift.protocol.TProtocol iprot, getGridFTPDataMovement_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.appcatalog.computeresource.GridFTPDataMovement();
                struct.success.read(iprot);
                struct.setSuccessIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 1: // IRE
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.ire = new org.apache.airavata.model.error.InvalidRequestException();
                struct.ire.read(iprot);
                struct.setIreIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 2: // ACE
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.ace = new org.apache.airavata.model.error.AiravataClientException();
                struct.ace.read(iprot);
                struct.setAceIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 3: // ASE
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.ase = new org.apache.airavata.model.error.AiravataSystemException();
                struct.ase.read(iprot);
                struct.setAseIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 4: // 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, getGridFTPDataMovement_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.ire != null) {
          oprot.writeFieldBegin(IRE_FIELD_DESC);
          struct.ire.write(oprot);
          oprot.writeFieldEnd();
        }
        if (struct.ace != null) {
          oprot.writeFieldBegin(ACE_FIELD_DESC);
          struct.ace.write(oprot);
          oprot.writeFieldEnd();
        }
        if (struct.ase != null) {
          oprot.writeFieldBegin(ASE_FIELD_DESC);
          struct.ase.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 getGridFTPDataMovement_resultTupleSchemeFactory implements SchemeFactory {
      public getGridFTPDataMovement_resultTupleScheme getScheme() {
        return new getGridFTPDataMovement_resultTupleScheme();
      }
    }

    private static class getGridFTPDataMovement_resultTupleScheme extends TupleScheme<getGridFTPDataMovement_result> {

      @Override
      public void write(org.apache.thrift.protocol.TProtocol prot, getGridFTPDataMovement_result struct) throws org.apache.thrift.TException {
        TTupleProtocol oprot = (TTupleProtocol) prot;
        BitSet optionals = new BitSet();
        if (struct.isSetSuccess()) {
          optionals.set(0);
        }
        if (struct.isSetIre()) {
          optionals.set(1);
        }
        if (struct.isSetAce()) {
          optionals.set(2);
        }
        if (struct.isSetAse()) {
          optionals.set(3);
        }
        if (struct.isSetAe()) {
          optionals.set(4);
        }
        oprot.writeBitSet(optionals, 5);
        if (struct.isSetSuccess()) {
          struct.success.write(oprot);
        }
        if (struct.isSetIre()) {
          struct.ire.write(oprot);
        }
        if (struct.isSetAce()) {
          struct.ace.write(oprot);
        }
        if (struct.isSetAse()) {
          struct.ase.write(oprot);
        }
        if (struct.isSetAe()) {
          struct.ae.write(oprot);
        }
      }

      @Override
      public void read(org.apache.thrift.protocol.TProtocol prot, getGridFTPDataMovement_result struct) throws org.apache.thrift.TException {
        TTupleProtocol iprot = (TTupleProtocol) prot;
        BitSet incoming = iprot.readBitSet(5);
        if (incoming.get(0)) {
          struct.success = new org.apache.airavata.model.appcatalog.computeresource.GridFTPDataMovement();
          struct.success.read(iprot);
          struct.setSuccessIsSet(true);
        }
        if (incoming.get(1)) {
          struct.ire = new org.apache.airavata.model.error.InvalidRequestException();
          struct.ire.read(iprot);
          struct.setIreIsSet(true);
        }
        if (incoming.get(2)) {
          struct.ace = new org.apache.airavata.model.error.AiravataClientException();
          struct.ace.read(iprot);
          struct.setAceIsSet(true);
        }
        if (incoming.get(3)) {
          struct.ase = new org.apache.airavata.model.error.AiravataSystemException();
          struct.ase.read(iprot);
          struct.setAseIsSet(true);
        }
        if (incoming.get(4)) {
          struct.ae = new org.apache.airavata.model.error.AuthorizationException();
          struct.ae.read(iprot);
          struct.setAeIsSet(true);
        }
      }
    }

  }

  public static class changeJobSubmissionPriority_args implements org.apache.thrift.TBase<changeJobSubmissionPriority_args, changeJobSubmissionPriority_args._Fields>, java.io.Serializable, Cloneable, Comparable<changeJobSubmissionPriority_args>   {
    private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("changeJobSubmissionPriority_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 JOB_SUBMISSION_INTERFACE_ID_FIELD_DESC = new org.apache.thrift.protocol.TField("jobSubmissionInterfaceId", org.apache.thrift.protocol.TType.STRING, (short)2);
    private static final org.apache.thrift.protocol.TField NEW_PRIORITY_ORDER_FIELD_DESC = new org.apache.thrift.protocol.TField("newPriorityOrder", org.apache.thrift.protocol.TType.I32, (short)3);

    private static final Map<Class<? extends IScheme>, SchemeFactory> schemes = new HashMap<Class<? extends IScheme>, SchemeFactory>();
    static {
      schemes.put(StandardScheme.class, new changeJobSubmissionPriority_argsStandardSchemeFactory());
      schemes.put(TupleScheme.class, new changeJobSubmissionPriority_argsTupleSchemeFactory());
    }

    public org.apache.airavata.model.security.AuthzToken authzToken; // required
    public String jobSubmissionInterfaceId; // required
    public int newPriorityOrder; // required

    /** 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"),
      JOB_SUBMISSION_INTERFACE_ID((short)2, "jobSubmissionInterfaceId"),
      NEW_PRIORITY_ORDER((short)3, "newPriorityOrder");

      private static final Map<String, _Fields> byName = new HashMap<String, _Fields>();

      static {
        for (_Fields field : EnumSet.allOf(_Fields.class)) {
          byName.put(field.getFieldName(), field);
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, or null if its not found.
       */
      public static _Fields findByThriftId(int fieldId) {
        switch(fieldId) {
          case 1: // AUTHZ_TOKEN
            return AUTHZ_TOKEN;
          case 2: // JOB_SUBMISSION_INTERFACE_ID
            return JOB_SUBMISSION_INTERFACE_ID;
          case 3: // NEW_PRIORITY_ORDER
            return NEW_PRIORITY_ORDER;
          default:
            return null;
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, throwing an exception
       * if it is not found.
       */
      public static _Fields findByThriftIdOrThrow(int fieldId) {
        _Fields fields = findByThriftId(fieldId);
        if (fields == null) throw new IllegalArgumentException("Field " + fieldId + " doesn't exist!");
        return fields;
      }

      /**
       * Find the _Fields constant that matches name, or null if its not found.
       */
      public static _Fields findByName(String name) {
        return byName.get(name);
      }

      private final short _thriftId;
      private final String _fieldName;

      _Fields(short thriftId, String fieldName) {
        _thriftId = thriftId;
        _fieldName = fieldName;
      }

      public short getThriftFieldId() {
        return _thriftId;
      }

      public String getFieldName() {
        return _fieldName;
      }
    }

    // isset id assignments
    private static final int __NEWPRIORITYORDER_ISSET_ID = 0;
    private byte __isset_bitfield = 0;
    public static final Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
    static {
      Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new EnumMap<_Fields, org.apache.thrift.meta_data.FieldMetaData>(_Fields.class);
      tmpMap.put(_Fields.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.JOB_SUBMISSION_INTERFACE_ID, new org.apache.thrift.meta_data.FieldMetaData("jobSubmissionInterfaceId", org.apache.thrift.TFieldRequirementType.REQUIRED, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING)));
      tmpMap.put(_Fields.NEW_PRIORITY_ORDER, new org.apache.thrift.meta_data.FieldMetaData("newPriorityOrder", org.apache.thrift.TFieldRequirementType.REQUIRED, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.I32)));
      metaDataMap = Collections.unmodifiableMap(tmpMap);
      org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(changeJobSubmissionPriority_args.class, metaDataMap);
    }

    public changeJobSubmissionPriority_args() {
    }

    public changeJobSubmissionPriority_args(
      org.apache.airavata.model.security.AuthzToken authzToken,
      String jobSubmissionInterfaceId,
      int newPriorityOrder)
    {
      this();
      this.authzToken = authzToken;
      this.jobSubmissionInterfaceId = jobSubmissionInterfaceId;
      this.newPriorityOrder = newPriorityOrder;
      setNewPriorityOrderIsSet(true);
    }

    /**
     * Performs a deep copy on <i>other</i>.
     */
    public changeJobSubmissionPriority_args(changeJobSubmissionPriority_args other) {
      __isset_bitfield = other.__isset_bitfield;
      if (other.isSetAuthzToken()) {
        this.authzToken = new org.apache.airavata.model.security.AuthzToken(other.authzToken);
      }
      if (other.isSetJobSubmissionInterfaceId()) {
        this.jobSubmissionInterfaceId = other.jobSubmissionInterfaceId;
      }
      this.newPriorityOrder = other.newPriorityOrder;
    }

    public changeJobSubmissionPriority_args deepCopy() {
      return new changeJobSubmissionPriority_args(this);
    }

    @Override
    public void clear() {
      this.authzToken = null;
      this.jobSubmissionInterfaceId = null;
      setNewPriorityOrderIsSet(false);
      this.newPriorityOrder = 0;
    }

    public org.apache.airavata.model.security.AuthzToken getAuthzToken() {
      return this.authzToken;
    }

    public changeJobSubmissionPriority_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 String getJobSubmissionInterfaceId() {
      return this.jobSubmissionInterfaceId;
    }

    public changeJobSubmissionPriority_args setJobSubmissionInterfaceId(String jobSubmissionInterfaceId) {
      this.jobSubmissionInterfaceId = jobSubmissionInterfaceId;
      return this;
    }

    public void unsetJobSubmissionInterfaceId() {
      this.jobSubmissionInterfaceId = null;
    }

    /** Returns true if field jobSubmissionInterfaceId is set (has been assigned a value) and false otherwise */
    public boolean isSetJobSubmissionInterfaceId() {
      return this.jobSubmissionInterfaceId != null;
    }

    public void setJobSubmissionInterfaceIdIsSet(boolean value) {
      if (!value) {
        this.jobSubmissionInterfaceId = null;
      }
    }

    public int getNewPriorityOrder() {
      return this.newPriorityOrder;
    }

    public changeJobSubmissionPriority_args setNewPriorityOrder(int newPriorityOrder) {
      this.newPriorityOrder = newPriorityOrder;
      setNewPriorityOrderIsSet(true);
      return this;
    }

    public void unsetNewPriorityOrder() {
      __isset_bitfield = EncodingUtils.clearBit(__isset_bitfield, __NEWPRIORITYORDER_ISSET_ID);
    }

    /** Returns true if field newPriorityOrder is set (has been assigned a value) and false otherwise */
    public boolean isSetNewPriorityOrder() {
      return EncodingUtils.testBit(__isset_bitfield, __NEWPRIORITYORDER_ISSET_ID);
    }

    public void setNewPriorityOrderIsSet(boolean value) {
      __isset_bitfield = EncodingUtils.setBit(__isset_bitfield, __NEWPRIORITYORDER_ISSET_ID, value);
    }

    public void setFieldValue(_Fields field, Object value) {
      switch (field) {
      case AUTHZ_TOKEN:
        if (value == null) {
          unsetAuthzToken();
        } else {
          setAuthzToken((org.apache.airavata.model.security.AuthzToken)value);
        }
        break;

      case JOB_SUBMISSION_INTERFACE_ID:
        if (value == null) {
          unsetJobSubmissionInterfaceId();
        } else {
          setJobSubmissionInterfaceId((String)value);
        }
        break;

      case NEW_PRIORITY_ORDER:
        if (value == null) {
          unsetNewPriorityOrder();
        } else {
          setNewPriorityOrder((Integer)value);
        }
        break;

      }
    }

    public Object getFieldValue(_Fields field) {
      switch (field) {
      case AUTHZ_TOKEN:
        return getAuthzToken();

      case JOB_SUBMISSION_INTERFACE_ID:
        return getJobSubmissionInterfaceId();

      case NEW_PRIORITY_ORDER:
        return Integer.valueOf(getNewPriorityOrder());

      }
      throw new IllegalStateException();
    }

    /** Returns true if field corresponding to fieldID is set (has been assigned a value) and false otherwise */
    public boolean isSet(_Fields field) {
      if (field == null) {
        throw new IllegalArgumentException();
      }

      switch (field) {
      case AUTHZ_TOKEN:
        return isSetAuthzToken();
      case JOB_SUBMISSION_INTERFACE_ID:
        return isSetJobSubmissionInterfaceId();
      case NEW_PRIORITY_ORDER:
        return isSetNewPriorityOrder();
      }
      throw new IllegalStateException();
    }

    @Override
    public boolean equals(Object that) {
      if (that == null)
        return false;
      if (that instanceof changeJobSubmissionPriority_args)
        return this.equals((changeJobSubmissionPriority_args)that);
      return false;
    }

    public boolean equals(changeJobSubmissionPriority_args that) {
      if (that == null)
        return false;

      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_jobSubmissionInterfaceId = true && this.isSetJobSubmissionInterfaceId();
      boolean that_present_jobSubmissionInterfaceId = true && that.isSetJobSubmissionInterfaceId();
      if (this_present_jobSubmissionInterfaceId || that_present_jobSubmissionInterfaceId) {
        if (!(this_present_jobSubmissionInterfaceId && that_present_jobSubmissionInterfaceId))
          return false;
        if (!this.jobSubmissionInterfaceId.equals(that.jobSubmissionInterfaceId))
          return false;
      }

      boolean this_present_newPriorityOrder = true;
      boolean that_present_newPriorityOrder = true;
      if (this_present_newPriorityOrder || that_present_newPriorityOrder) {
        if (!(this_present_newPriorityOrder && that_present_newPriorityOrder))
          return false;
        if (this.newPriorityOrder != that.newPriorityOrder)
          return false;
      }

      return true;
    }

    @Override
    public int hashCode() {
      List<Object> list = new ArrayList<Object>();

      boolean present_authzToken = true && (isSetAuthzToken());
      list.add(present_authzToken);
      if (present_authzToken)
        list.add(authzToken);

      boolean present_jobSubmissionInterfaceId = true && (isSetJobSubmissionInterfaceId());
      list.add(present_jobSubmissionInterfaceId);
      if (present_jobSubmissionInterfaceId)
        list.add(jobSubmissionInterfaceId);

      boolean present_newPriorityOrder = true;
      list.add(present_newPriorityOrder);
      if (present_newPriorityOrder)
        list.add(newPriorityOrder);

      return list.hashCode();
    }

    @Override
    public int compareTo(changeJobSubmissionPriority_args other) {
      if (!getClass().equals(other.getClass())) {
        return getClass().getName().compareTo(other.getClass().getName());
      }

      int lastComparison = 0;

      lastComparison = 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 = Boolean.valueOf(isSetJobSubmissionInterfaceId()).compareTo(other.isSetJobSubmissionInterfaceId());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetJobSubmissionInterfaceId()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.jobSubmissionInterfaceId, other.jobSubmissionInterfaceId);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = Boolean.valueOf(isSetNewPriorityOrder()).compareTo(other.isSetNewPriorityOrder());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetNewPriorityOrder()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.newPriorityOrder, other.newPriorityOrder);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      return 0;
    }

    public _Fields fieldForId(int fieldId) {
      return _Fields.findByThriftId(fieldId);
    }

    public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
      schemes.get(iprot.getScheme()).getScheme().read(iprot, this);
    }

    public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException {
      schemes.get(oprot.getScheme()).getScheme().write(oprot, this);
    }

    @Override
    public String toString() {
      StringBuilder sb = new StringBuilder("changeJobSubmissionPriority_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("jobSubmissionInterfaceId:");
      if (this.jobSubmissionInterfaceId == null) {
        sb.append("null");
      } else {
        sb.append(this.jobSubmissionInterfaceId);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("newPriorityOrder:");
      sb.append(this.newPriorityOrder);
      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 (jobSubmissionInterfaceId == null) {
        throw new org.apache.thrift.protocol.TProtocolException("Required field 'jobSubmissionInterfaceId' was not present! Struct: " + toString());
      }
      // alas, we cannot check 'newPriorityOrder' because it's a primitive and you chose the non-beans generator.
      // 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, 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 changeJobSubmissionPriority_argsStandardSchemeFactory implements SchemeFactory {
      public changeJobSubmissionPriority_argsStandardScheme getScheme() {
        return new changeJobSubmissionPriority_argsStandardScheme();
      }
    }

    private static class changeJobSubmissionPriority_argsStandardScheme extends StandardScheme<changeJobSubmissionPriority_args> {

      public void read(org.apache.thrift.protocol.TProtocol iprot, changeJobSubmissionPriority_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: // JOB_SUBMISSION_INTERFACE_ID
              if (schemeField.type == org.apache.thrift.protocol.TType.STRING) {
                struct.jobSubmissionInterfaceId = iprot.readString();
                struct.setJobSubmissionInterfaceIdIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 3: // NEW_PRIORITY_ORDER
              if (schemeField.type == org.apache.thrift.protocol.TType.I32) {
                struct.newPriorityOrder = iprot.readI32();
                struct.setNewPriorityOrderIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            default:
              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
          }
          iprot.readFieldEnd();
        }
        iprot.readStructEnd();

        // check for required fields of primitive type, which can't be checked in the validate method
        if (!struct.isSetNewPriorityOrder()) {
          throw new org.apache.thrift.protocol.TProtocolException("Required field 'newPriorityOrder' was not found in serialized data! Struct: " + toString());
        }
        struct.validate();
      }

      public void write(org.apache.thrift.protocol.TProtocol oprot, changeJobSubmissionPriority_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.jobSubmissionInterfaceId != null) {
          oprot.writeFieldBegin(JOB_SUBMISSION_INTERFACE_ID_FIELD_DESC);
          oprot.writeString(struct.jobSubmissionInterfaceId);
          oprot.writeFieldEnd();
        }
        oprot.writeFieldBegin(NEW_PRIORITY_ORDER_FIELD_DESC);
        oprot.writeI32(struct.newPriorityOrder);
        oprot.writeFieldEnd();
        oprot.writeFieldStop();
        oprot.writeStructEnd();
      }

    }

    private static class changeJobSubmissionPriority_argsTupleSchemeFactory implements SchemeFactory {
      public changeJobSubmissionPriority_argsTupleScheme getScheme() {
        return new changeJobSubmissionPriority_argsTupleScheme();
      }
    }

    private static class changeJobSubmissionPriority_argsTupleScheme extends TupleScheme<changeJobSubmissionPriority_args> {

      @Override
      public void write(org.apache.thrift.protocol.TProtocol prot, changeJobSubmissionPriority_args struct) throws org.apache.thrift.TException {
        TTupleProtocol oprot = (TTupleProtocol) prot;
        struct.authzToken.write(oprot);
        oprot.writeString(struct.jobSubmissionInterfaceId);
        oprot.writeI32(struct.newPriorityOrder);
      }

      @Override
      public void read(org.apache.thrift.protocol.TProtocol prot, changeJobSubmissionPriority_args struct) throws org.apache.thrift.TException {
        TTupleProtocol iprot = (TTupleProtocol) prot;
        struct.authzToken = new org.apache.airavata.model.security.AuthzToken();
        struct.authzToken.read(iprot);
        struct.setAuthzTokenIsSet(true);
        struct.jobSubmissionInterfaceId = iprot.readString();
        struct.setJobSubmissionInterfaceIdIsSet(true);
        struct.newPriorityOrder = iprot.readI32();
        struct.setNewPriorityOrderIsSet(true);
      }
    }

  }

  public static class changeJobSubmissionPriority_result implements org.apache.thrift.TBase<changeJobSubmissionPriority_result, changeJobSubmissionPriority_result._Fields>, java.io.Serializable, Cloneable, Comparable<changeJobSubmissionPriority_result>   {
    private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("changeJobSubmissionPriority_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 IRE_FIELD_DESC = new org.apache.thrift.protocol.TField("ire", org.apache.thrift.protocol.TType.STRUCT, (short)1);
    private static final org.apache.thrift.protocol.TField ACE_FIELD_DESC = new org.apache.thrift.protocol.TField("ace", org.apache.thrift.protocol.TType.STRUCT, (short)2);
    private static final org.apache.thrift.protocol.TField ASE_FIELD_DESC = new org.apache.thrift.protocol.TField("ase", org.apache.thrift.protocol.TType.STRUCT, (short)3);
    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)4);

    private static final Map<Class<? extends IScheme>, SchemeFactory> schemes = new HashMap<Class<? extends IScheme>, SchemeFactory>();
    static {
      schemes.put(StandardScheme.class, new changeJobSubmissionPriority_resultStandardSchemeFactory());
      schemes.put(TupleScheme.class, new changeJobSubmissionPriority_resultTupleSchemeFactory());
    }

    public boolean success; // required
    public org.apache.airavata.model.error.InvalidRequestException ire; // required
    public org.apache.airavata.model.error.AiravataClientException ace; // required
    public org.apache.airavata.model.error.AiravataSystemException ase; // 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"),
      IRE((short)1, "ire"),
      ACE((short)2, "ace"),
      ASE((short)3, "ase"),
      AE((short)4, "ae");

      private static final Map<String, _Fields> byName = new HashMap<String, _Fields>();

      static {
        for (_Fields field : EnumSet.allOf(_Fields.class)) {
          byName.put(field.getFieldName(), field);
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, or null if its not found.
       */
      public static _Fields findByThriftId(int fieldId) {
        switch(fieldId) {
          case 0: // SUCCESS
            return SUCCESS;
          case 1: // IRE
            return IRE;
          case 2: // ACE
            return ACE;
          case 3: // ASE
            return ASE;
          case 4: // 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 IllegalArgumentException("Field " + fieldId + " doesn't exist!");
        return fields;
      }

      /**
       * Find the _Fields constant that matches name, or null if its not found.
       */
      public static _Fields findByName(String name) {
        return byName.get(name);
      }

      private final short _thriftId;
      private final String _fieldName;

      _Fields(short thriftId, String fieldName) {
        _thriftId = thriftId;
        _fieldName = fieldName;
      }

      public short getThriftFieldId() {
        return _thriftId;
      }

      public String getFieldName() {
        return _fieldName;
      }
    }

    // isset id assignments
    private static final int __SUCCESS_ISSET_ID = 0;
    private byte __isset_bitfield = 0;
    public static final Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
    static {
      Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new EnumMap<_Fields, org.apache.thrift.meta_data.FieldMetaData>(_Fields.class);
      tmpMap.put(_Fields.SUCCESS, new org.apache.thrift.meta_data.FieldMetaData("success", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.BOOL)));
      tmpMap.put(_Fields.IRE, new org.apache.thrift.meta_data.FieldMetaData("ire", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRUCT)));
      tmpMap.put(_Fields.ACE, new org.apache.thrift.meta_data.FieldMetaData("ace", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRUCT)));
      tmpMap.put(_Fields.ASE, new org.apache.thrift.meta_data.FieldMetaData("ase", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRUCT)));
      tmpMap.put(_Fields.AE, new org.apache.thrift.meta_data.FieldMetaData("ae", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRUCT)));
      metaDataMap = Collections.unmodifiableMap(tmpMap);
      org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(changeJobSubmissionPriority_result.class, metaDataMap);
    }

    public changeJobSubmissionPriority_result() {
    }

    public changeJobSubmissionPriority_result(
      boolean success,
      org.apache.airavata.model.error.InvalidRequestException ire,
      org.apache.airavata.model.error.AiravataClientException ace,
      org.apache.airavata.model.error.AiravataSystemException ase,
      org.apache.airavata.model.error.AuthorizationException ae)
    {
      this();
      this.success = success;
      setSuccessIsSet(true);
      this.ire = ire;
      this.ace = ace;
      this.ase = ase;
      this.ae = ae;
    }

    /**
     * Performs a deep copy on <i>other</i>.
     */
    public changeJobSubmissionPriority_result(changeJobSubmissionPriority_result other) {
      __isset_bitfield = other.__isset_bitfield;
      this.success = other.success;
      if (other.isSetIre()) {
        this.ire = new org.apache.airavata.model.error.InvalidRequestException(other.ire);
      }
      if (other.isSetAce()) {
        this.ace = new org.apache.airavata.model.error.AiravataClientException(other.ace);
      }
      if (other.isSetAse()) {
        this.ase = new org.apache.airavata.model.error.AiravataSystemException(other.ase);
      }
      if (other.isSetAe()) {
        this.ae = new org.apache.airavata.model.error.AuthorizationException(other.ae);
      }
    }

    public changeJobSubmissionPriority_result deepCopy() {
      return new changeJobSubmissionPriority_result(this);
    }

    @Override
    public void clear() {
      setSuccessIsSet(false);
      this.success = false;
      this.ire = null;
      this.ace = null;
      this.ase = null;
      this.ae = null;
    }

    public boolean isSuccess() {
      return this.success;
    }

    public changeJobSubmissionPriority_result setSuccess(boolean success) {
      this.success = success;
      setSuccessIsSet(true);
      return this;
    }

    public void unsetSuccess() {
      __isset_bitfield = EncodingUtils.clearBit(__isset_bitfield, __SUCCESS_ISSET_ID);
    }

    /** Returns true if field success is set (has been assigned a value) and false otherwise */
    public boolean isSetSuccess() {
      return EncodingUtils.testBit(__isset_bitfield, __SUCCESS_ISSET_ID);
    }

    public void setSuccessIsSet(boolean value) {
      __isset_bitfield = EncodingUtils.setBit(__isset_bitfield, __SUCCESS_ISSET_ID, value);
    }

    public org.apache.airavata.model.error.InvalidRequestException getIre() {
      return this.ire;
    }

    public changeJobSubmissionPriority_result setIre(org.apache.airavata.model.error.InvalidRequestException ire) {
      this.ire = ire;
      return this;
    }

    public void unsetIre() {
      this.ire = null;
    }

    /** Returns true if field ire is set (has been assigned a value) and false otherwise */
    public boolean isSetIre() {
      return this.ire != null;
    }

    public void setIreIsSet(boolean value) {
      if (!value) {
        this.ire = null;
      }
    }

    public org.apache.airavata.model.error.AiravataClientException getAce() {
      return this.ace;
    }

    public changeJobSubmissionPriority_result setAce(org.apache.airavata.model.error.AiravataClientException ace) {
      this.ace = ace;
      return this;
    }

    public void unsetAce() {
      this.ace = null;
    }

    /** Returns true if field ace is set (has been assigned a value) and false otherwise */
    public boolean isSetAce() {
      return this.ace != null;
    }

    public void setAceIsSet(boolean value) {
      if (!value) {
        this.ace = null;
      }
    }

    public org.apache.airavata.model.error.AiravataSystemException getAse() {
      return this.ase;
    }

    public changeJobSubmissionPriority_result setAse(org.apache.airavata.model.error.AiravataSystemException ase) {
      this.ase = ase;
      return this;
    }

    public void unsetAse() {
      this.ase = null;
    }

    /** Returns true if field ase is set (has been assigned a value) and false otherwise */
    public boolean isSetAse() {
      return this.ase != null;
    }

    public void setAseIsSet(boolean value) {
      if (!value) {
        this.ase = null;
      }
    }

    public org.apache.airavata.model.error.AuthorizationException getAe() {
      return this.ae;
    }

    public changeJobSubmissionPriority_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, Object value) {
      switch (field) {
      case SUCCESS:
        if (value == null) {
          unsetSuccess();
        } else {
          setSuccess((Boolean)value);
        }
        break;

      case IRE:
        if (value == null) {
          unsetIre();
        } else {
          setIre((org.apache.airavata.model.error.InvalidRequestException)value);
        }
        break;

      case ACE:
        if (value == null) {
          unsetAce();
        } else {
          setAce((org.apache.airavata.model.error.AiravataClientException)value);
        }
        break;

      case ASE:
        if (value == null) {
          unsetAse();
        } else {
          setAse((org.apache.airavata.model.error.AiravataSystemException)value);
        }
        break;

      case AE:
        if (value == null) {
          unsetAe();
        } else {
          setAe((org.apache.airavata.model.error.AuthorizationException)value);
        }
        break;

      }
    }

    public Object getFieldValue(_Fields field) {
      switch (field) {
      case SUCCESS:
        return Boolean.valueOf(isSuccess());

      case IRE:
        return getIre();

      case ACE:
        return getAce();

      case ASE:
        return getAse();

      case AE:
        return getAe();

      }
      throw new IllegalStateException();
    }

    /** Returns true if field corresponding to fieldID is set (has been assigned a value) and false otherwise */
    public boolean isSet(_Fields field) {
      if (field == null) {
        throw new IllegalArgumentException();
      }

      switch (field) {
      case SUCCESS:
        return isSetSuccess();
      case IRE:
        return isSetIre();
      case ACE:
        return isSetAce();
      case ASE:
        return isSetAse();
      case AE:
        return isSetAe();
      }
      throw new IllegalStateException();
    }

    @Override
    public boolean equals(Object that) {
      if (that == null)
        return false;
      if (that instanceof changeJobSubmissionPriority_result)
        return this.equals((changeJobSubmissionPriority_result)that);
      return false;
    }

    public boolean equals(changeJobSubmissionPriority_result that) {
      if (that == null)
        return false;

      boolean this_present_success = true;
      boolean that_present_success = true;
      if (this_present_success || that_present_success) {
        if (!(this_present_success && that_present_success))
          return false;
        if (this.success != that.success)
          return false;
      }

      boolean this_present_ire = true && this.isSetIre();
      boolean that_present_ire = true && that.isSetIre();
      if (this_present_ire || that_present_ire) {
        if (!(this_present_ire && that_present_ire))
          return false;
        if (!this.ire.equals(that.ire))
          return false;
      }

      boolean this_present_ace = true && this.isSetAce();
      boolean that_present_ace = true && that.isSetAce();
      if (this_present_ace || that_present_ace) {
        if (!(this_present_ace && that_present_ace))
          return false;
        if (!this.ace.equals(that.ace))
          return false;
      }

      boolean this_present_ase = true && this.isSetAse();
      boolean that_present_ase = true && that.isSetAse();
      if (this_present_ase || that_present_ase) {
        if (!(this_present_ase && that_present_ase))
          return false;
        if (!this.ase.equals(that.ase))
          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() {
      List<Object> list = new ArrayList<Object>();

      boolean present_success = true;
      list.add(present_success);
      if (present_success)
        list.add(success);

      boolean present_ire = true && (isSetIre());
      list.add(present_ire);
      if (present_ire)
        list.add(ire);

      boolean present_ace = true && (isSetAce());
      list.add(present_ace);
      if (present_ace)
        list.add(ace);

      boolean present_ase = true && (isSetAse());
      list.add(present_ase);
      if (present_ase)
        list.add(ase);

      boolean present_ae = true && (isSetAe());
      list.add(present_ae);
      if (present_ae)
        list.add(ae);

      return list.hashCode();
    }

    @Override
    public int compareTo(changeJobSubmissionPriority_result other) {
      if (!getClass().equals(other.getClass())) {
        return getClass().getName().compareTo(other.getClass().getName());
      }

      int lastComparison = 0;

      lastComparison = Boolean.valueOf(isSetSuccess()).compareTo(other.isSetSuccess());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetSuccess()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.success, other.success);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = Boolean.valueOf(isSetIre()).compareTo(other.isSetIre());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetIre()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.ire, other.ire);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = Boolean.valueOf(isSetAce()).compareTo(other.isSetAce());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetAce()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.ace, other.ace);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = Boolean.valueOf(isSetAse()).compareTo(other.isSetAse());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetAse()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.ase, other.ase);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = 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 {
      schemes.get(iprot.getScheme()).getScheme().read(iprot, this);
    }

    public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException {
      schemes.get(oprot.getScheme()).getScheme().write(oprot, this);
      }

    @Override
    public String toString() {
      StringBuilder sb = new StringBuilder("changeJobSubmissionPriority_result(");
      boolean first = true;

      sb.append("success:");
      sb.append(this.success);
      first = false;
      if (!first) sb.append(", ");
      sb.append("ire:");
      if (this.ire == null) {
        sb.append("null");
      } else {
        sb.append(this.ire);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("ace:");
      if (this.ace == null) {
        sb.append("null");
      } else {
        sb.append(this.ace);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("ase:");
      if (this.ase == null) {
        sb.append("null");
      } else {
        sb.append(this.ase);
      }
      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, 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 changeJobSubmissionPriority_resultStandardSchemeFactory implements SchemeFactory {
      public changeJobSubmissionPriority_resultStandardScheme getScheme() {
        return new changeJobSubmissionPriority_resultStandardScheme();
      }
    }

    private static class changeJobSubmissionPriority_resultStandardScheme extends StandardScheme<changeJobSubmissionPriority_result> {

      public void read(org.apache.thrift.protocol.TProtocol iprot, changeJobSubmissionPriority_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: // IRE
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.ire = new org.apache.airavata.model.error.InvalidRequestException();
                struct.ire.read(iprot);
                struct.setIreIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 2: // ACE
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.ace = new org.apache.airavata.model.error.AiravataClientException();
                struct.ace.read(iprot);
                struct.setAceIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 3: // ASE
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.ase = new org.apache.airavata.model.error.AiravataSystemException();
                struct.ase.read(iprot);
                struct.setAseIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 4: // 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, changeJobSubmissionPriority_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.ire != null) {
          oprot.writeFieldBegin(IRE_FIELD_DESC);
          struct.ire.write(oprot);
          oprot.writeFieldEnd();
        }
        if (struct.ace != null) {
          oprot.writeFieldBegin(ACE_FIELD_DESC);
          struct.ace.write(oprot);
          oprot.writeFieldEnd();
        }
        if (struct.ase != null) {
          oprot.writeFieldBegin(ASE_FIELD_DESC);
          struct.ase.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 changeJobSubmissionPriority_resultTupleSchemeFactory implements SchemeFactory {
      public changeJobSubmissionPriority_resultTupleScheme getScheme() {
        return new changeJobSubmissionPriority_resultTupleScheme();
      }
    }

    private static class changeJobSubmissionPriority_resultTupleScheme extends TupleScheme<changeJobSubmissionPriority_result> {

      @Override
      public void write(org.apache.thrift.protocol.TProtocol prot, changeJobSubmissionPriority_result struct) throws org.apache.thrift.TException {
        TTupleProtocol oprot = (TTupleProtocol) prot;
        BitSet optionals = new BitSet();
        if (struct.isSetSuccess()) {
          optionals.set(0);
        }
        if (struct.isSetIre()) {
          optionals.set(1);
        }
        if (struct.isSetAce()) {
          optionals.set(2);
        }
        if (struct.isSetAse()) {
          optionals.set(3);
        }
        if (struct.isSetAe()) {
          optionals.set(4);
        }
        oprot.writeBitSet(optionals, 5);
        if (struct.isSetSuccess()) {
          oprot.writeBool(struct.success);
        }
        if (struct.isSetIre()) {
          struct.ire.write(oprot);
        }
        if (struct.isSetAce()) {
          struct.ace.write(oprot);
        }
        if (struct.isSetAse()) {
          struct.ase.write(oprot);
        }
        if (struct.isSetAe()) {
          struct.ae.write(oprot);
        }
      }

      @Override
      public void read(org.apache.thrift.protocol.TProtocol prot, changeJobSubmissionPriority_result struct) throws org.apache.thrift.TException {
        TTupleProtocol iprot = (TTupleProtocol) prot;
        BitSet incoming = iprot.readBitSet(5);
        if (incoming.get(0)) {
          struct.success = iprot.readBool();
          struct.setSuccessIsSet(true);
        }
        if (incoming.get(1)) {
          struct.ire = new org.apache.airavata.model.error.InvalidRequestException();
          struct.ire.read(iprot);
          struct.setIreIsSet(true);
        }
        if (incoming.get(2)) {
          struct.ace = new org.apache.airavata.model.error.AiravataClientException();
          struct.ace.read(iprot);
          struct.setAceIsSet(true);
        }
        if (incoming.get(3)) {
          struct.ase = new org.apache.airavata.model.error.AiravataSystemException();
          struct.ase.read(iprot);
          struct.setAseIsSet(true);
        }
        if (incoming.get(4)) {
          struct.ae = new org.apache.airavata.model.error.AuthorizationException();
          struct.ae.read(iprot);
          struct.setAeIsSet(true);
        }
      }
    }

  }

  public static class changeDataMovementPriority_args implements org.apache.thrift.TBase<changeDataMovementPriority_args, changeDataMovementPriority_args._Fields>, java.io.Serializable, Cloneable, Comparable<changeDataMovementPriority_args>   {
    private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("changeDataMovementPriority_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 DATA_MOVEMENT_INTERFACE_ID_FIELD_DESC = new org.apache.thrift.protocol.TField("dataMovementInterfaceId", org.apache.thrift.protocol.TType.STRING, (short)2);
    private static final org.apache.thrift.protocol.TField NEW_PRIORITY_ORDER_FIELD_DESC = new org.apache.thrift.protocol.TField("newPriorityOrder", org.apache.thrift.protocol.TType.I32, (short)3);

    private static final Map<Class<? extends IScheme>, SchemeFactory> schemes = new HashMap<Class<? extends IScheme>, SchemeFactory>();
    static {
      schemes.put(StandardScheme.class, new changeDataMovementPriority_argsStandardSchemeFactory());
      schemes.put(TupleScheme.class, new changeDataMovementPriority_argsTupleSchemeFactory());
    }

    public org.apache.airavata.model.security.AuthzToken authzToken; // required
    public String dataMovementInterfaceId; // required
    public int newPriorityOrder; // required

    /** 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"),
      DATA_MOVEMENT_INTERFACE_ID((short)2, "dataMovementInterfaceId"),
      NEW_PRIORITY_ORDER((short)3, "newPriorityOrder");

      private static final Map<String, _Fields> byName = new HashMap<String, _Fields>();

      static {
        for (_Fields field : EnumSet.allOf(_Fields.class)) {
          byName.put(field.getFieldName(), field);
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, or null if its not found.
       */
      public static _Fields findByThriftId(int fieldId) {
        switch(fieldId) {
          case 1: // AUTHZ_TOKEN
            return AUTHZ_TOKEN;
          case 2: // DATA_MOVEMENT_INTERFACE_ID
            return DATA_MOVEMENT_INTERFACE_ID;
          case 3: // NEW_PRIORITY_ORDER
            return NEW_PRIORITY_ORDER;
          default:
            return null;
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, throwing an exception
       * if it is not found.
       */
      public static _Fields findByThriftIdOrThrow(int fieldId) {
        _Fields fields = findByThriftId(fieldId);
        if (fields == null) throw new IllegalArgumentException("Field " + fieldId + " doesn't exist!");
        return fields;
      }

      /**
       * Find the _Fields constant that matches name, or null if its not found.
       */
      public static _Fields findByName(String name) {
        return byName.get(name);
      }

      private final short _thriftId;
      private final String _fieldName;

      _Fields(short thriftId, String fieldName) {
        _thriftId = thriftId;
        _fieldName = fieldName;
      }

      public short getThriftFieldId() {
        return _thriftId;
      }

      public String getFieldName() {
        return _fieldName;
      }
    }

    // isset id assignments
    private static final int __NEWPRIORITYORDER_ISSET_ID = 0;
    private byte __isset_bitfield = 0;
    public static final Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
    static {
      Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new EnumMap<_Fields, org.apache.thrift.meta_data.FieldMetaData>(_Fields.class);
      tmpMap.put(_Fields.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.DATA_MOVEMENT_INTERFACE_ID, new org.apache.thrift.meta_data.FieldMetaData("dataMovementInterfaceId", org.apache.thrift.TFieldRequirementType.REQUIRED, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING)));
      tmpMap.put(_Fields.NEW_PRIORITY_ORDER, new org.apache.thrift.meta_data.FieldMetaData("newPriorityOrder", org.apache.thrift.TFieldRequirementType.REQUIRED, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.I32)));
      metaDataMap = Collections.unmodifiableMap(tmpMap);
      org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(changeDataMovementPriority_args.class, metaDataMap);
    }

    public changeDataMovementPriority_args() {
    }

    public changeDataMovementPriority_args(
      org.apache.airavata.model.security.AuthzToken authzToken,
      String dataMovementInterfaceId,
      int newPriorityOrder)
    {
      this();
      this.authzToken = authzToken;
      this.dataMovementInterfaceId = dataMovementInterfaceId;
      this.newPriorityOrder = newPriorityOrder;
      setNewPriorityOrderIsSet(true);
    }

    /**
     * Performs a deep copy on <i>other</i>.
     */
    public changeDataMovementPriority_args(changeDataMovementPriority_args other) {
      __isset_bitfield = other.__isset_bitfield;
      if (other.isSetAuthzToken()) {
        this.authzToken = new org.apache.airavata.model.security.AuthzToken(other.authzToken);
      }
      if (other.isSetDataMovementInterfaceId()) {
        this.dataMovementInterfaceId = other.dataMovementInterfaceId;
      }
      this.newPriorityOrder = other.newPriorityOrder;
    }

    public changeDataMovementPriority_args deepCopy() {
      return new changeDataMovementPriority_args(this);
    }

    @Override
    public void clear() {
      this.authzToken = null;
      this.dataMovementInterfaceId = null;
      setNewPriorityOrderIsSet(false);
      this.newPriorityOrder = 0;
    }

    public org.apache.airavata.model.security.AuthzToken getAuthzToken() {
      return this.authzToken;
    }

    public changeDataMovementPriority_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 String getDataMovementInterfaceId() {
      return this.dataMovementInterfaceId;
    }

    public changeDataMovementPriority_args setDataMovementInterfaceId(String dataMovementInterfaceId) {
      this.dataMovementInterfaceId = dataMovementInterfaceId;
      return this;
    }

    public void unsetDataMovementInterfaceId() {
      this.dataMovementInterfaceId = null;
    }

    /** Returns true if field dataMovementInterfaceId is set (has been assigned a value) and false otherwise */
    public boolean isSetDataMovementInterfaceId() {
      return this.dataMovementInterfaceId != null;
    }

    public void setDataMovementInterfaceIdIsSet(boolean value) {
      if (!value) {
        this.dataMovementInterfaceId = null;
      }
    }

    public int getNewPriorityOrder() {
      return this.newPriorityOrder;
    }

    public changeDataMovementPriority_args setNewPriorityOrder(int newPriorityOrder) {
      this.newPriorityOrder = newPriorityOrder;
      setNewPriorityOrderIsSet(true);
      return this;
    }

    public void unsetNewPriorityOrder() {
      __isset_bitfield = EncodingUtils.clearBit(__isset_bitfield, __NEWPRIORITYORDER_ISSET_ID);
    }

    /** Returns true if field newPriorityOrder is set (has been assigned a value) and false otherwise */
    public boolean isSetNewPriorityOrder() {
      return EncodingUtils.testBit(__isset_bitfield, __NEWPRIORITYORDER_ISSET_ID);
    }

    public void setNewPriorityOrderIsSet(boolean value) {
      __isset_bitfield = EncodingUtils.setBit(__isset_bitfield, __NEWPRIORITYORDER_ISSET_ID, value);
    }

    public void setFieldValue(_Fields field, Object value) {
      switch (field) {
      case AUTHZ_TOKEN:
        if (value == null) {
          unsetAuthzToken();
        } else {
          setAuthzToken((org.apache.airavata.model.security.AuthzToken)value);
        }
        break;

      case DATA_MOVEMENT_INTERFACE_ID:
        if (value == null) {
          unsetDataMovementInterfaceId();
        } else {
          setDataMovementInterfaceId((String)value);
        }
        break;

      case NEW_PRIORITY_ORDER:
        if (value == null) {
          unsetNewPriorityOrder();
        } else {
          setNewPriorityOrder((Integer)value);
        }
        break;

      }
    }

    public Object getFieldValue(_Fields field) {
      switch (field) {
      case AUTHZ_TOKEN:
        return getAuthzToken();

      case DATA_MOVEMENT_INTERFACE_ID:
        return getDataMovementInterfaceId();

      case NEW_PRIORITY_ORDER:
        return Integer.valueOf(getNewPriorityOrder());

      }
      throw new IllegalStateException();
    }

    /** Returns true if field corresponding to fieldID is set (has been assigned a value) and false otherwise */
    public boolean isSet(_Fields field) {
      if (field == null) {
        throw new IllegalArgumentException();
      }

      switch (field) {
      case AUTHZ_TOKEN:
        return isSetAuthzToken();
      case DATA_MOVEMENT_INTERFACE_ID:
        return isSetDataMovementInterfaceId();
      case NEW_PRIORITY_ORDER:
        return isSetNewPriorityOrder();
      }
      throw new IllegalStateException();
    }

    @Override
    public boolean equals(Object that) {
      if (that == null)
        return false;
      if (that instanceof changeDataMovementPriority_args)
        return this.equals((changeDataMovementPriority_args)that);
      return false;
    }

    public boolean equals(changeDataMovementPriority_args that) {
      if (that == null)
        return false;

      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_dataMovementInterfaceId = true && this.isSetDataMovementInterfaceId();
      boolean that_present_dataMovementInterfaceId = true && that.isSetDataMovementInterfaceId();
      if (this_present_dataMovementInterfaceId || that_present_dataMovementInterfaceId) {
        if (!(this_present_dataMovementInterfaceId && that_present_dataMovementInterfaceId))
          return false;
        if (!this.dataMovementInterfaceId.equals(that.dataMovementInterfaceId))
          return false;
      }

      boolean this_present_newPriorityOrder = true;
      boolean that_present_newPriorityOrder = true;
      if (this_present_newPriorityOrder || that_present_newPriorityOrder) {
        if (!(this_present_newPriorityOrder && that_present_newPriorityOrder))
          return false;
        if (this.newPriorityOrder != that.newPriorityOrder)
          return false;
      }

      return true;
    }

    @Override
    public int hashCode() {
      List<Object> list = new ArrayList<Object>();

      boolean present_authzToken = true && (isSetAuthzToken());
      list.add(present_authzToken);
      if (present_authzToken)
        list.add(authzToken);

      boolean present_dataMovementInterfaceId = true && (isSetDataMovementInterfaceId());
      list.add(present_dataMovementInterfaceId);
      if (present_dataMovementInterfaceId)
        list.add(dataMovementInterfaceId);

      boolean present_newPriorityOrder = true;
      list.add(present_newPriorityOrder);
      if (present_newPriorityOrder)
        list.add(newPriorityOrder);

      return list.hashCode();
    }

    @Override
    public int compareTo(changeDataMovementPriority_args other) {
      if (!getClass().equals(other.getClass())) {
        return getClass().getName().compareTo(other.getClass().getName());
      }

      int lastComparison = 0;

      lastComparison = 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 = Boolean.valueOf(isSetDataMovementInterfaceId()).compareTo(other.isSetDataMovementInterfaceId());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetDataMovementInterfaceId()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.dataMovementInterfaceId, other.dataMovementInterfaceId);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = Boolean.valueOf(isSetNewPriorityOrder()).compareTo(other.isSetNewPriorityOrder());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetNewPriorityOrder()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.newPriorityOrder, other.newPriorityOrder);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      return 0;
    }

    public _Fields fieldForId(int fieldId) {
      return _Fields.findByThriftId(fieldId);
    }

    public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
      schemes.get(iprot.getScheme()).getScheme().read(iprot, this);
    }

    public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException {
      schemes.get(oprot.getScheme()).getScheme().write(oprot, this);
    }

    @Override
    public String toString() {
      StringBuilder sb = new StringBuilder("changeDataMovementPriority_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("dataMovementInterfaceId:");
      if (this.dataMovementInterfaceId == null) {
        sb.append("null");
      } else {
        sb.append(this.dataMovementInterfaceId);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("newPriorityOrder:");
      sb.append(this.newPriorityOrder);
      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 (dataMovementInterfaceId == null) {
        throw new org.apache.thrift.protocol.TProtocolException("Required field 'dataMovementInterfaceId' was not present! Struct: " + toString());
      }
      // alas, we cannot check 'newPriorityOrder' because it's a primitive and you chose the non-beans generator.
      // 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, 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 changeDataMovementPriority_argsStandardSchemeFactory implements SchemeFactory {
      public changeDataMovementPriority_argsStandardScheme getScheme() {
        return new changeDataMovementPriority_argsStandardScheme();
      }
    }

    private static class changeDataMovementPriority_argsStandardScheme extends StandardScheme<changeDataMovementPriority_args> {

      public void read(org.apache.thrift.protocol.TProtocol iprot, changeDataMovementPriority_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: // DATA_MOVEMENT_INTERFACE_ID
              if (schemeField.type == org.apache.thrift.protocol.TType.STRING) {
                struct.dataMovementInterfaceId = iprot.readString();
                struct.setDataMovementInterfaceIdIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 3: // NEW_PRIORITY_ORDER
              if (schemeField.type == org.apache.thrift.protocol.TType.I32) {
                struct.newPriorityOrder = iprot.readI32();
                struct.setNewPriorityOrderIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            default:
              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
          }
          iprot.readFieldEnd();
        }
        iprot.readStructEnd();

        // check for required fields of primitive type, which can't be checked in the validate method
        if (!struct.isSetNewPriorityOrder()) {
          throw new org.apache.thrift.protocol.TProtocolException("Required field 'newPriorityOrder' was not found in serialized data! Struct: " + toString());
        }
        struct.validate();
      }

      public void write(org.apache.thrift.protocol.TProtocol oprot, changeDataMovementPriority_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.dataMovementInterfaceId != null) {
          oprot.writeFieldBegin(DATA_MOVEMENT_INTERFACE_ID_FIELD_DESC);
          oprot.writeString(struct.dataMovementInterfaceId);
          oprot.writeFieldEnd();
        }
        oprot.writeFieldBegin(NEW_PRIORITY_ORDER_FIELD_DESC);
        oprot.writeI32(struct.newPriorityOrder);
        oprot.writeFieldEnd();
        oprot.writeFieldStop();
        oprot.writeStructEnd();
      }

    }

    private static class changeDataMovementPriority_argsTupleSchemeFactory implements SchemeFactory {
      public changeDataMovementPriority_argsTupleScheme getScheme() {
        return new changeDataMovementPriority_argsTupleScheme();
      }
    }

    private static class changeDataMovementPriority_argsTupleScheme extends TupleScheme<changeDataMovementPriority_args> {

      @Override
      public void write(org.apache.thrift.protocol.TProtocol prot, changeDataMovementPriority_args struct) throws org.apache.thrift.TException {
        TTupleProtocol oprot = (TTupleProtocol) prot;
        struct.authzToken.write(oprot);
        oprot.writeString(struct.dataMovementInterfaceId);
        oprot.writeI32(struct.newPriorityOrder);
      }

      @Override
      public void read(org.apache.thrift.protocol.TProtocol prot, changeDataMovementPriority_args struct) throws org.apache.thrift.TException {
        TTupleProtocol iprot = (TTupleProtocol) prot;
        struct.authzToken = new org.apache.airavata.model.security.AuthzToken();
        struct.authzToken.read(iprot);
        struct.setAuthzTokenIsSet(true);
        struct.dataMovementInterfaceId = iprot.readString();
        struct.setDataMovementInterfaceIdIsSet(true);
        struct.newPriorityOrder = iprot.readI32();
        struct.setNewPriorityOrderIsSet(true);
      }
    }

  }

  public static class changeDataMovementPriority_result implements org.apache.thrift.TBase<changeDataMovementPriority_result, changeDataMovementPriority_result._Fields>, java.io.Serializable, Cloneable, Comparable<changeDataMovementPriority_result>   {
    private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("changeDataMovementPriority_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 IRE_FIELD_DESC = new org.apache.thrift.protocol.TField("ire", org.apache.thrift.protocol.TType.STRUCT, (short)1);
    private static final org.apache.thrift.protocol.TField ACE_FIELD_DESC = new org.apache.thrift.protocol.TField("ace", org.apache.thrift.protocol.TType.STRUCT, (short)2);
    private static final org.apache.thrift.protocol.TField ASE_FIELD_DESC = new org.apache.thrift.protocol.TField("ase", org.apache.thrift.protocol.TType.STRUCT, (short)3);
    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)4);

    private static final Map<Class<? extends IScheme>, SchemeFactory> schemes = new HashMap<Class<? extends IScheme>, SchemeFactory>();
    static {
      schemes.put(StandardScheme.class, new changeDataMovementPriority_resultStandardSchemeFactory());
      schemes.put(TupleScheme.class, new changeDataMovementPriority_resultTupleSchemeFactory());
    }

    public boolean success; // required
    public org.apache.airavata.model.error.InvalidRequestException ire; // required
    public org.apache.airavata.model.error.AiravataClientException ace; // required
    public org.apache.airavata.model.error.AiravataSystemException ase; // 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"),
      IRE((short)1, "ire"),
      ACE((short)2, "ace"),
      ASE((short)3, "ase"),
      AE((short)4, "ae");

      private static final Map<String, _Fields> byName = new HashMap<String, _Fields>();

      static {
        for (_Fields field : EnumSet.allOf(_Fields.class)) {
          byName.put(field.getFieldName(), field);
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, or null if its not found.
       */
      public static _Fields findByThriftId(int fieldId) {
        switch(fieldId) {
          case 0: // SUCCESS
            return SUCCESS;
          case 1: // IRE
            return IRE;
          case 2: // ACE
            return ACE;
          case 3: // ASE
            return ASE;
          case 4: // 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 IllegalArgumentException("Field " + fieldId + " doesn't exist!");
        return fields;
      }

      /**
       * Find the _Fields constant that matches name, or null if its not found.
       */
      public static _Fields findByName(String name) {
        return byName.get(name);
      }

      private final short _thriftId;
      private final String _fieldName;

      _Fields(short thriftId, String fieldName) {
        _thriftId = thriftId;
        _fieldName = fieldName;
      }

      public short getThriftFieldId() {
        return _thriftId;
      }

      public String getFieldName() {
        return _fieldName;
      }
    }

    // isset id assignments
    private static final int __SUCCESS_ISSET_ID = 0;
    private byte __isset_bitfield = 0;
    public static final Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
    static {
      Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new EnumMap<_Fields, org.apache.thrift.meta_data.FieldMetaData>(_Fields.class);
      tmpMap.put(_Fields.SUCCESS, new org.apache.thrift.meta_data.FieldMetaData("success", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.BOOL)));
      tmpMap.put(_Fields.IRE, new org.apache.thrift.meta_data.FieldMetaData("ire", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRUCT)));
      tmpMap.put(_Fields.ACE, new org.apache.thrift.meta_data.FieldMetaData("ace", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRUCT)));
      tmpMap.put(_Fields.ASE, new org.apache.thrift.meta_data.FieldMetaData("ase", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRUCT)));
      tmpMap.put(_Fields.AE, new org.apache.thrift.meta_data.FieldMetaData("ae", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRUCT)));
      metaDataMap = Collections.unmodifiableMap(tmpMap);
      org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(changeDataMovementPriority_result.class, metaDataMap);
    }

    public changeDataMovementPriority_result() {
    }

    public changeDataMovementPriority_result(
      boolean success,
      org.apache.airavata.model.error.InvalidRequestException ire,
      org.apache.airavata.model.error.AiravataClientException ace,
      org.apache.airavata.model.error.AiravataSystemException ase,
      org.apache.airavata.model.error.AuthorizationException ae)
    {
      this();
      this.success = success;
      setSuccessIsSet(true);
      this.ire = ire;
      this.ace = ace;
      this.ase = ase;
      this.ae = ae;
    }

    /**
     * Performs a deep copy on <i>other</i>.
     */
    public changeDataMovementPriority_result(changeDataMovementPriority_result other) {
      __isset_bitfield = other.__isset_bitfield;
      this.success = other.success;
      if (other.isSetIre()) {
        this.ire = new org.apache.airavata.model.error.InvalidRequestException(other.ire);
      }
      if (other.isSetAce()) {
        this.ace = new org.apache.airavata.model.error.AiravataClientException(other.ace);
      }
      if (other.isSetAse()) {
        this.ase = new org.apache.airavata.model.error.AiravataSystemException(other.ase);
      }
      if (other.isSetAe()) {
        this.ae = new org.apache.airavata.model.error.AuthorizationException(other.ae);
      }
    }

    public changeDataMovementPriority_result deepCopy() {
      return new changeDataMovementPriority_result(this);
    }

    @Override
    public void clear() {
      setSuccessIsSet(false);
      this.success = false;
      this.ire = null;
      this.ace = null;
      this.ase = null;
      this.ae = null;
    }

    public boolean isSuccess() {
      return this.success;
    }

    public changeDataMovementPriority_result setSuccess(boolean success) {
      this.success = success;
      setSuccessIsSet(true);
      return this;
    }

    public void unsetSuccess() {
      __isset_bitfield = EncodingUtils.clearBit(__isset_bitfield, __SUCCESS_ISSET_ID);
    }

    /** Returns true if field success is set (has been assigned a value) and false otherwise */
    public boolean isSetSuccess() {
      return EncodingUtils.testBit(__isset_bitfield, __SUCCESS_ISSET_ID);
    }

    public void setSuccessIsSet(boolean value) {
      __isset_bitfield = EncodingUtils.setBit(__isset_bitfield, __SUCCESS_ISSET_ID, value);
    }

    public org.apache.airavata.model.error.InvalidRequestException getIre() {
      return this.ire;
    }

    public changeDataMovementPriority_result setIre(org.apache.airavata.model.error.InvalidRequestException ire) {
      this.ire = ire;
      return this;
    }

    public void unsetIre() {
      this.ire = null;
    }

    /** Returns true if field ire is set (has been assigned a value) and false otherwise */
    public boolean isSetIre() {
      return this.ire != null;
    }

    public void setIreIsSet(boolean value) {
      if (!value) {
        this.ire = null;
      }
    }

    public org.apache.airavata.model.error.AiravataClientException getAce() {
      return this.ace;
    }

    public changeDataMovementPriority_result setAce(org.apache.airavata.model.error.AiravataClientException ace) {
      this.ace = ace;
      return this;
    }

    public void unsetAce() {
      this.ace = null;
    }

    /** Returns true if field ace is set (has been assigned a value) and false otherwise */
    public boolean isSetAce() {
      return this.ace != null;
    }

    public void setAceIsSet(boolean value) {
      if (!value) {
        this.ace = null;
      }
    }

    public org.apache.airavata.model.error.AiravataSystemException getAse() {
      return this.ase;
    }

    public changeDataMovementPriority_result setAse(org.apache.airavata.model.error.AiravataSystemException ase) {
      this.ase = ase;
      return this;
    }

    public void unsetAse() {
      this.ase = null;
    }

    /** Returns true if field ase is set (has been assigned a value) and false otherwise */
    public boolean isSetAse() {
      return this.ase != null;
    }

    public void setAseIsSet(boolean value) {
      if (!value) {
        this.ase = null;
      }
    }

    public org.apache.airavata.model.error.AuthorizationException getAe() {
      return this.ae;
    }

    public changeDataMovementPriority_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, Object value) {
      switch (field) {
      case SUCCESS:
        if (value == null) {
          unsetSuccess();
        } else {
          setSuccess((Boolean)value);
        }
        break;

      case IRE:
        if (value == null) {
          unsetIre();
        } else {
          setIre((org.apache.airavata.model.error.InvalidRequestException)value);
        }
        break;

      case ACE:
        if (value == null) {
          unsetAce();
        } else {
          setAce((org.apache.airavata.model.error.AiravataClientException)value);
        }
        break;

      case ASE:
        if (value == null) {
          unsetAse();
        } else {
          setAse((org.apache.airavata.model.error.AiravataSystemException)value);
        }
        break;

      case AE:
        if (value == null) {
          unsetAe();
        } else {
          setAe((org.apache.airavata.model.error.AuthorizationException)value);
        }
        break;

      }
    }

    public Object getFieldValue(_Fields field) {
      switch (field) {
      case SUCCESS:
        return Boolean.valueOf(isSuccess());

      case IRE:
        return getIre();

      case ACE:
        return getAce();

      case ASE:
        return getAse();

      case AE:
        return getAe();

      }
      throw new IllegalStateException();
    }

    /** Returns true if field corresponding to fieldID is set (has been assigned a value) and false otherwise */
    public boolean isSet(_Fields field) {
      if (field == null) {
        throw new IllegalArgumentException();
      }

      switch (field) {
      case SUCCESS:
        return isSetSuccess();
      case IRE:
        return isSetIre();
      case ACE:
        return isSetAce();
      case ASE:
        return isSetAse();
      case AE:
        return isSetAe();
      }
      throw new IllegalStateException();
    }

    @Override
    public boolean equals(Object that) {
      if (that == null)
        return false;
      if (that instanceof changeDataMovementPriority_result)
        return this.equals((changeDataMovementPriority_result)that);
      return false;
    }

    public boolean equals(changeDataMovementPriority_result that) {
      if (that == null)
        return false;

      boolean this_present_success = true;
      boolean that_present_success = true;
      if (this_present_success || that_present_success) {
        if (!(this_present_success && that_present_success))
          return false;
        if (this.success != that.success)
          return false;
      }

      boolean this_present_ire = true && this.isSetIre();
      boolean that_present_ire = true && that.isSetIre();
      if (this_present_ire || that_present_ire) {
        if (!(this_present_ire && that_present_ire))
          return false;
        if (!this.ire.equals(that.ire))
          return false;
      }

      boolean this_present_ace = true && this.isSetAce();
      boolean that_present_ace = true && that.isSetAce();
      if (this_present_ace || that_present_ace) {
        if (!(this_present_ace && that_present_ace))
          return false;
        if (!this.ace.equals(that.ace))
          return false;
      }

      boolean this_present_ase = true && this.isSetAse();
      boolean that_present_ase = true && that.isSetAse();
      if (this_present_ase || that_present_ase) {
        if (!(this_present_ase && that_present_ase))
          return false;
        if (!this.ase.equals(that.ase))
          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() {
      List<Object> list = new ArrayList<Object>();

      boolean present_success = true;
      list.add(present_success);
      if (present_success)
        list.add(success);

      boolean present_ire = true && (isSetIre());
      list.add(present_ire);
      if (present_ire)
        list.add(ire);

      boolean present_ace = true && (isSetAce());
      list.add(present_ace);
      if (present_ace)
        list.add(ace);

      boolean present_ase = true && (isSetAse());
      list.add(present_ase);
      if (present_ase)
        list.add(ase);

      boolean present_ae = true && (isSetAe());
      list.add(present_ae);
      if (present_ae)
        list.add(ae);

      return list.hashCode();
    }

    @Override
    public int compareTo(changeDataMovementPriority_result other) {
      if (!getClass().equals(other.getClass())) {
        return getClass().getName().compareTo(other.getClass().getName());
      }

      int lastComparison = 0;

      lastComparison = Boolean.valueOf(isSetSuccess()).compareTo(other.isSetSuccess());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetSuccess()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.success, other.success);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = Boolean.valueOf(isSetIre()).compareTo(other.isSetIre());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetIre()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.ire, other.ire);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = Boolean.valueOf(isSetAce()).compareTo(other.isSetAce());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetAce()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.ace, other.ace);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = Boolean.valueOf(isSetAse()).compareTo(other.isSetAse());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetAse()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.ase, other.ase);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = 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 {
      schemes.get(iprot.getScheme()).getScheme().read(iprot, this);
    }

    public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException {
      schemes.get(oprot.getScheme()).getScheme().write(oprot, this);
      }

    @Override
    public String toString() {
      StringBuilder sb = new StringBuilder("changeDataMovementPriority_result(");
      boolean first = true;

      sb.append("success:");
      sb.append(this.success);
      first = false;
      if (!first) sb.append(", ");
      sb.append("ire:");
      if (this.ire == null) {
        sb.append("null");
      } else {
        sb.append(this.ire);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("ace:");
      if (this.ace == null) {
        sb.append("null");
      } else {
        sb.append(this.ace);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("ase:");
      if (this.ase == null) {
        sb.append("null");
      } else {
        sb.append(this.ase);
      }
      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, 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 changeDataMovementPriority_resultStandardSchemeFactory implements SchemeFactory {
      public changeDataMovementPriority_resultStandardScheme getScheme() {
        return new changeDataMovementPriority_resultStandardScheme();
      }
    }

    private static class changeDataMovementPriority_resultStandardScheme extends StandardScheme<changeDataMovementPriority_result> {

      public void read(org.apache.thrift.protocol.TProtocol iprot, changeDataMovementPriority_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: // IRE
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.ire = new org.apache.airavata.model.error.InvalidRequestException();
                struct.ire.read(iprot);
                struct.setIreIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 2: // ACE
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.ace = new org.apache.airavata.model.error.AiravataClientException();
                struct.ace.read(iprot);
                struct.setAceIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 3: // ASE
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.ase = new org.apache.airavata.model.error.AiravataSystemException();
                struct.ase.read(iprot);
                struct.setAseIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 4: // 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, changeDataMovementPriority_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.ire != null) {
          oprot.writeFieldBegin(IRE_FIELD_DESC);
          struct.ire.write(oprot);
          oprot.writeFieldEnd();
        }
        if (struct.ace != null) {
          oprot.writeFieldBegin(ACE_FIELD_DESC);
          struct.ace.write(oprot);
          oprot.writeFieldEnd();
        }
        if (struct.ase != null) {
          oprot.writeFieldBegin(ASE_FIELD_DESC);
          struct.ase.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 changeDataMovementPriority_resultTupleSchemeFactory implements SchemeFactory {
      public changeDataMovementPriority_resultTupleScheme getScheme() {
        return new changeDataMovementPriority_resultTupleScheme();
      }
    }

    private static class changeDataMovementPriority_resultTupleScheme extends TupleScheme<changeDataMovementPriority_result> {

      @Override
      public void write(org.apache.thrift.protocol.TProtocol prot, changeDataMovementPriority_result struct) throws org.apache.thrift.TException {
        TTupleProtocol oprot = (TTupleProtocol) prot;
        BitSet optionals = new BitSet();
        if (struct.isSetSuccess()) {
          optionals.set(0);
        }
        if (struct.isSetIre()) {
          optionals.set(1);
        }
        if (struct.isSetAce()) {
          optionals.set(2);
        }
        if (struct.isSetAse()) {
          optionals.set(3);
        }
        if (struct.isSetAe()) {
          optionals.set(4);
        }
        oprot.writeBitSet(optionals, 5);
        if (struct.isSetSuccess()) {
          oprot.writeBool(struct.success);
        }
        if (struct.isSetIre()) {
          struct.ire.write(oprot);
        }
        if (struct.isSetAce()) {
          struct.ace.write(oprot);
        }
        if (struct.isSetAse()) {
          struct.ase.write(oprot);
        }
        if (struct.isSetAe()) {
          struct.ae.write(oprot);
        }
      }

      @Override
      public void read(org.apache.thrift.protocol.TProtocol prot, changeDataMovementPriority_result struct) throws org.apache.thrift.TException {
        TTupleProtocol iprot = (TTupleProtocol) prot;
        BitSet incoming = iprot.readBitSet(5);
        if (incoming.get(0)) {
          struct.success = iprot.readBool();
          struct.setSuccessIsSet(true);
        }
        if (incoming.get(1)) {
          struct.ire = new org.apache.airavata.model.error.InvalidRequestException();
          struct.ire.read(iprot);
          struct.setIreIsSet(true);
        }
        if (incoming.get(2)) {
          struct.ace = new org.apache.airavata.model.error.AiravataClientException();
          struct.ace.read(iprot);
          struct.setAceIsSet(true);
        }
        if (incoming.get(3)) {
          struct.ase = new org.apache.airavata.model.error.AiravataSystemException();
          struct.ase.read(iprot);
          struct.setAseIsSet(true);
        }
        if (incoming.get(4)) {
          struct.ae = new org.apache.airavata.model.error.AuthorizationException();
          struct.ae.read(iprot);
          struct.setAeIsSet(true);
        }
      }
    }

  }

  public static class changeJobSubmissionPriorities_args implements org.apache.thrift.TBase<changeJobSubmissionPriorities_args, changeJobSubmissionPriorities_args._Fields>, java.io.Serializable, Cloneable, Comparable<changeJobSubmissionPriorities_args>   {
    private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("changeJobSubmissionPriorities_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 JOB_SUBMISSION_PRIORITY_MAP_FIELD_DESC = new org.apache.thrift.protocol.TField("jobSubmissionPriorityMap", org.apache.thrift.protocol.TType.MAP, (short)2);

    private static final Map<Class<? extends IScheme>, SchemeFactory> schemes = new HashMap<Class<? extends IScheme>, SchemeFactory>();
    static {
      schemes.put(StandardScheme.class, new changeJobSubmissionPriorities_argsStandardSchemeFactory());
      schemes.put(TupleScheme.class, new changeJobSubmissionPriorities_argsTupleSchemeFactory());
    }

    public org.apache.airavata.model.security.AuthzToken authzToken; // required
    public Map<String,Integer> jobSubmissionPriorityMap; // required

    /** 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"),
      JOB_SUBMISSION_PRIORITY_MAP((short)2, "jobSubmissionPriorityMap");

      private static final Map<String, _Fields> byName = new HashMap<String, _Fields>();

      static {
        for (_Fields field : EnumSet.allOf(_Fields.class)) {
          byName.put(field.getFieldName(), field);
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, or null if its not found.
       */
      public static _Fields findByThriftId(int fieldId) {
        switch(fieldId) {
          case 1: // AUTHZ_TOKEN
            return AUTHZ_TOKEN;
          case 2: // JOB_SUBMISSION_PRIORITY_MAP
            return JOB_SUBMISSION_PRIORITY_MAP;
          default:
            return null;
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, throwing an exception
       * if it is not found.
       */
      public static _Fields findByThriftIdOrThrow(int fieldId) {
        _Fields fields = findByThriftId(fieldId);
        if (fields == null) throw new IllegalArgumentException("Field " + fieldId + " doesn't exist!");
        return fields;
      }

      /**
       * Find the _Fields constant that matches name, or null if its not found.
       */
      public static _Fields findByName(String name) {
        return byName.get(name);
      }

      private final short _thriftId;
      private final String _fieldName;

      _Fields(short thriftId, String fieldName) {
        _thriftId = thriftId;
        _fieldName = fieldName;
      }

      public short getThriftFieldId() {
        return _thriftId;
      }

      public String getFieldName() {
        return _fieldName;
      }
    }

    // isset id assignments
    public static final Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
    static {
      Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new EnumMap<_Fields, org.apache.thrift.meta_data.FieldMetaData>(_Fields.class);
      tmpMap.put(_Fields.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.JOB_SUBMISSION_PRIORITY_MAP, new org.apache.thrift.meta_data.FieldMetaData("jobSubmissionPriorityMap", org.apache.thrift.TFieldRequirementType.REQUIRED, 
          new org.apache.thrift.meta_data.MapMetaData(org.apache.thrift.protocol.TType.MAP, 
              new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING), 
              new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.I32))));
      metaDataMap = Collections.unmodifiableMap(tmpMap);
      org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(changeJobSubmissionPriorities_args.class, metaDataMap);
    }

    public changeJobSubmissionPriorities_args() {
    }

    public changeJobSubmissionPriorities_args(
      org.apache.airavata.model.security.AuthzToken authzToken,
      Map<String,Integer> jobSubmissionPriorityMap)
    {
      this();
      this.authzToken = authzToken;
      this.jobSubmissionPriorityMap = jobSubmissionPriorityMap;
    }

    /**
     * Performs a deep copy on <i>other</i>.
     */
    public changeJobSubmissionPriorities_args(changeJobSubmissionPriorities_args other) {
      if (other.isSetAuthzToken()) {
        this.authzToken = new org.apache.airavata.model.security.AuthzToken(other.authzToken);
      }
      if (other.isSetJobSubmissionPriorityMap()) {
        Map<String,Integer> __this__jobSubmissionPriorityMap = new HashMap<String,Integer>(other.jobSubmissionPriorityMap);
        this.jobSubmissionPriorityMap = __this__jobSubmissionPriorityMap;
      }
    }

    public changeJobSubmissionPriorities_args deepCopy() {
      return new changeJobSubmissionPriorities_args(this);
    }

    @Override
    public void clear() {
      this.authzToken = null;
      this.jobSubmissionPriorityMap = null;
    }

    public org.apache.airavata.model.security.AuthzToken getAuthzToken() {
      return this.authzToken;
    }

    public changeJobSubmissionPriorities_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 int getJobSubmissionPriorityMapSize() {
      return (this.jobSubmissionPriorityMap == null) ? 0 : this.jobSubmissionPriorityMap.size();
    }

    public void putToJobSubmissionPriorityMap(String key, int val) {
      if (this.jobSubmissionPriorityMap == null) {
        this.jobSubmissionPriorityMap = new HashMap<String,Integer>();
      }
      this.jobSubmissionPriorityMap.put(key, val);
    }

    public Map<String,Integer> getJobSubmissionPriorityMap() {
      return this.jobSubmissionPriorityMap;
    }

    public changeJobSubmissionPriorities_args setJobSubmissionPriorityMap(Map<String,Integer> jobSubmissionPriorityMap) {
      this.jobSubmissionPriorityMap = jobSubmissionPriorityMap;
      return this;
    }

    public void unsetJobSubmissionPriorityMap() {
      this.jobSubmissionPriorityMap = null;
    }

    /** Returns true if field jobSubmissionPriorityMap is set (has been assigned a value) and false otherwise */
    public boolean isSetJobSubmissionPriorityMap() {
      return this.jobSubmissionPriorityMap != null;
    }

    public void setJobSubmissionPriorityMapIsSet(boolean value) {
      if (!value) {
        this.jobSubmissionPriorityMap = null;
      }
    }

    public void setFieldValue(_Fields field, Object value) {
      switch (field) {
      case AUTHZ_TOKEN:
        if (value == null) {
          unsetAuthzToken();
        } else {
          setAuthzToken((org.apache.airavata.model.security.AuthzToken)value);
        }
        break;

      case JOB_SUBMISSION_PRIORITY_MAP:
        if (value == null) {
          unsetJobSubmissionPriorityMap();
        } else {
          setJobSubmissionPriorityMap((Map<String,Integer>)value);
        }
        break;

      }
    }

    public Object getFieldValue(_Fields field) {
      switch (field) {
      case AUTHZ_TOKEN:
        return getAuthzToken();

      case JOB_SUBMISSION_PRIORITY_MAP:
        return getJobSubmissionPriorityMap();

      }
      throw new IllegalStateException();
    }

    /** Returns true if field corresponding to fieldID is set (has been assigned a value) and false otherwise */
    public boolean isSet(_Fields field) {
      if (field == null) {
        throw new IllegalArgumentException();
      }

      switch (field) {
      case AUTHZ_TOKEN:
        return isSetAuthzToken();
      case JOB_SUBMISSION_PRIORITY_MAP:
        return isSetJobSubmissionPriorityMap();
      }
      throw new IllegalStateException();
    }

    @Override
    public boolean equals(Object that) {
      if (that == null)
        return false;
      if (that instanceof changeJobSubmissionPriorities_args)
        return this.equals((changeJobSubmissionPriorities_args)that);
      return false;
    }

    public boolean equals(changeJobSubmissionPriorities_args that) {
      if (that == null)
        return false;

      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_jobSubmissionPriorityMap = true && this.isSetJobSubmissionPriorityMap();
      boolean that_present_jobSubmissionPriorityMap = true && that.isSetJobSubmissionPriorityMap();
      if (this_present_jobSubmissionPriorityMap || that_present_jobSubmissionPriorityMap) {
        if (!(this_present_jobSubmissionPriorityMap && that_present_jobSubmissionPriorityMap))
          return false;
        if (!this.jobSubmissionPriorityMap.equals(that.jobSubmissionPriorityMap))
          return false;
      }

      return true;
    }

    @Override
    public int hashCode() {
      List<Object> list = new ArrayList<Object>();

      boolean present_authzToken = true && (isSetAuthzToken());
      list.add(present_authzToken);
      if (present_authzToken)
        list.add(authzToken);

      boolean present_jobSubmissionPriorityMap = true && (isSetJobSubmissionPriorityMap());
      list.add(present_jobSubmissionPriorityMap);
      if (present_jobSubmissionPriorityMap)
        list.add(jobSubmissionPriorityMap);

      return list.hashCode();
    }

    @Override
    public int compareTo(changeJobSubmissionPriorities_args other) {
      if (!getClass().equals(other.getClass())) {
        return getClass().getName().compareTo(other.getClass().getName());
      }

      int lastComparison = 0;

      lastComparison = 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 = Boolean.valueOf(isSetJobSubmissionPriorityMap()).compareTo(other.isSetJobSubmissionPriorityMap());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetJobSubmissionPriorityMap()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.jobSubmissionPriorityMap, other.jobSubmissionPriorityMap);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      return 0;
    }

    public _Fields fieldForId(int fieldId) {
      return _Fields.findByThriftId(fieldId);
    }

    public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
      schemes.get(iprot.getScheme()).getScheme().read(iprot, this);
    }

    public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException {
      schemes.get(oprot.getScheme()).getScheme().write(oprot, this);
    }

    @Override
    public String toString() {
      StringBuilder sb = new StringBuilder("changeJobSubmissionPriorities_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("jobSubmissionPriorityMap:");
      if (this.jobSubmissionPriorityMap == null) {
        sb.append("null");
      } else {
        sb.append(this.jobSubmissionPriorityMap);
      }
      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 (jobSubmissionPriorityMap == null) {
        throw new org.apache.thrift.protocol.TProtocolException("Required field 'jobSubmissionPriorityMap' 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, 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 changeJobSubmissionPriorities_argsStandardSchemeFactory implements SchemeFactory {
      public changeJobSubmissionPriorities_argsStandardScheme getScheme() {
        return new changeJobSubmissionPriorities_argsStandardScheme();
      }
    }

    private static class changeJobSubmissionPriorities_argsStandardScheme extends StandardScheme<changeJobSubmissionPriorities_args> {

      public void read(org.apache.thrift.protocol.TProtocol iprot, changeJobSubmissionPriorities_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: // JOB_SUBMISSION_PRIORITY_MAP
              if (schemeField.type == org.apache.thrift.protocol.TType.MAP) {
                {
                  org.apache.thrift.protocol.TMap _map228 = iprot.readMapBegin();
                  struct.jobSubmissionPriorityMap = new HashMap<String,Integer>(2*_map228.size);
                  String _key229;
                  int _val230;
                  for (int _i231 = 0; _i231 < _map228.size; ++_i231)
                  {
                    _key229 = iprot.readString();
                    _val230 = iprot.readI32();
                    struct.jobSubmissionPriorityMap.put(_key229, _val230);
                  }
                  iprot.readMapEnd();
                }
                struct.setJobSubmissionPriorityMapIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            default:
              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
          }
          iprot.readFieldEnd();
        }
        iprot.readStructEnd();

        // check for required fields of primitive type, which can't be checked in the validate method
        struct.validate();
      }

      public void write(org.apache.thrift.protocol.TProtocol oprot, changeJobSubmissionPriorities_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.jobSubmissionPriorityMap != null) {
          oprot.writeFieldBegin(JOB_SUBMISSION_PRIORITY_MAP_FIELD_DESC);
          {
            oprot.writeMapBegin(new org.apache.thrift.protocol.TMap(org.apache.thrift.protocol.TType.STRING, org.apache.thrift.protocol.TType.I32, struct.jobSubmissionPriorityMap.size()));
            for (Map.Entry<String, Integer> _iter232 : struct.jobSubmissionPriorityMap.entrySet())
            {
              oprot.writeString(_iter232.getKey());
              oprot.writeI32(_iter232.getValue());
            }
            oprot.writeMapEnd();
          }
          oprot.writeFieldEnd();
        }
        oprot.writeFieldStop();
        oprot.writeStructEnd();
      }

    }

    private static class changeJobSubmissionPriorities_argsTupleSchemeFactory implements SchemeFactory {
      public changeJobSubmissionPriorities_argsTupleScheme getScheme() {
        return new changeJobSubmissionPriorities_argsTupleScheme();
      }
    }

    private static class changeJobSubmissionPriorities_argsTupleScheme extends TupleScheme<changeJobSubmissionPriorities_args> {

      @Override
      public void write(org.apache.thrift.protocol.TProtocol prot, changeJobSubmissionPriorities_args struct) throws org.apache.thrift.TException {
        TTupleProtocol oprot = (TTupleProtocol) prot;
        struct.authzToken.write(oprot);
        {
          oprot.writeI32(struct.jobSubmissionPriorityMap.size());
          for (Map.Entry<String, Integer> _iter233 : struct.jobSubmissionPriorityMap.entrySet())
          {
            oprot.writeString(_iter233.getKey());
            oprot.writeI32(_iter233.getValue());
          }
        }
      }

      @Override
      public void read(org.apache.thrift.protocol.TProtocol prot, changeJobSubmissionPriorities_args struct) throws org.apache.thrift.TException {
        TTupleProtocol iprot = (TTupleProtocol) prot;
        struct.authzToken = new org.apache.airavata.model.security.AuthzToken();
        struct.authzToken.read(iprot);
        struct.setAuthzTokenIsSet(true);
        {
          org.apache.thrift.protocol.TMap _map234 = new org.apache.thrift.protocol.TMap(org.apache.thrift.protocol.TType.STRING, org.apache.thrift.protocol.TType.I32, iprot.readI32());
          struct.jobSubmissionPriorityMap = new HashMap<String,Integer>(2*_map234.size);
          String _key235;
          int _val236;
          for (int _i237 = 0; _i237 < _map234.size; ++_i237)
          {
            _key235 = iprot.readString();
            _val236 = iprot.readI32();
            struct.jobSubmissionPriorityMap.put(_key235, _val236);
          }
        }
        struct.setJobSubmissionPriorityMapIsSet(true);
      }
    }

  }

  public static class changeJobSubmissionPriorities_result implements org.apache.thrift.TBase<changeJobSubmissionPriorities_result, changeJobSubmissionPriorities_result._Fields>, java.io.Serializable, Cloneable, Comparable<changeJobSubmissionPriorities_result>   {
    private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("changeJobSubmissionPriorities_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 IRE_FIELD_DESC = new org.apache.thrift.protocol.TField("ire", org.apache.thrift.protocol.TType.STRUCT, (short)1);
    private static final org.apache.thrift.protocol.TField ACE_FIELD_DESC = new org.apache.thrift.protocol.TField("ace", org.apache.thrift.protocol.TType.STRUCT, (short)2);
    private static final org.apache.thrift.protocol.TField ASE_FIELD_DESC = new org.apache.thrift.protocol.TField("ase", org.apache.thrift.protocol.TType.STRUCT, (short)3);
    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)4);

    private static final Map<Class<? extends IScheme>, SchemeFactory> schemes = new HashMap<Class<? extends IScheme>, SchemeFactory>();
    static {
      schemes.put(StandardScheme.class, new changeJobSubmissionPriorities_resultStandardSchemeFactory());
      schemes.put(TupleScheme.class, new changeJobSubmissionPriorities_resultTupleSchemeFactory());
    }

    public boolean success; // required
    public org.apache.airavata.model.error.InvalidRequestException ire; // required
    public org.apache.airavata.model.error.AiravataClientException ace; // required
    public org.apache.airavata.model.error.AiravataSystemException ase; // 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"),
      IRE((short)1, "ire"),
      ACE((short)2, "ace"),
      ASE((short)3, "ase"),
      AE((short)4, "ae");

      private static final Map<String, _Fields> byName = new HashMap<String, _Fields>();

      static {
        for (_Fields field : EnumSet.allOf(_Fields.class)) {
          byName.put(field.getFieldName(), field);
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, or null if its not found.
       */
      public static _Fields findByThriftId(int fieldId) {
        switch(fieldId) {
          case 0: // SUCCESS
            return SUCCESS;
          case 1: // IRE
            return IRE;
          case 2: // ACE
            return ACE;
          case 3: // ASE
            return ASE;
          case 4: // 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 IllegalArgumentException("Field " + fieldId + " doesn't exist!");
        return fields;
      }

      /**
       * Find the _Fields constant that matches name, or null if its not found.
       */
      public static _Fields findByName(String name) {
        return byName.get(name);
      }

      private final short _thriftId;
      private final String _fieldName;

      _Fields(short thriftId, String fieldName) {
        _thriftId = thriftId;
        _fieldName = fieldName;
      }

      public short getThriftFieldId() {
        return _thriftId;
      }

      public String getFieldName() {
        return _fieldName;
      }
    }

    // isset id assignments
    private static final int __SUCCESS_ISSET_ID = 0;
    private byte __isset_bitfield = 0;
    public static final Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
    static {
      Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new EnumMap<_Fields, org.apache.thrift.meta_data.FieldMetaData>(_Fields.class);
      tmpMap.put(_Fields.SUCCESS, new org.apache.thrift.meta_data.FieldMetaData("success", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.BOOL)));
      tmpMap.put(_Fields.IRE, new org.apache.thrift.meta_data.FieldMetaData("ire", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRUCT)));
      tmpMap.put(_Fields.ACE, new org.apache.thrift.meta_data.FieldMetaData("ace", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRUCT)));
      tmpMap.put(_Fields.ASE, new org.apache.thrift.meta_data.FieldMetaData("ase", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRUCT)));
      tmpMap.put(_Fields.AE, new org.apache.thrift.meta_data.FieldMetaData("ae", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRUCT)));
      metaDataMap = Collections.unmodifiableMap(tmpMap);
      org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(changeJobSubmissionPriorities_result.class, metaDataMap);
    }

    public changeJobSubmissionPriorities_result() {
    }

    public changeJobSubmissionPriorities_result(
      boolean success,
      org.apache.airavata.model.error.InvalidRequestException ire,
      org.apache.airavata.model.error.AiravataClientException ace,
      org.apache.airavata.model.error.AiravataSystemException ase,
      org.apache.airavata.model.error.AuthorizationException ae)
    {
      this();
      this.success = success;
      setSuccessIsSet(true);
      this.ire = ire;
      this.ace = ace;
      this.ase = ase;
      this.ae = ae;
    }

    /**
     * Performs a deep copy on <i>other</i>.
     */
    public changeJobSubmissionPriorities_result(changeJobSubmissionPriorities_result other) {
      __isset_bitfield = other.__isset_bitfield;
      this.success = other.success;
      if (other.isSetIre()) {
        this.ire = new org.apache.airavata.model.error.InvalidRequestException(other.ire);
      }
      if (other.isSetAce()) {
        this.ace = new org.apache.airavata.model.error.AiravataClientException(other.ace);
      }
      if (other.isSetAse()) {
        this.ase = new org.apache.airavata.model.error.AiravataSystemException(other.ase);
      }
      if (other.isSetAe()) {
        this.ae = new org.apache.airavata.model.error.AuthorizationException(other.ae);
      }
    }

    public changeJobSubmissionPriorities_result deepCopy() {
      return new changeJobSubmissionPriorities_result(this);
    }

    @Override
    public void clear() {
      setSuccessIsSet(false);
      this.success = false;
      this.ire = null;
      this.ace = null;
      this.ase = null;
      this.ae = null;
    }

    public boolean isSuccess() {
      return this.success;
    }

    public changeJobSubmissionPriorities_result setSuccess(boolean success) {
      this.success = success;
      setSuccessIsSet(true);
      return this;
    }

    public void unsetSuccess() {
      __isset_bitfield = EncodingUtils.clearBit(__isset_bitfield, __SUCCESS_ISSET_ID);
    }

    /** Returns true if field success is set (has been assigned a value) and false otherwise */
    public boolean isSetSuccess() {
      return EncodingUtils.testBit(__isset_bitfield, __SUCCESS_ISSET_ID);
    }

    public void setSuccessIsSet(boolean value) {
      __isset_bitfield = EncodingUtils.setBit(__isset_bitfield, __SUCCESS_ISSET_ID, value);
    }

    public org.apache.airavata.model.error.InvalidRequestException getIre() {
      return this.ire;
    }

    public changeJobSubmissionPriorities_result setIre(org.apache.airavata.model.error.InvalidRequestException ire) {
      this.ire = ire;
      return this;
    }

    public void unsetIre() {
      this.ire = null;
    }

    /** Returns true if field ire is set (has been assigned a value) and false otherwise */
    public boolean isSetIre() {
      return this.ire != null;
    }

    public void setIreIsSet(boolean value) {
      if (!value) {
        this.ire = null;
      }
    }

    public org.apache.airavata.model.error.AiravataClientException getAce() {
      return this.ace;
    }

    public changeJobSubmissionPriorities_result setAce(org.apache.airavata.model.error.AiravataClientException ace) {
      this.ace = ace;
      return this;
    }

    public void unsetAce() {
      this.ace = null;
    }

    /** Returns true if field ace is set (has been assigned a value) and false otherwise */
    public boolean isSetAce() {
      return this.ace != null;
    }

    public void setAceIsSet(boolean value) {
      if (!value) {
        this.ace = null;
      }
    }

    public org.apache.airavata.model.error.AiravataSystemException getAse() {
      return this.ase;
    }

    public changeJobSubmissionPriorities_result setAse(org.apache.airavata.model.error.AiravataSystemException ase) {
      this.ase = ase;
      return this;
    }

    public void unsetAse() {
      this.ase = null;
    }

    /** Returns true if field ase is set (has been assigned a value) and false otherwise */
    public boolean isSetAse() {
      return this.ase != null;
    }

    public void setAseIsSet(boolean value) {
      if (!value) {
        this.ase = null;
      }
    }

    public org.apache.airavata.model.error.AuthorizationException getAe() {
      return this.ae;
    }

    public changeJobSubmissionPriorities_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, Object value) {
      switch (field) {
      case SUCCESS:
        if (value == null) {
          unsetSuccess();
        } else {
          setSuccess((Boolean)value);
        }
        break;

      case IRE:
        if (value == null) {
          unsetIre();
        } else {
          setIre((org.apache.airavata.model.error.InvalidRequestException)value);
        }
        break;

      case ACE:
        if (value == null) {
          unsetAce();
        } else {
          setAce((org.apache.airavata.model.error.AiravataClientException)value);
        }
        break;

      case ASE:
        if (value == null) {
          unsetAse();
        } else {
          setAse((org.apache.airavata.model.error.AiravataSystemException)value);
        }
        break;

      case AE:
        if (value == null) {
          unsetAe();
        } else {
          setAe((org.apache.airavata.model.error.AuthorizationException)value);
        }
        break;

      }
    }

    public Object getFieldValue(_Fields field) {
      switch (field) {
      case SUCCESS:
        return Boolean.valueOf(isSuccess());

      case IRE:
        return getIre();

      case ACE:
        return getAce();

      case ASE:
        return getAse();

      case AE:
        return getAe();

      }
      throw new IllegalStateException();
    }

    /** Returns true if field corresponding to fieldID is set (has been assigned a value) and false otherwise */
    public boolean isSet(_Fields field) {
      if (field == null) {
        throw new IllegalArgumentException();
      }

      switch (field) {
      case SUCCESS:
        return isSetSuccess();
      case IRE:
        return isSetIre();
      case ACE:
        return isSetAce();
      case ASE:
        return isSetAse();
      case AE:
        return isSetAe();
      }
      throw new IllegalStateException();
    }

    @Override
    public boolean equals(Object that) {
      if (that == null)
        return false;
      if (that instanceof changeJobSubmissionPriorities_result)
        return this.equals((changeJobSubmissionPriorities_result)that);
      return false;
    }

    public boolean equals(changeJobSubmissionPriorities_result that) {
      if (that == null)
        return false;

      boolean this_present_success = true;
      boolean that_present_success = true;
      if (this_present_success || that_present_success) {
        if (!(this_present_success && that_present_success))
          return false;
        if (this.success != that.success)
          return false;
      }

      boolean this_present_ire = true && this.isSetIre();
      boolean that_present_ire = true && that.isSetIre();
      if (this_present_ire || that_present_ire) {
        if (!(this_present_ire && that_present_ire))
          return false;
        if (!this.ire.equals(that.ire))
          return false;
      }

      boolean this_present_ace = true && this.isSetAce();
      boolean that_present_ace = true && that.isSetAce();
      if (this_present_ace || that_present_ace) {
        if (!(this_present_ace && that_present_ace))
          return false;
        if (!this.ace.equals(that.ace))
          return false;
      }

      boolean this_present_ase = true && this.isSetAse();
      boolean that_present_ase = true && that.isSetAse();
      if (this_present_ase || that_present_ase) {
        if (!(this_present_ase && that_present_ase))
          return false;
        if (!this.ase.equals(that.ase))
          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() {
      List<Object> list = new ArrayList<Object>();

      boolean present_success = true;
      list.add(present_success);
      if (present_success)
        list.add(success);

      boolean present_ire = true && (isSetIre());
      list.add(present_ire);
      if (present_ire)
        list.add(ire);

      boolean present_ace = true && (isSetAce());
      list.add(present_ace);
      if (present_ace)
        list.add(ace);

      boolean present_ase = true && (isSetAse());
      list.add(present_ase);
      if (present_ase)
        list.add(ase);

      boolean present_ae = true && (isSetAe());
      list.add(present_ae);
      if (present_ae)
        list.add(ae);

      return list.hashCode();
    }

    @Override
    public int compareTo(changeJobSubmissionPriorities_result other) {
      if (!getClass().equals(other.getClass())) {
        return getClass().getName().compareTo(other.getClass().getName());
      }

      int lastComparison = 0;

      lastComparison = Boolean.valueOf(isSetSuccess()).compareTo(other.isSetSuccess());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetSuccess()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.success, other.success);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = Boolean.valueOf(isSetIre()).compareTo(other.isSetIre());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetIre()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.ire, other.ire);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = Boolean.valueOf(isSetAce()).compareTo(other.isSetAce());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetAce()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.ace, other.ace);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = Boolean.valueOf(isSetAse()).compareTo(other.isSetAse());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetAse()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.ase, other.ase);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = 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 {
      schemes.get(iprot.getScheme()).getScheme().read(iprot, this);
    }

    public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException {
      schemes.get(oprot.getScheme()).getScheme().write(oprot, this);
      }

    @Override
    public String toString() {
      StringBuilder sb = new StringBuilder("changeJobSubmissionPriorities_result(");
      boolean first = true;

      sb.append("success:");
      sb.append(this.success);
      first = false;
      if (!first) sb.append(", ");
      sb.append("ire:");
      if (this.ire == null) {
        sb.append("null");
      } else {
        sb.append(this.ire);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("ace:");
      if (this.ace == null) {
        sb.append("null");
      } else {
        sb.append(this.ace);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("ase:");
      if (this.ase == null) {
        sb.append("null");
      } else {
        sb.append(this.ase);
      }
      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, 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 changeJobSubmissionPriorities_resultStandardSchemeFactory implements SchemeFactory {
      public changeJobSubmissionPriorities_resultStandardScheme getScheme() {
        return new changeJobSubmissionPriorities_resultStandardScheme();
      }
    }

    private static class changeJobSubmissionPriorities_resultStandardScheme extends StandardScheme<changeJobSubmissionPriorities_result> {

      public void read(org.apache.thrift.protocol.TProtocol iprot, changeJobSubmissionPriorities_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: // IRE
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.ire = new org.apache.airavata.model.error.InvalidRequestException();
                struct.ire.read(iprot);
                struct.setIreIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 2: // ACE
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.ace = new org.apache.airavata.model.error.AiravataClientException();
                struct.ace.read(iprot);
                struct.setAceIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 3: // ASE
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.ase = new org.apache.airavata.model.error.AiravataSystemException();
                struct.ase.read(iprot);
                struct.setAseIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 4: // 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, changeJobSubmissionPriorities_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.ire != null) {
          oprot.writeFieldBegin(IRE_FIELD_DESC);
          struct.ire.write(oprot);
          oprot.writeFieldEnd();
        }
        if (struct.ace != null) {
          oprot.writeFieldBegin(ACE_FIELD_DESC);
          struct.ace.write(oprot);
          oprot.writeFieldEnd();
        }
        if (struct.ase != null) {
          oprot.writeFieldBegin(ASE_FIELD_DESC);
          struct.ase.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 changeJobSubmissionPriorities_resultTupleSchemeFactory implements SchemeFactory {
      public changeJobSubmissionPriorities_resultTupleScheme getScheme() {
        return new changeJobSubmissionPriorities_resultTupleScheme();
      }
    }

    private static class changeJobSubmissionPriorities_resultTupleScheme extends TupleScheme<changeJobSubmissionPriorities_result> {

      @Override
      public void write(org.apache.thrift.protocol.TProtocol prot, changeJobSubmissionPriorities_result struct) throws org.apache.thrift.TException {
        TTupleProtocol oprot = (TTupleProtocol) prot;
        BitSet optionals = new BitSet();
        if (struct.isSetSuccess()) {
          optionals.set(0);
        }
        if (struct.isSetIre()) {
          optionals.set(1);
        }
        if (struct.isSetAce()) {
          optionals.set(2);
        }
        if (struct.isSetAse()) {
          optionals.set(3);
        }
        if (struct.isSetAe()) {
          optionals.set(4);
        }
        oprot.writeBitSet(optionals, 5);
        if (struct.isSetSuccess()) {
          oprot.writeBool(struct.success);
        }
        if (struct.isSetIre()) {
          struct.ire.write(oprot);
        }
        if (struct.isSetAce()) {
          struct.ace.write(oprot);
        }
        if (struct.isSetAse()) {
          struct.ase.write(oprot);
        }
        if (struct.isSetAe()) {
          struct.ae.write(oprot);
        }
      }

      @Override
      public void read(org.apache.thrift.protocol.TProtocol prot, changeJobSubmissionPriorities_result struct) throws org.apache.thrift.TException {
        TTupleProtocol iprot = (TTupleProtocol) prot;
        BitSet incoming = iprot.readBitSet(5);
        if (incoming.get(0)) {
          struct.success = iprot.readBool();
          struct.setSuccessIsSet(true);
        }
        if (incoming.get(1)) {
          struct.ire = new org.apache.airavata.model.error.InvalidRequestException();
          struct.ire.read(iprot);
          struct.setIreIsSet(true);
        }
        if (incoming.get(2)) {
          struct.ace = new org.apache.airavata.model.error.AiravataClientException();
          struct.ace.read(iprot);
          struct.setAceIsSet(true);
        }
        if (incoming.get(3)) {
          struct.ase = new org.apache.airavata.model.error.AiravataSystemException();
          struct.ase.read(iprot);
          struct.setAseIsSet(true);
        }
        if (incoming.get(4)) {
          struct.ae = new org.apache.airavata.model.error.AuthorizationException();
          struct.ae.read(iprot);
          struct.setAeIsSet(true);
        }
      }
    }

  }

  public static class changeDataMovementPriorities_args implements org.apache.thrift.TBase<changeDataMovementPriorities_args, changeDataMovementPriorities_args._Fields>, java.io.Serializable, Cloneable, Comparable<changeDataMovementPriorities_args>   {
    private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("changeDataMovementPriorities_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 DATA_MOVEMENT_PRIORITY_MAP_FIELD_DESC = new org.apache.thrift.protocol.TField("dataMovementPriorityMap", org.apache.thrift.protocol.TType.MAP, (short)2);

    private static final Map<Class<? extends IScheme>, SchemeFactory> schemes = new HashMap<Class<? extends IScheme>, SchemeFactory>();
    static {
      schemes.put(StandardScheme.class, new changeDataMovementPriorities_argsStandardSchemeFactory());
      schemes.put(TupleScheme.class, new changeDataMovementPriorities_argsTupleSchemeFactory());
    }

    public org.apache.airavata.model.security.AuthzToken authzToken; // required
    public Map<String,Integer> dataMovementPriorityMap; // required

    /** 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"),
      DATA_MOVEMENT_PRIORITY_MAP((short)2, "dataMovementPriorityMap");

      private static final Map<String, _Fields> byName = new HashMap<String, _Fields>();

      static {
        for (_Fields field : EnumSet.allOf(_Fields.class)) {
          byName.put(field.getFieldName(), field);
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, or null if its not found.
       */
      public static _Fields findByThriftId(int fieldId) {
        switch(fieldId) {
          case 1: // AUTHZ_TOKEN
            return AUTHZ_TOKEN;
          case 2: // DATA_MOVEMENT_PRIORITY_MAP
            return DATA_MOVEMENT_PRIORITY_MAP;
          default:
            return null;
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, throwing an exception
       * if it is not found.
       */
      public static _Fields findByThriftIdOrThrow(int fieldId) {
        _Fields fields = findByThriftId(fieldId);
        if (fields == null) throw new IllegalArgumentException("Field " + fieldId + " doesn't exist!");
        return fields;
      }

      /**
       * Find the _Fields constant that matches name, or null if its not found.
       */
      public static _Fields findByName(String name) {
        return byName.get(name);
      }

      private final short _thriftId;
      private final String _fieldName;

      _Fields(short thriftId, String fieldName) {
        _thriftId = thriftId;
        _fieldName = fieldName;
      }

      public short getThriftFieldId() {
        return _thriftId;
      }

      public String getFieldName() {
        return _fieldName;
      }
    }

    // isset id assignments
    public static final Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
    static {
      Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new EnumMap<_Fields, org.apache.thrift.meta_data.FieldMetaData>(_Fields.class);
      tmpMap.put(_Fields.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.DATA_MOVEMENT_PRIORITY_MAP, new org.apache.thrift.meta_data.FieldMetaData("dataMovementPriorityMap", org.apache.thrift.TFieldRequirementType.REQUIRED, 
          new org.apache.thrift.meta_data.MapMetaData(org.apache.thrift.protocol.TType.MAP, 
              new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING), 
              new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.I32))));
      metaDataMap = Collections.unmodifiableMap(tmpMap);
      org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(changeDataMovementPriorities_args.class, metaDataMap);
    }

    public changeDataMovementPriorities_args() {
    }

    public changeDataMovementPriorities_args(
      org.apache.airavata.model.security.AuthzToken authzToken,
      Map<String,Integer> dataMovementPriorityMap)
    {
      this();
      this.authzToken = authzToken;
      this.dataMovementPriorityMap = dataMovementPriorityMap;
    }

    /**
     * Performs a deep copy on <i>other</i>.
     */
    public changeDataMovementPriorities_args(changeDataMovementPriorities_args other) {
      if (other.isSetAuthzToken()) {
        this.authzToken = new org.apache.airavata.model.security.AuthzToken(other.authzToken);
      }
      if (other.isSetDataMovementPriorityMap()) {
        Map<String,Integer> __this__dataMovementPriorityMap = new HashMap<String,Integer>(other.dataMovementPriorityMap);
        this.dataMovementPriorityMap = __this__dataMovementPriorityMap;
      }
    }

    public changeDataMovementPriorities_args deepCopy() {
      return new changeDataMovementPriorities_args(this);
    }

    @Override
    public void clear() {
      this.authzToken = null;
      this.dataMovementPriorityMap = null;
    }

    public org.apache.airavata.model.security.AuthzToken getAuthzToken() {
      return this.authzToken;
    }

    public changeDataMovementPriorities_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 int getDataMovementPriorityMapSize() {
      return (this.dataMovementPriorityMap == null) ? 0 : this.dataMovementPriorityMap.size();
    }

    public void putToDataMovementPriorityMap(String key, int val) {
      if (this.dataMovementPriorityMap == null) {
        this.dataMovementPriorityMap = new HashMap<String,Integer>();
      }
      this.dataMovementPriorityMap.put(key, val);
    }

    public Map<String,Integer> getDataMovementPriorityMap() {
      return this.dataMovementPriorityMap;
    }

    public changeDataMovementPriorities_args setDataMovementPriorityMap(Map<String,Integer> dataMovementPriorityMap) {
      this.dataMovementPriorityMap = dataMovementPriorityMap;
      return this;
    }

    public void unsetDataMovementPriorityMap() {
      this.dataMovementPriorityMap = null;
    }

    /** Returns true if field dataMovementPriorityMap is set (has been assigned a value) and false otherwise */
    public boolean isSetDataMovementPriorityMap() {
      return this.dataMovementPriorityMap != null;
    }

    public void setDataMovementPriorityMapIsSet(boolean value) {
      if (!value) {
        this.dataMovementPriorityMap = null;
      }
    }

    public void setFieldValue(_Fields field, Object value) {
      switch (field) {
      case AUTHZ_TOKEN:
        if (value == null) {
          unsetAuthzToken();
        } else {
          setAuthzToken((org.apache.airavata.model.security.AuthzToken)value);
        }
        break;

      case DATA_MOVEMENT_PRIORITY_MAP:
        if (value == null) {
          unsetDataMovementPriorityMap();
        } else {
          setDataMovementPriorityMap((Map<String,Integer>)value);
        }
        break;

      }
    }

    public Object getFieldValue(_Fields field) {
      switch (field) {
      case AUTHZ_TOKEN:
        return getAuthzToken();

      case DATA_MOVEMENT_PRIORITY_MAP:
        return getDataMovementPriorityMap();

      }
      throw new IllegalStateException();
    }

    /** Returns true if field corresponding to fieldID is set (has been assigned a value) and false otherwise */
    public boolean isSet(_Fields field) {
      if (field == null) {
        throw new IllegalArgumentException();
      }

      switch (field) {
      case AUTHZ_TOKEN:
        return isSetAuthzToken();
      case DATA_MOVEMENT_PRIORITY_MAP:
        return isSetDataMovementPriorityMap();
      }
      throw new IllegalStateException();
    }

    @Override
    public boolean equals(Object that) {
      if (that == null)
        return false;
      if (that instanceof changeDataMovementPriorities_args)
        return this.equals((changeDataMovementPriorities_args)that);
      return false;
    }

    public boolean equals(changeDataMovementPriorities_args that) {
      if (that == null)
        return false;

      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_dataMovementPriorityMap = true && this.isSetDataMovementPriorityMap();
      boolean that_present_dataMovementPriorityMap = true && that.isSetDataMovementPriorityMap();
      if (this_present_dataMovementPriorityMap || that_present_dataMovementPriorityMap) {
        if (!(this_present_dataMovementPriorityMap && that_present_dataMovementPriorityMap))
          return false;
        if (!this.dataMovementPriorityMap.equals(that.dataMovementPriorityMap))
          return false;
      }

      return true;
    }

    @Override
    public int hashCode() {
      List<Object> list = new ArrayList<Object>();

      boolean present_authzToken = true && (isSetAuthzToken());
      list.add(present_authzToken);
      if (present_authzToken)
        list.add(authzToken);

      boolean present_dataMovementPriorityMap = true && (isSetDataMovementPriorityMap());
      list.add(present_dataMovementPriorityMap);
      if (present_dataMovementPriorityMap)
        list.add(dataMovementPriorityMap);

      return list.hashCode();
    }

    @Override
    public int compareTo(changeDataMovementPriorities_args other) {
      if (!getClass().equals(other.getClass())) {
        return getClass().getName().compareTo(other.getClass().getName());
      }

      int lastComparison = 0;

      lastComparison = 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 = Boolean.valueOf(isSetDataMovementPriorityMap()).compareTo(other.isSetDataMovementPriorityMap());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetDataMovementPriorityMap()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.dataMovementPriorityMap, other.dataMovementPriorityMap);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      return 0;
    }

    public _Fields fieldForId(int fieldId) {
      return _Fields.findByThriftId(fieldId);
    }

    public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
      schemes.get(iprot.getScheme()).getScheme().read(iprot, this);
    }

    public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException {
      schemes.get(oprot.getScheme()).getScheme().write(oprot, this);
    }

    @Override
    public String toString() {
      StringBuilder sb = new StringBuilder("changeDataMovementPriorities_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("dataMovementPriorityMap:");
      if (this.dataMovementPriorityMap == null) {
        sb.append("null");
      } else {
        sb.append(this.dataMovementPriorityMap);
      }
      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 (dataMovementPriorityMap == null) {
        throw new org.apache.thrift.protocol.TProtocolException("Required field 'dataMovementPriorityMap' 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, 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 changeDataMovementPriorities_argsStandardSchemeFactory implements SchemeFactory {
      public changeDataMovementPriorities_argsStandardScheme getScheme() {
        return new changeDataMovementPriorities_argsStandardScheme();
      }
    }

    private static class changeDataMovementPriorities_argsStandardScheme extends StandardScheme<changeDataMovementPriorities_args> {

      public void read(org.apache.thrift.protocol.TProtocol iprot, changeDataMovementPriorities_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: // DATA_MOVEMENT_PRIORITY_MAP
              if (schemeField.type == org.apache.thrift.protocol.TType.MAP) {
                {
                  org.apache.thrift.protocol.TMap _map238 = iprot.readMapBegin();
                  struct.dataMovementPriorityMap = new HashMap<String,Integer>(2*_map238.size);
                  String _key239;
                  int _val240;
                  for (int _i241 = 0; _i241 < _map238.size; ++_i241)
                  {
                    _key239 = iprot.readString();
                    _val240 = iprot.readI32();
                    struct.dataMovementPriorityMap.put(_key239, _val240);
                  }
                  iprot.readMapEnd();
                }
                struct.setDataMovementPriorityMapIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            default:
              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
          }
          iprot.readFieldEnd();
        }
        iprot.readStructEnd();

        // check for required fields of primitive type, which can't be checked in the validate method
        struct.validate();
      }

      public void write(org.apache.thrift.protocol.TProtocol oprot, changeDataMovementPriorities_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.dataMovementPriorityMap != null) {
          oprot.writeFieldBegin(DATA_MOVEMENT_PRIORITY_MAP_FIELD_DESC);
          {
            oprot.writeMapBegin(new org.apache.thrift.protocol.TMap(org.apache.thrift.protocol.TType.STRING, org.apache.thrift.protocol.TType.I32, struct.dataMovementPriorityMap.size()));
            for (Map.Entry<String, Integer> _iter242 : struct.dataMovementPriorityMap.entrySet())
            {
              oprot.writeString(_iter242.getKey());
              oprot.writeI32(_iter242.getValue());
            }
            oprot.writeMapEnd();
          }
          oprot.writeFieldEnd();
        }
        oprot.writeFieldStop();
        oprot.writeStructEnd();
      }

    }

    private static class changeDataMovementPriorities_argsTupleSchemeFactory implements SchemeFactory {
      public changeDataMovementPriorities_argsTupleScheme getScheme() {
        return new changeDataMovementPriorities_argsTupleScheme();
      }
    }

    private static class changeDataMovementPriorities_argsTupleScheme extends TupleScheme<changeDataMovementPriorities_args> {

      @Override
      public void write(org.apache.thrift.protocol.TProtocol prot, changeDataMovementPriorities_args struct) throws org.apache.thrift.TException {
        TTupleProtocol oprot = (TTupleProtocol) prot;
        struct.authzToken.write(oprot);
        {
          oprot.writeI32(struct.dataMovementPriorityMap.size());
          for (Map.Entry<String, Integer> _iter243 : struct.dataMovementPriorityMap.entrySet())
          {
            oprot.writeString(_iter243.getKey());
            oprot.writeI32(_iter243.getValue());
          }
        }
      }

      @Override
      public void read(org.apache.thrift.protocol.TProtocol prot, changeDataMovementPriorities_args struct) throws org.apache.thrift.TException {
        TTupleProtocol iprot = (TTupleProtocol) prot;
        struct.authzToken = new org.apache.airavata.model.security.AuthzToken();
        struct.authzToken.read(iprot);
        struct.setAuthzTokenIsSet(true);
        {
          org.apache.thrift.protocol.TMap _map244 = new org.apache.thrift.protocol.TMap(org.apache.thrift.protocol.TType.STRING, org.apache.thrift.protocol.TType.I32, iprot.readI32());
          struct.dataMovementPriorityMap = new HashMap<String,Integer>(2*_map244.size);
          String _key245;
          int _val246;
          for (int _i247 = 0; _i247 < _map244.size; ++_i247)
          {
            _key245 = iprot.readString();
            _val246 = iprot.readI32();
            struct.dataMovementPriorityMap.put(_key245, _val246);
          }
        }
        struct.setDataMovementPriorityMapIsSet(true);
      }
    }

  }

  public static class changeDataMovementPriorities_result implements org.apache.thrift.TBase<changeDataMovementPriorities_result, changeDataMovementPriorities_result._Fields>, java.io.Serializable, Cloneable, Comparable<changeDataMovementPriorities_result>   {
    private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("changeDataMovementPriorities_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 IRE_FIELD_DESC = new org.apache.thrift.protocol.TField("ire", org.apache.thrift.protocol.TType.STRUCT, (short)1);
    private static final org.apache.thrift.protocol.TField ACE_FIELD_DESC = new org.apache.thrift.protocol.TField("ace", org.apache.thrift.protocol.TType.STRUCT, (short)2);
    private static final org.apache.thrift.protocol.TField ASE_FIELD_DESC = new org.apache.thrift.protocol.TField("ase", org.apache.thrift.protocol.TType.STRUCT, (short)3);
    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)4);

    private static final Map<Class<? extends IScheme>, SchemeFactory> schemes = new HashMap<Class<? extends IScheme>, SchemeFactory>();
    static {
      schemes.put(StandardScheme.class, new changeDataMovementPriorities_resultStandardSchemeFactory());
      schemes.put(TupleScheme.class, new changeDataMovementPriorities_resultTupleSchemeFactory());
    }

    public boolean success; // required
    public org.apache.airavata.model.error.InvalidRequestException ire; // required
    public org.apache.airavata.model.error.AiravataClientException ace; // required
    public org.apache.airavata.model.error.AiravataSystemException ase; // 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"),
      IRE((short)1, "ire"),
      ACE((short)2, "ace"),
      ASE((short)3, "ase"),
      AE((short)4, "ae");

      private static final Map<String, _Fields> byName = new HashMap<String, _Fields>();

      static {
        for (_Fields field : EnumSet.allOf(_Fields.class)) {
          byName.put(field.getFieldName(), field);
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, or null if its not found.
       */
      public static _Fields findByThriftId(int fieldId) {
        switch(fieldId) {
          case 0: // SUCCESS
            return SUCCESS;
          case 1: // IRE
            return IRE;
          case 2: // ACE
            return ACE;
          case 3: // ASE
            return ASE;
          case 4: // 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 IllegalArgumentException("Field " + fieldId + " doesn't exist!");
        return fields;
      }

      /**
       * Find the _Fields constant that matches name, or null if its not found.
       */
      public static _Fields findByName(String name) {
        return byName.get(name);
      }

      private final short _thriftId;
      private final String _fieldName;

      _Fields(short thriftId, String fieldName) {
        _thriftId = thriftId;
        _fieldName = fieldName;
      }

      public short getThriftFieldId() {
        return _thriftId;
      }

      public String getFieldName() {
        return _fieldName;
      }
    }

    // isset id assignments
    private static final int __SUCCESS_ISSET_ID = 0;
    private byte __isset_bitfield = 0;
    public static final Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
    static {
      Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new EnumMap<_Fields, org.apache.thrift.meta_data.FieldMetaData>(_Fields.class);
      tmpMap.put(_Fields.SUCCESS, new org.apache.thrift.meta_data.FieldMetaData("success", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.BOOL)));
      tmpMap.put(_Fields.IRE, new org.apache.thrift.meta_data.FieldMetaData("ire", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRUCT)));
      tmpMap.put(_Fields.ACE, new org.apache.thrift.meta_data.FieldMetaData("ace", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRUCT)));
      tmpMap.put(_Fields.ASE, new org.apache.thrift.meta_data.FieldMetaData("ase", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRUCT)));
      tmpMap.put(_Fields.AE, new org.apache.thrift.meta_data.FieldMetaData("ae", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRUCT)));
      metaDataMap = Collections.unmodifiableMap(tmpMap);
      org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(changeDataMovementPriorities_result.class, metaDataMap);
    }

    public changeDataMovementPriorities_result() {
    }

    public changeDataMovementPriorities_result(
      boolean success,
      org.apache.airavata.model.error.InvalidRequestException ire,
      org.apache.airavata.model.error.AiravataClientException ace,
      org.apache.airavata.model.error.AiravataSystemException ase,
      org.apache.airavata.model.error.AuthorizationException ae)
    {
      this();
      this.success = success;
      setSuccessIsSet(true);
      this.ire = ire;
      this.ace = ace;
      this.ase = ase;
      this.ae = ae;
    }

    /**
     * Performs a deep copy on <i>other</i>.
     */
    public changeDataMovementPriorities_result(changeDataMovementPriorities_result other) {
      __isset_bitfield = other.__isset_bitfield;
      this.success = other.success;
      if (other.isSetIre()) {
        this.ire = new org.apache.airavata.model.error.InvalidRequestException(other.ire);
      }
      if (other.isSetAce()) {
        this.ace = new org.apache.airavata.model.error.AiravataClientException(other.ace);
      }
      if (other.isSetAse()) {
        this.ase = new org.apache.airavata.model.error.AiravataSystemException(other.ase);
      }
      if (other.isSetAe()) {
        this.ae = new org.apache.airavata.model.error.AuthorizationException(other.ae);
      }
    }

    public changeDataMovementPriorities_result deepCopy() {
      return new changeDataMovementPriorities_result(this);
    }

    @Override
    public void clear() {
      setSuccessIsSet(false);
      this.success = false;
      this.ire = null;
      this.ace = null;
      this.ase = null;
      this.ae = null;
    }

    public boolean isSuccess() {
      return this.success;
    }

    public changeDataMovementPriorities_result setSuccess(boolean success) {
      this.success = success;
      setSuccessIsSet(true);
      return this;
    }

    public void unsetSuccess() {
      __isset_bitfield = EncodingUtils.clearBit(__isset_bitfield, __SUCCESS_ISSET_ID);
    }

    /** Returns true if field success is set (has been assigned a value) and false otherwise */
    public boolean isSetSuccess() {
      return EncodingUtils.testBit(__isset_bitfield, __SUCCESS_ISSET_ID);
    }

    public void setSuccessIsSet(boolean value) {
      __isset_bitfield = EncodingUtils.setBit(__isset_bitfield, __SUCCESS_ISSET_ID, value);
    }

    public org.apache.airavata.model.error.InvalidRequestException getIre() {
      return this.ire;
    }

    public changeDataMovementPriorities_result setIre(org.apache.airavata.model.error.InvalidRequestException ire) {
      this.ire = ire;
      return this;
    }

    public void unsetIre() {
      this.ire = null;
    }

    /** Returns true if field ire is set (has been assigned a value) and false otherwise */
    public boolean isSetIre() {
      return this.ire != null;
    }

    public void setIreIsSet(boolean value) {
      if (!value) {
        this.ire = null;
      }
    }

    public org.apache.airavata.model.error.AiravataClientException getAce() {
      return this.ace;
    }

    public changeDataMovementPriorities_result setAce(org.apache.airavata.model.error.AiravataClientException ace) {
      this.ace = ace;
      return this;
    }

    public void unsetAce() {
      this.ace = null;
    }

    /** Returns true if field ace is set (has been assigned a value) and false otherwise */
    public boolean isSetAce() {
      return this.ace != null;
    }

    public void setAceIsSet(boolean value) {
      if (!value) {
        this.ace = null;
      }
    }

    public org.apache.airavata.model.error.AiravataSystemException getAse() {
      return this.ase;
    }

    public changeDataMovementPriorities_result setAse(org.apache.airavata.model.error.AiravataSystemException ase) {
      this.ase = ase;
      return this;
    }

    public void unsetAse() {
      this.ase = null;
    }

    /** Returns true if field ase is set (has been assigned a value) and false otherwise */
    public boolean isSetAse() {
      return this.ase != null;
    }

    public void setAseIsSet(boolean value) {
      if (!value) {
        this.ase = null;
      }
    }

    public org.apache.airavata.model.error.AuthorizationException getAe() {
      return this.ae;
    }

    public changeDataMovementPriorities_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, Object value) {
      switch (field) {
      case SUCCESS:
        if (value == null) {
          unsetSuccess();
        } else {
          setSuccess((Boolean)value);
        }
        break;

      case IRE:
        if (value == null) {
          unsetIre();
        } else {
          setIre((org.apache.airavata.model.error.InvalidRequestException)value);
        }
        break;

      case ACE:
        if (value == null) {
          unsetAce();
        } else {
          setAce((org.apache.airavata.model.error.AiravataClientException)value);
        }
        break;

      case ASE:
        if (value == null) {
          unsetAse();
        } else {
          setAse((org.apache.airavata.model.error.AiravataSystemException)value);
        }
        break;

      case AE:
        if (value == null) {
          unsetAe();
        } else {
          setAe((org.apache.airavata.model.error.AuthorizationException)value);
        }
        break;

      }
    }

    public Object getFieldValue(_Fields field) {
      switch (field) {
      case SUCCESS:
        return Boolean.valueOf(isSuccess());

      case IRE:
        return getIre();

      case ACE:
        return getAce();

      case ASE:
        return getAse();

      case AE:
        return getAe();

      }
      throw new IllegalStateException();
    }

    /** Returns true if field corresponding to fieldID is set (has been assigned a value) and false otherwise */
    public boolean isSet(_Fields field) {
      if (field == null) {
        throw new IllegalArgumentException();
      }

      switch (field) {
      case SUCCESS:
        return isSetSuccess();
      case IRE:
        return isSetIre();
      case ACE:
        return isSetAce();
      case ASE:
        return isSetAse();
      case AE:
        return isSetAe();
      }
      throw new IllegalStateException();
    }

    @Override
    public boolean equals(Object that) {
      if (that == null)
        return false;
      if (that instanceof changeDataMovementPriorities_result)
        return this.equals((changeDataMovementPriorities_result)that);
      return false;
    }

    public boolean equals(changeDataMovementPriorities_result that) {
      if (that == null)
        return false;

      boolean this_present_success = true;
      boolean that_present_success = true;
      if (this_present_success || that_present_success) {
        if (!(this_present_success && that_present_success))
          return false;
        if (this.success != that.success)
          return false;
      }

      boolean this_present_ire = true && this.isSetIre();
      boolean that_present_ire = true && that.isSetIre();
      if (this_present_ire || that_present_ire) {
        if (!(this_present_ire && that_present_ire))
          return false;
        if (!this.ire.equals(that.ire))
          return false;
      }

      boolean this_present_ace = true && this.isSetAce();
      boolean that_present_ace = true && that.isSetAce();
      if (this_present_ace || that_present_ace) {
        if (!(this_present_ace && that_present_ace))
          return false;
        if (!this.ace.equals(that.ace))
          return false;
      }

      boolean this_present_ase = true && this.isSetAse();
      boolean that_present_ase = true && that.isSetAse();
      if (this_present_ase || that_present_ase) {
        if (!(this_present_ase && that_present_ase))
          return false;
        if (!this.ase.equals(that.ase))
          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() {
      List<Object> list = new ArrayList<Object>();

      boolean present_success = true;
      list.add(present_success);
      if (present_success)
        list.add(success);

      boolean present_ire = true && (isSetIre());
      list.add(present_ire);
      if (present_ire)
        list.add(ire);

      boolean present_ace = true && (isSetAce());
      list.add(present_ace);
      if (present_ace)
        list.add(ace);

      boolean present_ase = true && (isSetAse());
      list.add(present_ase);
      if (present_ase)
        list.add(ase);

      boolean present_ae = true && (isSetAe());
      list.add(present_ae);
      if (present_ae)
        list.add(ae);

      return list.hashCode();
    }

    @Override
    public int compareTo(changeDataMovementPriorities_result other) {
      if (!getClass().equals(other.getClass())) {
        return getClass().getName().compareTo(other.getClass().getName());
      }

      int lastComparison = 0;

      lastComparison = Boolean.valueOf(isSetSuccess()).compareTo(other.isSetSuccess());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetSuccess()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.success, other.success);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = Boolean.valueOf(isSetIre()).compareTo(other.isSetIre());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetIre()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.ire, other.ire);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = Boolean.valueOf(isSetAce()).compareTo(other.isSetAce());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetAce()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.ace, other.ace);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = Boolean.valueOf(isSetAse()).compareTo(other.isSetAse());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetAse()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.ase, other.ase);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = 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 {
      schemes.get(iprot.getScheme()).getScheme().read(iprot, this);
    }

    public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException {
      schemes.get(oprot.getScheme()).getScheme().write(oprot, this);
      }

    @Override
    public String toString() {
      StringBuilder sb = new StringBuilder("changeDataMovementPriorities_result(");
      boolean first = true;

      sb.append("success:");
      sb.append(this.success);
      first = false;
      if (!first) sb.append(", ");
      sb.append("ire:");
      if (this.ire == null) {
        sb.append("null");
      } else {
        sb.append(this.ire);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("ace:");
      if (this.ace == null) {
        sb.append("null");
      } else {
        sb.append(this.ace);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("ase:");
      if (this.ase == null) {
        sb.append("null");
      } else {
        sb.append(this.ase);
      }
      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, 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 changeDataMovementPriorities_resultStandardSchemeFactory implements SchemeFactory {
      public changeDataMovementPriorities_resultStandardScheme getScheme() {
        return new changeDataMovementPriorities_resultStandardScheme();
      }
    }

    private static class changeDataMovementPriorities_resultStandardScheme extends StandardScheme<changeDataMovementPriorities_result> {

      public void read(org.apache.thrift.protocol.TProtocol iprot, changeDataMovementPriorities_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: // IRE
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.ire = new org.apache.airavata.model.error.InvalidRequestException();
                struct.ire.read(iprot);
                struct.setIreIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 2: // ACE
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.ace = new org.apache.airavata.model.error.AiravataClientException();
                struct.ace.read(iprot);
                struct.setAceIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 3: // ASE
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.ase = new org.apache.airavata.model.error.AiravataSystemException();
                struct.ase.read(iprot);
                struct.setAseIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 4: // 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, changeDataMovementPriorities_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.ire != null) {
          oprot.writeFieldBegin(IRE_FIELD_DESC);
          struct.ire.write(oprot);
          oprot.writeFieldEnd();
        }
        if (struct.ace != null) {
          oprot.writeFieldBegin(ACE_FIELD_DESC);
          struct.ace.write(oprot);
          oprot.writeFieldEnd();
        }
        if (struct.ase != null) {
          oprot.writeFieldBegin(ASE_FIELD_DESC);
          struct.ase.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 changeDataMovementPriorities_resultTupleSchemeFactory implements SchemeFactory {
      public changeDataMovementPriorities_resultTupleScheme getScheme() {
        return new changeDataMovementPriorities_resultTupleScheme();
      }
    }

    private static class changeDataMovementPriorities_resultTupleScheme extends TupleScheme<changeDataMovementPriorities_result> {

      @Override
      public void write(org.apache.thrift.protocol.TProtocol prot, changeDataMovementPriorities_result struct) throws org.apache.thrift.TException {
        TTupleProtocol oprot = (TTupleProtocol) prot;
        BitSet optionals = new BitSet();
        if (struct.isSetSuccess()) {
          optionals.set(0);
        }
        if (struct.isSetIre()) {
          optionals.set(1);
        }
        if (struct.isSetAce()) {
          optionals.set(2);
        }
        if (struct.isSetAse()) {
          optionals.set(3);
        }
        if (struct.isSetAe()) {
          optionals.set(4);
        }
        oprot.writeBitSet(optionals, 5);
        if (struct.isSetSuccess()) {
          oprot.writeBool(struct.success);
        }
        if (struct.isSetIre()) {
          struct.ire.write(oprot);
        }
        if (struct.isSetAce()) {
          struct.ace.write(oprot);
        }
        if (struct.isSetAse()) {
          struct.ase.write(oprot);
        }
        if (struct.isSetAe()) {
          struct.ae.write(oprot);
        }
      }

      @Override
      public void read(org.apache.thrift.protocol.TProtocol prot, changeDataMovementPriorities_result struct) throws org.apache.thrift.TException {
        TTupleProtocol iprot = (TTupleProtocol) prot;
        BitSet incoming = iprot.readBitSet(5);
        if (incoming.get(0)) {
          struct.success = iprot.readBool();
          struct.setSuccessIsSet(true);
        }
        if (incoming.get(1)) {
          struct.ire = new org.apache.airavata.model.error.InvalidRequestException();
          struct.ire.read(iprot);
          struct.setIreIsSet(true);
        }
        if (incoming.get(2)) {
          struct.ace = new org.apache.airavata.model.error.AiravataClientException();
          struct.ace.read(iprot);
          struct.setAceIsSet(true);
        }
        if (incoming.get(3)) {
          struct.ase = new org.apache.airavata.model.error.AiravataSystemException();
          struct.ase.read(iprot);
          struct.setAseIsSet(true);
        }
        if (incoming.get(4)) {
          struct.ae = new org.apache.airavata.model.error.AuthorizationException();
          struct.ae.read(iprot);
          struct.setAeIsSet(true);
        }
      }
    }

  }

  public static class deleteJobSubmissionInterface_args implements org.apache.thrift.TBase<deleteJobSubmissionInterface_args, deleteJobSubmissionInterface_args._Fields>, java.io.Serializable, Cloneable, Comparable<deleteJobSubmissionInterface_args>   {
    private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("deleteJobSubmissionInterface_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 COMPUTE_RESOURCE_ID_FIELD_DESC = new org.apache.thrift.protocol.TField("computeResourceId", org.apache.thrift.protocol.TType.STRING, (short)2);
    private static final org.apache.thrift.protocol.TField JOB_SUBMISSION_INTERFACE_ID_FIELD_DESC = new org.apache.thrift.protocol.TField("jobSubmissionInterfaceId", org.apache.thrift.protocol.TType.STRING, (short)3);

    private static final Map<Class<? extends IScheme>, SchemeFactory> schemes = new HashMap<Class<? extends IScheme>, SchemeFactory>();
    static {
      schemes.put(StandardScheme.class, new deleteJobSubmissionInterface_argsStandardSchemeFactory());
      schemes.put(TupleScheme.class, new deleteJobSubmissionInterface_argsTupleSchemeFactory());
    }

    public org.apache.airavata.model.security.AuthzToken authzToken; // required
    public String computeResourceId; // required
    public String jobSubmissionInterfaceId; // required

    /** 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"),
      COMPUTE_RESOURCE_ID((short)2, "computeResourceId"),
      JOB_SUBMISSION_INTERFACE_ID((short)3, "jobSubmissionInterfaceId");

      private static final Map<String, _Fields> byName = new HashMap<String, _Fields>();

      static {
        for (_Fields field : EnumSet.allOf(_Fields.class)) {
          byName.put(field.getFieldName(), field);
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, or null if its not found.
       */
      public static _Fields findByThriftId(int fieldId) {
        switch(fieldId) {
          case 1: // AUTHZ_TOKEN
            return AUTHZ_TOKEN;
          case 2: // COMPUTE_RESOURCE_ID
            return COMPUTE_RESOURCE_ID;
          case 3: // JOB_SUBMISSION_INTERFACE_ID
            return JOB_SUBMISSION_INTERFACE_ID;
          default:
            return null;
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, throwing an exception
       * if it is not found.
       */
      public static _Fields findByThriftIdOrThrow(int fieldId) {
        _Fields fields = findByThriftId(fieldId);
        if (fields == null) throw new IllegalArgumentException("Field " + fieldId + " doesn't exist!");
        return fields;
      }

      /**
       * Find the _Fields constant that matches name, or null if its not found.
       */
      public static _Fields findByName(String name) {
        return byName.get(name);
      }

      private final short _thriftId;
      private final String _fieldName;

      _Fields(short thriftId, String fieldName) {
        _thriftId = thriftId;
        _fieldName = fieldName;
      }

      public short getThriftFieldId() {
        return _thriftId;
      }

      public String getFieldName() {
        return _fieldName;
      }
    }

    // isset id assignments
    public static final Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
    static {
      Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new EnumMap<_Fields, org.apache.thrift.meta_data.FieldMetaData>(_Fields.class);
      tmpMap.put(_Fields.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.COMPUTE_RESOURCE_ID, new org.apache.thrift.meta_data.FieldMetaData("computeResourceId", org.apache.thrift.TFieldRequirementType.REQUIRED, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING)));
      tmpMap.put(_Fields.JOB_SUBMISSION_INTERFACE_ID, new org.apache.thrift.meta_data.FieldMetaData("jobSubmissionInterfaceId", org.apache.thrift.TFieldRequirementType.REQUIRED, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING)));
      metaDataMap = Collections.unmodifiableMap(tmpMap);
      org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(deleteJobSubmissionInterface_args.class, metaDataMap);
    }

    public deleteJobSubmissionInterface_args() {
    }

    public deleteJobSubmissionInterface_args(
      org.apache.airavata.model.security.AuthzToken authzToken,
      String computeResourceId,
      String jobSubmissionInterfaceId)
    {
      this();
      this.authzToken = authzToken;
      this.computeResourceId = computeResourceId;
      this.jobSubmissionInterfaceId = jobSubmissionInterfaceId;
    }

    /**
     * Performs a deep copy on <i>other</i>.
     */
    public deleteJobSubmissionInterface_args(deleteJobSubmissionInterface_args other) {
      if (other.isSetAuthzToken()) {
        this.authzToken = new org.apache.airavata.model.security.AuthzToken(other.authzToken);
      }
      if (other.isSetComputeResourceId()) {
        this.computeResourceId = other.computeResourceId;
      }
      if (other.isSetJobSubmissionInterfaceId()) {
        this.jobSubmissionInterfaceId = other.jobSubmissionInterfaceId;
      }
    }

    public deleteJobSubmissionInterface_args deepCopy() {
      return new deleteJobSubmissionInterface_args(this);
    }

    @Override
    public void clear() {
      this.authzToken = null;
      this.computeResourceId = null;
      this.jobSubmissionInterfaceId = null;
    }

    public org.apache.airavata.model.security.AuthzToken getAuthzToken() {
      return this.authzToken;
    }

    public deleteJobSubmissionInterface_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 String getComputeResourceId() {
      return this.computeResourceId;
    }

    public deleteJobSubmissionInterface_args setComputeResourceId(String computeResourceId) {
      this.computeResourceId = computeResourceId;
      return this;
    }

    public void unsetComputeResourceId() {
      this.computeResourceId = null;
    }

    /** Returns true if field computeResourceId is set (has been assigned a value) and false otherwise */
    public boolean isSetComputeResourceId() {
      return this.computeResourceId != null;
    }

    public void setComputeResourceIdIsSet(boolean value) {
      if (!value) {
        this.computeResourceId = null;
      }
    }

    public String getJobSubmissionInterfaceId() {
      return this.jobSubmissionInterfaceId;
    }

    public deleteJobSubmissionInterface_args setJobSubmissionInterfaceId(String jobSubmissionInterfaceId) {
      this.jobSubmissionInterfaceId = jobSubmissionInterfaceId;
      return this;
    }

    public void unsetJobSubmissionInterfaceId() {
      this.jobSubmissionInterfaceId = null;
    }

    /** Returns true if field jobSubmissionInterfaceId is set (has been assigned a value) and false otherwise */
    public boolean isSetJobSubmissionInterfaceId() {
      return this.jobSubmissionInterfaceId != null;
    }

    public void setJobSubmissionInterfaceIdIsSet(boolean value) {
      if (!value) {
        this.jobSubmissionInterfaceId = null;
      }
    }

    public void setFieldValue(_Fields field, Object value) {
      switch (field) {
      case AUTHZ_TOKEN:
        if (value == null) {
          unsetAuthzToken();
        } else {
          setAuthzToken((org.apache.airavata.model.security.AuthzToken)value);
        }
        break;

      case COMPUTE_RESOURCE_ID:
        if (value == null) {
          unsetComputeResourceId();
        } else {
          setComputeResourceId((String)value);
        }
        break;

      case JOB_SUBMISSION_INTERFACE_ID:
        if (value == null) {
          unsetJobSubmissionInterfaceId();
        } else {
          setJobSubmissionInterfaceId((String)value);
        }
        break;

      }
    }

    public Object getFieldValue(_Fields field) {
      switch (field) {
      case AUTHZ_TOKEN:
        return getAuthzToken();

      case COMPUTE_RESOURCE_ID:
        return getComputeResourceId();

      case JOB_SUBMISSION_INTERFACE_ID:
        return getJobSubmissionInterfaceId();

      }
      throw new IllegalStateException();
    }

    /** Returns true if field corresponding to fieldID is set (has been assigned a value) and false otherwise */
    public boolean isSet(_Fields field) {
      if (field == null) {
        throw new IllegalArgumentException();
      }

      switch (field) {
      case AUTHZ_TOKEN:
        return isSetAuthzToken();
      case COMPUTE_RESOURCE_ID:
        return isSetComputeResourceId();
      case JOB_SUBMISSION_INTERFACE_ID:
        return isSetJobSubmissionInterfaceId();
      }
      throw new IllegalStateException();
    }

    @Override
    public boolean equals(Object that) {
      if (that == null)
        return false;
      if (that instanceof deleteJobSubmissionInterface_args)
        return this.equals((deleteJobSubmissionInterface_args)that);
      return false;
    }

    public boolean equals(deleteJobSubmissionInterface_args that) {
      if (that == null)
        return false;

      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_computeResourceId = true && this.isSetComputeResourceId();
      boolean that_present_computeResourceId = true && that.isSetComputeResourceId();
      if (this_present_computeResourceId || that_present_computeResourceId) {
        if (!(this_present_computeResourceId && that_present_computeResourceId))
          return false;
        if (!this.computeResourceId.equals(that.computeResourceId))
          return false;
      }

      boolean this_present_jobSubmissionInterfaceId = true && this.isSetJobSubmissionInterfaceId();
      boolean that_present_jobSubmissionInterfaceId = true && that.isSetJobSubmissionInterfaceId();
      if (this_present_jobSubmissionInterfaceId || that_present_jobSubmissionInterfaceId) {
        if (!(this_present_jobSubmissionInterfaceId && that_present_jobSubmissionInterfaceId))
          return false;
        if (!this.jobSubmissionInterfaceId.equals(that.jobSubmissionInterfaceId))
          return false;
      }

      return true;
    }

    @Override
    public int hashCode() {
      List<Object> list = new ArrayList<Object>();

      boolean present_authzToken = true && (isSetAuthzToken());
      list.add(present_authzToken);
      if (present_authzToken)
        list.add(authzToken);

      boolean present_computeResourceId = true && (isSetComputeResourceId());
      list.add(present_computeResourceId);
      if (present_computeResourceId)
        list.add(computeResourceId);

      boolean present_jobSubmissionInterfaceId = true && (isSetJobSubmissionInterfaceId());
      list.add(present_jobSubmissionInterfaceId);
      if (present_jobSubmissionInterfaceId)
        list.add(jobSubmissionInterfaceId);

      return list.hashCode();
    }

    @Override
    public int compareTo(deleteJobSubmissionInterface_args other) {
      if (!getClass().equals(other.getClass())) {
        return getClass().getName().compareTo(other.getClass().getName());
      }

      int lastComparison = 0;

      lastComparison = 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 = Boolean.valueOf(isSetComputeResourceId()).compareTo(other.isSetComputeResourceId());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetComputeResourceId()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.computeResourceId, other.computeResourceId);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = Boolean.valueOf(isSetJobSubmissionInterfaceId()).compareTo(other.isSetJobSubmissionInterfaceId());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetJobSubmissionInterfaceId()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.jobSubmissionInterfaceId, other.jobSubmissionInterfaceId);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      return 0;
    }

    public _Fields fieldForId(int fieldId) {
      return _Fields.findByThriftId(fieldId);
    }

    public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
      schemes.get(iprot.getScheme()).getScheme().read(iprot, this);
    }

    public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException {
      schemes.get(oprot.getScheme()).getScheme().write(oprot, this);
    }

    @Override
    public String toString() {
      StringBuilder sb = new StringBuilder("deleteJobSubmissionInterface_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("computeResourceId:");
      if (this.computeResourceId == null) {
        sb.append("null");
      } else {
        sb.append(this.computeResourceId);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("jobSubmissionInterfaceId:");
      if (this.jobSubmissionInterfaceId == null) {
        sb.append("null");
      } else {
        sb.append(this.jobSubmissionInterfaceId);
      }
      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 (computeResourceId == null) {
        throw new org.apache.thrift.protocol.TProtocolException("Required field 'computeResourceId' was not present! Struct: " + toString());
      }
      if (jobSubmissionInterfaceId == null) {
        throw new org.apache.thrift.protocol.TProtocolException("Required field 'jobSubmissionInterfaceId' 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, 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 deleteJobSubmissionInterface_argsStandardSchemeFactory implements SchemeFactory {
      public deleteJobSubmissionInterface_argsStandardScheme getScheme() {
        return new deleteJobSubmissionInterface_argsStandardScheme();
      }
    }

    private static class deleteJobSubmissionInterface_argsStandardScheme extends StandardScheme<deleteJobSubmissionInterface_args> {

      public void read(org.apache.thrift.protocol.TProtocol iprot, deleteJobSubmissionInterface_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: // COMPUTE_RESOURCE_ID
              if (schemeField.type == org.apache.thrift.protocol.TType.STRING) {
                struct.computeResourceId = iprot.readString();
                struct.setComputeResourceIdIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 3: // JOB_SUBMISSION_INTERFACE_ID
              if (schemeField.type == org.apache.thrift.protocol.TType.STRING) {
                struct.jobSubmissionInterfaceId = iprot.readString();
                struct.setJobSubmissionInterfaceIdIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            default:
              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
          }
          iprot.readFieldEnd();
        }
        iprot.readStructEnd();

        // check for required fields of primitive type, which can't be checked in the validate method
        struct.validate();
      }

      public void write(org.apache.thrift.protocol.TProtocol oprot, deleteJobSubmissionInterface_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.computeResourceId != null) {
          oprot.writeFieldBegin(COMPUTE_RESOURCE_ID_FIELD_DESC);
          oprot.writeString(struct.computeResourceId);
          oprot.writeFieldEnd();
        }
        if (struct.jobSubmissionInterfaceId != null) {
          oprot.writeFieldBegin(JOB_SUBMISSION_INTERFACE_ID_FIELD_DESC);
          oprot.writeString(struct.jobSubmissionInterfaceId);
          oprot.writeFieldEnd();
        }
        oprot.writeFieldStop();
        oprot.writeStructEnd();
      }

    }

    private static class deleteJobSubmissionInterface_argsTupleSchemeFactory implements SchemeFactory {
      public deleteJobSubmissionInterface_argsTupleScheme getScheme() {
        return new deleteJobSubmissionInterface_argsTupleScheme();
      }
    }

    private static class deleteJobSubmissionInterface_argsTupleScheme extends TupleScheme<deleteJobSubmissionInterface_args> {

      @Override
      public void write(org.apache.thrift.protocol.TProtocol prot, deleteJobSubmissionInterface_args struct) throws org.apache.thrift.TException {
        TTupleProtocol oprot = (TTupleProtocol) prot;
        struct.authzToken.write(oprot);
        oprot.writeString(struct.computeResourceId);
        oprot.writeString(struct.jobSubmissionInterfaceId);
      }

      @Override
      public void read(org.apache.thrift.protocol.TProtocol prot, deleteJobSubmissionInterface_args struct) throws org.apache.thrift.TException {
        TTupleProtocol iprot = (TTupleProtocol) prot;
        struct.authzToken = new org.apache.airavata.model.security.AuthzToken();
        struct.authzToken.read(iprot);
        struct.setAuthzTokenIsSet(true);
        struct.computeResourceId = iprot.readString();
        struct.setComputeResourceIdIsSet(true);
        struct.jobSubmissionInterfaceId = iprot.readString();
        struct.setJobSubmissionInterfaceIdIsSet(true);
      }
    }

  }

  public static class deleteJobSubmissionInterface_result implements org.apache.thrift.TBase<deleteJobSubmissionInterface_result, deleteJobSubmissionInterface_result._Fields>, java.io.Serializable, Cloneable, Comparable<deleteJobSubmissionInterface_result>   {
    private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("deleteJobSubmissionInterface_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 IRE_FIELD_DESC = new org.apache.thrift.protocol.TField("ire", org.apache.thrift.protocol.TType.STRUCT, (short)1);
    private static final org.apache.thrift.protocol.TField ACE_FIELD_DESC = new org.apache.thrift.protocol.TField("ace", org.apache.thrift.protocol.TType.STRUCT, (short)2);
    private static final org.apache.thrift.protocol.TField ASE_FIELD_DESC = new org.apache.thrift.protocol.TField("ase", org.apache.thrift.protocol.TType.STRUCT, (short)3);
    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)4);

    private static final Map<Class<? extends IScheme>, SchemeFactory> schemes = new HashMap<Class<? extends IScheme>, SchemeFactory>();
    static {
      schemes.put(StandardScheme.class, new deleteJobSubmissionInterface_resultStandardSchemeFactory());
      schemes.put(TupleScheme.class, new deleteJobSubmissionInterface_resultTupleSchemeFactory());
    }

    public boolean success; // required
    public org.apache.airavata.model.error.InvalidRequestException ire; // required
    public org.apache.airavata.model.error.AiravataClientException ace; // required
    public org.apache.airavata.model.error.AiravataSystemException ase; // 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"),
      IRE((short)1, "ire"),
      ACE((short)2, "ace"),
      ASE((short)3, "ase"),
      AE((short)4, "ae");

      private static final Map<String, _Fields> byName = new HashMap<String, _Fields>();

      static {
        for (_Fields field : EnumSet.allOf(_Fields.class)) {
          byName.put(field.getFieldName(), field);
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, or null if its not found.
       */
      public static _Fields findByThriftId(int fieldId) {
        switch(fieldId) {
          case 0: // SUCCESS
            return SUCCESS;
          case 1: // IRE
            return IRE;
          case 2: // ACE
            return ACE;
          case 3: // ASE
            return ASE;
          case 4: // 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 IllegalArgumentException("Field " + fieldId + " doesn't exist!");
        return fields;
      }

      /**
       * Find the _Fields constant that matches name, or null if its not found.
       */
      public static _Fields findByName(String name) {
        return byName.get(name);
      }

      private final short _thriftId;
      private final String _fieldName;

      _Fields(short thriftId, String fieldName) {
        _thriftId = thriftId;
        _fieldName = fieldName;
      }

      public short getThriftFieldId() {
        return _thriftId;
      }

      public String getFieldName() {
        return _fieldName;
      }
    }

    // isset id assignments
    private static final int __SUCCESS_ISSET_ID = 0;
    private byte __isset_bitfield = 0;
    public static final Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
    static {
      Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new EnumMap<_Fields, org.apache.thrift.meta_data.FieldMetaData>(_Fields.class);
      tmpMap.put(_Fields.SUCCESS, new org.apache.thrift.meta_data.FieldMetaData("success", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.BOOL)));
      tmpMap.put(_Fields.IRE, new org.apache.thrift.meta_data.FieldMetaData("ire", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRUCT)));
      tmpMap.put(_Fields.ACE, new org.apache.thrift.meta_data.FieldMetaData("ace", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRUCT)));
      tmpMap.put(_Fields.ASE, new org.apache.thrift.meta_data.FieldMetaData("ase", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRUCT)));
      tmpMap.put(_Fields.AE, new org.apache.thrift.meta_data.FieldMetaData("ae", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRUCT)));
      metaDataMap = Collections.unmodifiableMap(tmpMap);
      org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(deleteJobSubmissionInterface_result.class, metaDataMap);
    }

    public deleteJobSubmissionInterface_result() {
    }

    public deleteJobSubmissionInterface_result(
      boolean success,
      org.apache.airavata.model.error.InvalidRequestException ire,
      org.apache.airavata.model.error.AiravataClientException ace,
      org.apache.airavata.model.error.AiravataSystemException ase,
      org.apache.airavata.model.error.AuthorizationException ae)
    {
      this();
      this.success = success;
      setSuccessIsSet(true);
      this.ire = ire;
      this.ace = ace;
      this.ase = ase;
      this.ae = ae;
    }

    /**
     * Performs a deep copy on <i>other</i>.
     */
    public deleteJobSubmissionInterface_result(deleteJobSubmissionInterface_result other) {
      __isset_bitfield = other.__isset_bitfield;
      this.success = other.success;
      if (other.isSetIre()) {
        this.ire = new org.apache.airavata.model.error.InvalidRequestException(other.ire);
      }
      if (other.isSetAce()) {
        this.ace = new org.apache.airavata.model.error.AiravataClientException(other.ace);
      }
      if (other.isSetAse()) {
        this.ase = new org.apache.airavata.model.error.AiravataSystemException(other.ase);
      }
      if (other.isSetAe()) {
        this.ae = new org.apache.airavata.model.error.AuthorizationException(other.ae);
      }
    }

    public deleteJobSubmissionInterface_result deepCopy() {
      return new deleteJobSubmissionInterface_result(this);
    }

    @Override
    public void clear() {
      setSuccessIsSet(false);
      this.success = false;
      this.ire = null;
      this.ace = null;
      this.ase = null;
      this.ae = null;
    }

    public boolean isSuccess() {
      return this.success;
    }

    public deleteJobSubmissionInterface_result setSuccess(boolean success) {
      this.success = success;
      setSuccessIsSet(true);
      return this;
    }

    public void unsetSuccess() {
      __isset_bitfield = EncodingUtils.clearBit(__isset_bitfield, __SUCCESS_ISSET_ID);
    }

    /** Returns true if field success is set (has been assigned a value) and false otherwise */
    public boolean isSetSuccess() {
      return EncodingUtils.testBit(__isset_bitfield, __SUCCESS_ISSET_ID);
    }

    public void setSuccessIsSet(boolean value) {
      __isset_bitfield = EncodingUtils.setBit(__isset_bitfield, __SUCCESS_ISSET_ID, value);
    }

    public org.apache.airavata.model.error.InvalidRequestException getIre() {
      return this.ire;
    }

    public deleteJobSubmissionInterface_result setIre(org.apache.airavata.model.error.InvalidRequestException ire) {
      this.ire = ire;
      return this;
    }

    public void unsetIre() {
      this.ire = null;
    }

    /** Returns true if field ire is set (has been assigned a value) and false otherwise */
    public boolean isSetIre() {
      return this.ire != null;
    }

    public void setIreIsSet(boolean value) {
      if (!value) {
        this.ire = null;
      }
    }

    public org.apache.airavata.model.error.AiravataClientException getAce() {
      return this.ace;
    }

    public deleteJobSubmissionInterface_result setAce(org.apache.airavata.model.error.AiravataClientException ace) {
      this.ace = ace;
      return this;
    }

    public void unsetAce() {
      this.ace = null;
    }

    /** Returns true if field ace is set (has been assigned a value) and false otherwise */
    public boolean isSetAce() {
      return this.ace != null;
    }

    public void setAceIsSet(boolean value) {
      if (!value) {
        this.ace = null;
      }
    }

    public org.apache.airavata.model.error.AiravataSystemException getAse() {
      return this.ase;
    }

    public deleteJobSubmissionInterface_result setAse(org.apache.airavata.model.error.AiravataSystemException ase) {
      this.ase = ase;
      return this;
    }

    public void unsetAse() {
      this.ase = null;
    }

    /** Returns true if field ase is set (has been assigned a value) and false otherwise */
    public boolean isSetAse() {
      return this.ase != null;
    }

    public void setAseIsSet(boolean value) {
      if (!value) {
        this.ase = null;
      }
    }

    public org.apache.airavata.model.error.AuthorizationException getAe() {
      return this.ae;
    }

    public deleteJobSubmissionInterface_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, Object value) {
      switch (field) {
      case SUCCESS:
        if (value == null) {
          unsetSuccess();
        } else {
          setSuccess((Boolean)value);
        }
        break;

      case IRE:
        if (value == null) {
          unsetIre();
        } else {
          setIre((org.apache.airavata.model.error.InvalidRequestException)value);
        }
        break;

      case ACE:
        if (value == null) {
          unsetAce();
        } else {
          setAce((org.apache.airavata.model.error.AiravataClientException)value);
        }
        break;

      case ASE:
        if (value == null) {
          unsetAse();
        } else {
          setAse((org.apache.airavata.model.error.AiravataSystemException)value);
        }
        break;

      case AE:
        if (value == null) {
          unsetAe();
        } else {
          setAe((org.apache.airavata.model.error.AuthorizationException)value);
        }
        break;

      }
    }

    public Object getFieldValue(_Fields field) {
      switch (field) {
      case SUCCESS:
        return Boolean.valueOf(isSuccess());

      case IRE:
        return getIre();

      case ACE:
        return getAce();

      case ASE:
        return getAse();

      case AE:
        return getAe();

      }
      throw new IllegalStateException();
    }

    /** Returns true if field corresponding to fieldID is set (has been assigned a value) and false otherwise */
    public boolean isSet(_Fields field) {
      if (field == null) {
        throw new IllegalArgumentException();
      }

      switch (field) {
      case SUCCESS:
        return isSetSuccess();
      case IRE:
        return isSetIre();
      case ACE:
        return isSetAce();
      case ASE:
        return isSetAse();
      case AE:
        return isSetAe();
      }
      throw new IllegalStateException();
    }

    @Override
    public boolean equals(Object that) {
      if (that == null)
        return false;
      if (that instanceof deleteJobSubmissionInterface_result)
        return this.equals((deleteJobSubmissionInterface_result)that);
      return false;
    }

    public boolean equals(deleteJobSubmissionInterface_result that) {
      if (that == null)
        return false;

      boolean this_present_success = true;
      boolean that_present_success = true;
      if (this_present_success || that_present_success) {
        if (!(this_present_success && that_present_success))
          return false;
        if (this.success != that.success)
          return false;
      }

      boolean this_present_ire = true && this.isSetIre();
      boolean that_present_ire = true && that.isSetIre();
      if (this_present_ire || that_present_ire) {
        if (!(this_present_ire && that_present_ire))
          return false;
        if (!this.ire.equals(that.ire))
          return false;
      }

      boolean this_present_ace = true && this.isSetAce();
      boolean that_present_ace = true && that.isSetAce();
      if (this_present_ace || that_present_ace) {
        if (!(this_present_ace && that_present_ace))
          return false;
        if (!this.ace.equals(that.ace))
          return false;
      }

      boolean this_present_ase = true && this.isSetAse();
      boolean that_present_ase = true && that.isSetAse();
      if (this_present_ase || that_present_ase) {
        if (!(this_present_ase && that_present_ase))
          return false;
        if (!this.ase.equals(that.ase))
          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() {
      List<Object> list = new ArrayList<Object>();

      boolean present_success = true;
      list.add(present_success);
      if (present_success)
        list.add(success);

      boolean present_ire = true && (isSetIre());
      list.add(present_ire);
      if (present_ire)
        list.add(ire);

      boolean present_ace = true && (isSetAce());
      list.add(present_ace);
      if (present_ace)
        list.add(ace);

      boolean present_ase = true && (isSetAse());
      list.add(present_ase);
      if (present_ase)
        list.add(ase);

      boolean present_ae = true && (isSetAe());
      list.add(present_ae);
      if (present_ae)
        list.add(ae);

      return list.hashCode();
    }

    @Override
    public int compareTo(deleteJobSubmissionInterface_result other) {
      if (!getClass().equals(other.getClass())) {
        return getClass().getName().compareTo(other.getClass().getName());
      }

      int lastComparison = 0;

      lastComparison = Boolean.valueOf(isSetSuccess()).compareTo(other.isSetSuccess());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetSuccess()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.success, other.success);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = Boolean.valueOf(isSetIre()).compareTo(other.isSetIre());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetIre()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.ire, other.ire);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = Boolean.valueOf(isSetAce()).compareTo(other.isSetAce());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetAce()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.ace, other.ace);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = Boolean.valueOf(isSetAse()).compareTo(other.isSetAse());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetAse()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.ase, other.ase);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = 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 {
      schemes.get(iprot.getScheme()).getScheme().read(iprot, this);
    }

    public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException {
      schemes.get(oprot.getScheme()).getScheme().write(oprot, this);
      }

    @Override
    public String toString() {
      StringBuilder sb = new StringBuilder("deleteJobSubmissionInterface_result(");
      boolean first = true;

      sb.append("success:");
      sb.append(this.success);
      first = false;
      if (!first) sb.append(", ");
      sb.append("ire:");
      if (this.ire == null) {
        sb.append("null");
      } else {
        sb.append(this.ire);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("ace:");
      if (this.ace == null) {
        sb.append("null");
      } else {
        sb.append(this.ace);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("ase:");
      if (this.ase == null) {
        sb.append("null");
      } else {
        sb.append(this.ase);
      }
      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, 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 deleteJobSubmissionInterface_resultStandardSchemeFactory implements SchemeFactory {
      public deleteJobSubmissionInterface_resultStandardScheme getScheme() {
        return new deleteJobSubmissionInterface_resultStandardScheme();
      }
    }

    private static class deleteJobSubmissionInterface_resultStandardScheme extends StandardScheme<deleteJobSubmissionInterface_result> {

      public void read(org.apache.thrift.protocol.TProtocol iprot, deleteJobSubmissionInterface_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: // IRE
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.ire = new org.apache.airavata.model.error.InvalidRequestException();
                struct.ire.read(iprot);
                struct.setIreIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 2: // ACE
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.ace = new org.apache.airavata.model.error.AiravataClientException();
                struct.ace.read(iprot);
                struct.setAceIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 3: // ASE
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.ase = new org.apache.airavata.model.error.AiravataSystemException();
                struct.ase.read(iprot);
                struct.setAseIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 4: // 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, deleteJobSubmissionInterface_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.ire != null) {
          oprot.writeFieldBegin(IRE_FIELD_DESC);
          struct.ire.write(oprot);
          oprot.writeFieldEnd();
        }
        if (struct.ace != null) {
          oprot.writeFieldBegin(ACE_FIELD_DESC);
          struct.ace.write(oprot);
          oprot.writeFieldEnd();
        }
        if (struct.ase != null) {
          oprot.writeFieldBegin(ASE_FIELD_DESC);
          struct.ase.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 deleteJobSubmissionInterface_resultTupleSchemeFactory implements SchemeFactory {
      public deleteJobSubmissionInterface_resultTupleScheme getScheme() {
        return new deleteJobSubmissionInterface_resultTupleScheme();
      }
    }

    private static class deleteJobSubmissionInterface_resultTupleScheme extends TupleScheme<deleteJobSubmissionInterface_result> {

      @Override
      public void write(org.apache.thrift.protocol.TProtocol prot, deleteJobSubmissionInterface_result struct) throws org.apache.thrift.TException {
        TTupleProtocol oprot = (TTupleProtocol) prot;
        BitSet optionals = new BitSet();
        if (struct.isSetSuccess()) {
          optionals.set(0);
        }
        if (struct.isSetIre()) {
          optionals.set(1);
        }
        if (struct.isSetAce()) {
          optionals.set(2);
        }
        if (struct.isSetAse()) {
          optionals.set(3);
        }
        if (struct.isSetAe()) {
          optionals.set(4);
        }
        oprot.writeBitSet(optionals, 5);
        if (struct.isSetSuccess()) {
          oprot.writeBool(struct.success);
        }
        if (struct.isSetIre()) {
          struct.ire.write(oprot);
        }
        if (struct.isSetAce()) {
          struct.ace.write(oprot);
        }
        if (struct.isSetAse()) {
          struct.ase.write(oprot);
        }
        if (struct.isSetAe()) {
          struct.ae.write(oprot);
        }
      }

      @Override
      public void read(org.apache.thrift.protocol.TProtocol prot, deleteJobSubmissionInterface_result struct) throws org.apache.thrift.TException {
        TTupleProtocol iprot = (TTupleProtocol) prot;
        BitSet incoming = iprot.readBitSet(5);
        if (incoming.get(0)) {
          struct.success = iprot.readBool();
          struct.setSuccessIsSet(true);
        }
        if (incoming.get(1)) {
          struct.ire = new org.apache.airavata.model.error.InvalidRequestException();
          struct.ire.read(iprot);
          struct.setIreIsSet(true);
        }
        if (incoming.get(2)) {
          struct.ace = new org.apache.airavata.model.error.AiravataClientException();
          struct.ace.read(iprot);
          struct.setAceIsSet(true);
        }
        if (incoming.get(3)) {
          struct.ase = new org.apache.airavata.model.error.AiravataSystemException();
          struct.ase.read(iprot);
          struct.setAseIsSet(true);
        }
        if (incoming.get(4)) {
          struct.ae = new org.apache.airavata.model.error.AuthorizationException();
          struct.ae.read(iprot);
          struct.setAeIsSet(true);
        }
      }
    }

  }

  public static class deleteDataMovementInterface_args implements org.apache.thrift.TBase<deleteDataMovementInterface_args, deleteDataMovementInterface_args._Fields>, java.io.Serializable, Cloneable, Comparable<deleteDataMovementInterface_args>   {
    private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("deleteDataMovementInterface_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 COMPUTE_RESOURCE_ID_FIELD_DESC = new org.apache.thrift.protocol.TField("computeResourceId", org.apache.thrift.protocol.TType.STRING, (short)2);
    private static final org.apache.thrift.protocol.TField DATA_MOVEMENT_INTERFACE_ID_FIELD_DESC = new org.apache.thrift.protocol.TField("dataMovementInterfaceId", org.apache.thrift.protocol.TType.STRING, (short)3);

    private static final Map<Class<? extends IScheme>, SchemeFactory> schemes = new HashMap<Class<? extends IScheme>, SchemeFactory>();
    static {
      schemes.put(StandardScheme.class, new deleteDataMovementInterface_argsStandardSchemeFactory());
      schemes.put(TupleScheme.class, new deleteDataMovementInterface_argsTupleSchemeFactory());
    }

    public org.apache.airavata.model.security.AuthzToken authzToken; // required
    public String computeResourceId; // required
    public String dataMovementInterfaceId; // required

    /** 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"),
      COMPUTE_RESOURCE_ID((short)2, "computeResourceId"),
      DATA_MOVEMENT_INTERFACE_ID((short)3, "dataMovementInterfaceId");

      private static final Map<String, _Fields> byName = new HashMap<String, _Fields>();

      static {
        for (_Fields field : EnumSet.allOf(_Fields.class)) {
          byName.put(field.getFieldName(), field);
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, or null if its not found.
       */
      public static _Fields findByThriftId(int fieldId) {
        switch(fieldId) {
          case 1: // AUTHZ_TOKEN
            return AUTHZ_TOKEN;
          case 2: // COMPUTE_RESOURCE_ID
            return COMPUTE_RESOURCE_ID;
          case 3: // DATA_MOVEMENT_INTERFACE_ID
            return DATA_MOVEMENT_INTERFACE_ID;
          default:
            return null;
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, throwing an exception
       * if it is not found.
       */
      public static _Fields findByThriftIdOrThrow(int fieldId) {
        _Fields fields = findByThriftId(fieldId);
        if (fields == null) throw new IllegalArgumentException("Field " + fieldId + " doesn't exist!");
        return fields;
      }

      /**
       * Find the _Fields constant that matches name, or null if its not found.
       */
      public static _Fields findByName(String name) {
        return byName.get(name);
      }

      private final short _thriftId;
      private final String _fieldName;

      _Fields(short thriftId, String fieldName) {
        _thriftId = thriftId;
        _fieldName = fieldName;
      }

      public short getThriftFieldId() {
        return _thriftId;
      }

      public String getFieldName() {
        return _fieldName;
      }
    }

    // isset id assignments
    public static final Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
    static {
      Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new EnumMap<_Fields, org.apache.thrift.meta_data.FieldMetaData>(_Fields.class);
      tmpMap.put(_Fields.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.COMPUTE_RESOURCE_ID, new org.apache.thrift.meta_data.FieldMetaData("computeResourceId", org.apache.thrift.TFieldRequirementType.REQUIRED, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING)));
      tmpMap.put(_Fields.DATA_MOVEMENT_INTERFACE_ID, new org.apache.thrift.meta_data.FieldMetaData("dataMovementInterfaceId", org.apache.thrift.TFieldRequirementType.REQUIRED, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING)));
      metaDataMap = Collections.unmodifiableMap(tmpMap);
      org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(deleteDataMovementInterface_args.class, metaDataMap);
    }

    public deleteDataMovementInterface_args() {
    }

    public deleteDataMovementInterface_args(
      org.apache.airavata.model.security.AuthzToken authzToken,
      String computeResourceId,
      String dataMovementInterfaceId)
    {
      this();
      this.authzToken = authzToken;
      this.computeResourceId = computeResourceId;
      this.dataMovementInterfaceId = dataMovementInterfaceId;
    }

    /**
     * Performs a deep copy on <i>other</i>.
     */
    public deleteDataMovementInterface_args(deleteDataMovementInterface_args other) {
      if (other.isSetAuthzToken()) {
        this.authzToken = new org.apache.airavata.model.security.AuthzToken(other.authzToken);
      }
      if (other.isSetComputeResourceId()) {
        this.computeResourceId = other.computeResourceId;
      }
      if (other.isSetDataMovementInterfaceId()) {
        this.dataMovementInterfaceId = other.dataMovementInterfaceId;
      }
    }

    public deleteDataMovementInterface_args deepCopy() {
      return new deleteDataMovementInterface_args(this);
    }

    @Override
    public void clear() {
      this.authzToken = null;
      this.computeResourceId = null;
      this.dataMovementInterfaceId = null;
    }

    public org.apache.airavata.model.security.AuthzToken getAuthzToken() {
      return this.authzToken;
    }

    public deleteDataMovementInterface_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 String getComputeResourceId() {
      return this.computeResourceId;
    }

    public deleteDataMovementInterface_args setComputeResourceId(String computeResourceId) {
      this.computeResourceId = computeResourceId;
      return this;
    }

    public void unsetComputeResourceId() {
      this.computeResourceId = null;
    }

    /** Returns true if field computeResourceId is set (has been assigned a value) and false otherwise */
    public boolean isSetComputeResourceId() {
      return this.computeResourceId != null;
    }

    public void setComputeResourceIdIsSet(boolean value) {
      if (!value) {
        this.computeResourceId = null;
      }
    }

    public String getDataMovementInterfaceId() {
      return this.dataMovementInterfaceId;
    }

    public deleteDataMovementInterface_args setDataMovementInterfaceId(String dataMovementInterfaceId) {
      this.dataMovementInterfaceId = dataMovementInterfaceId;
      return this;
    }

    public void unsetDataMovementInterfaceId() {
      this.dataMovementInterfaceId = null;
    }

    /** Returns true if field dataMovementInterfaceId is set (has been assigned a value) and false otherwise */
    public boolean isSetDataMovementInterfaceId() {
      return this.dataMovementInterfaceId != null;
    }

    public void setDataMovementInterfaceIdIsSet(boolean value) {
      if (!value) {
        this.dataMovementInterfaceId = null;
      }
    }

    public void setFieldValue(_Fields field, Object value) {
      switch (field) {
      case AUTHZ_TOKEN:
        if (value == null) {
          unsetAuthzToken();
        } else {
          setAuthzToken((org.apache.airavata.model.security.AuthzToken)value);
        }
        break;

      case COMPUTE_RESOURCE_ID:
        if (value == null) {
          unsetComputeResourceId();
        } else {
          setComputeResourceId((String)value);
        }
        break;

      case DATA_MOVEMENT_INTERFACE_ID:
        if (value == null) {
          unsetDataMovementInterfaceId();
        } else {
          setDataMovementInterfaceId((String)value);
        }
        break;

      }
    }

    public Object getFieldValue(_Fields field) {
      switch (field) {
      case AUTHZ_TOKEN:
        return getAuthzToken();

      case COMPUTE_RESOURCE_ID:
        return getComputeResourceId();

      case DATA_MOVEMENT_INTERFACE_ID:
        return getDataMovementInterfaceId();

      }
      throw new IllegalStateException();
    }

    /** Returns true if field corresponding to fieldID is set (has been assigned a value) and false otherwise */
    public boolean isSet(_Fields field) {
      if (field == null) {
        throw new IllegalArgumentException();
      }

      switch (field) {
      case AUTHZ_TOKEN:
        return isSetAuthzToken();
      case COMPUTE_RESOURCE_ID:
        return isSetComputeResourceId();
      case DATA_MOVEMENT_INTERFACE_ID:
        return isSetDataMovementInterfaceId();
      }
      throw new IllegalStateException();
    }

    @Override
    public boolean equals(Object that) {
      if (that == null)
        return false;
      if (that instanceof deleteDataMovementInterface_args)
        return this.equals((deleteDataMovementInterface_args)that);
      return false;
    }

    public boolean equals(deleteDataMovementInterface_args that) {
      if (that == null)
        return false;

      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_computeResourceId = true && this.isSetComputeResourceId();
      boolean that_present_computeResourceId = true && that.isSetComputeResourceId();
      if (this_present_computeResourceId || that_present_computeResourceId) {
        if (!(this_present_computeResourceId && that_present_computeResourceId))
          return false;
        if (!this.computeResourceId.equals(that.computeResourceId))
          return false;
      }

      boolean this_present_dataMovementInterfaceId = true && this.isSetDataMovementInterfaceId();
      boolean that_present_dataMovementInterfaceId = true && that.isSetDataMovementInterfaceId();
      if (this_present_dataMovementInterfaceId || that_present_dataMovementInterfaceId) {
        if (!(this_present_dataMovementInterfaceId && that_present_dataMovementInterfaceId))
          return false;
        if (!this.dataMovementInterfaceId.equals(that.dataMovementInterfaceId))
          return false;
      }

      return true;
    }

    @Override
    public int hashCode() {
      List<Object> list = new ArrayList<Object>();

      boolean present_authzToken = true && (isSetAuthzToken());
      list.add(present_authzToken);
      if (present_authzToken)
        list.add(authzToken);

      boolean present_computeResourceId = true && (isSetComputeResourceId());
      list.add(present_computeResourceId);
      if (present_computeResourceId)
        list.add(computeResourceId);

      boolean present_dataMovementInterfaceId = true && (isSetDataMovementInterfaceId());
      list.add(present_dataMovementInterfaceId);
      if (present_dataMovementInterfaceId)
        list.add(dataMovementInterfaceId);

      return list.hashCode();
    }

    @Override
    public int compareTo(deleteDataMovementInterface_args other) {
      if (!getClass().equals(other.getClass())) {
        return getClass().getName().compareTo(other.getClass().getName());
      }

      int lastComparison = 0;

      lastComparison = 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 = Boolean.valueOf(isSetComputeResourceId()).compareTo(other.isSetComputeResourceId());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetComputeResourceId()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.computeResourceId, other.computeResourceId);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = Boolean.valueOf(isSetDataMovementInterfaceId()).compareTo(other.isSetDataMovementInterfaceId());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetDataMovementInterfaceId()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.dataMovementInterfaceId, other.dataMovementInterfaceId);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      return 0;
    }

    public _Fields fieldForId(int fieldId) {
      return _Fields.findByThriftId(fieldId);
    }

    public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
      schemes.get(iprot.getScheme()).getScheme().read(iprot, this);
    }

    public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException {
      schemes.get(oprot.getScheme()).getScheme().write(oprot, this);
    }

    @Override
    public String toString() {
      StringBuilder sb = new StringBuilder("deleteDataMovementInterface_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("computeResourceId:");
      if (this.computeResourceId == null) {
        sb.append("null");
      } else {
        sb.append(this.computeResourceId);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("dataMovementInterfaceId:");
      if (this.dataMovementInterfaceId == null) {
        sb.append("null");
      } else {
        sb.append(this.dataMovementInterfaceId);
      }
      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 (computeResourceId == null) {
        throw new org.apache.thrift.protocol.TProtocolException("Required field 'computeResourceId' was not present! Struct: " + toString());
      }
      if (dataMovementInterfaceId == null) {
        throw new org.apache.thrift.protocol.TProtocolException("Required field 'dataMovementInterfaceId' 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, 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 deleteDataMovementInterface_argsStandardSchemeFactory implements SchemeFactory {
      public deleteDataMovementInterface_argsStandardScheme getScheme() {
        return new deleteDataMovementInterface_argsStandardScheme();
      }
    }

    private static class deleteDataMovementInterface_argsStandardScheme extends StandardScheme<deleteDataMovementInterface_args> {

      public void read(org.apache.thrift.protocol.TProtocol iprot, deleteDataMovementInterface_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: // COMPUTE_RESOURCE_ID
              if (schemeField.type == org.apache.thrift.protocol.TType.STRING) {
                struct.computeResourceId = iprot.readString();
                struct.setComputeResourceIdIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 3: // DATA_MOVEMENT_INTERFACE_ID
              if (schemeField.type == org.apache.thrift.protocol.TType.STRING) {
                struct.dataMovementInterfaceId = iprot.readString();
                struct.setDataMovementInterfaceIdIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            default:
              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
          }
          iprot.readFieldEnd();
        }
        iprot.readStructEnd();

        // check for required fields of primitive type, which can't be checked in the validate method
        struct.validate();
      }

      public void write(org.apache.thrift.protocol.TProtocol oprot, deleteDataMovementInterface_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.computeResourceId != null) {
          oprot.writeFieldBegin(COMPUTE_RESOURCE_ID_FIELD_DESC);
          oprot.writeString(struct.computeResourceId);
          oprot.writeFieldEnd();
        }
        if (struct.dataMovementInterfaceId != null) {
          oprot.writeFieldBegin(DATA_MOVEMENT_INTERFACE_ID_FIELD_DESC);
          oprot.writeString(struct.dataMovementInterfaceId);
          oprot.writeFieldEnd();
        }
        oprot.writeFieldStop();
        oprot.writeStructEnd();
      }

    }

    private static class deleteDataMovementInterface_argsTupleSchemeFactory implements SchemeFactory {
      public deleteDataMovementInterface_argsTupleScheme getScheme() {
        return new deleteDataMovementInterface_argsTupleScheme();
      }
    }

    private static class deleteDataMovementInterface_argsTupleScheme extends TupleScheme<deleteDataMovementInterface_args> {

      @Override
      public void write(org.apache.thrift.protocol.TProtocol prot, deleteDataMovementInterface_args struct) throws org.apache.thrift.TException {
        TTupleProtocol oprot = (TTupleProtocol) prot;
        struct.authzToken.write(oprot);
        oprot.writeString(struct.computeResourceId);
        oprot.writeString(struct.dataMovementInterfaceId);
      }

      @Override
      public void read(org.apache.thrift.protocol.TProtocol prot, deleteDataMovementInterface_args struct) throws org.apache.thrift.TException {
        TTupleProtocol iprot = (TTupleProtocol) prot;
        struct.authzToken = new org.apache.airavata.model.security.AuthzToken();
        struct.authzToken.read(iprot);
        struct.setAuthzTokenIsSet(true);
        struct.computeResourceId = iprot.readString();
        struct.setComputeResourceIdIsSet(true);
        struct.dataMovementInterfaceId = iprot.readString();
        struct.setDataMovementInterfaceIdIsSet(true);
      }
    }

  }

  public static class deleteDataMovementInterface_result implements org.apache.thrift.TBase<deleteDataMovementInterface_result, deleteDataMovementInterface_result._Fields>, java.io.Serializable, Cloneable, Comparable<deleteDataMovementInterface_result>   {
    private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("deleteDataMovementInterface_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 IRE_FIELD_DESC = new org.apache.thrift.protocol.TField("ire", org.apache.thrift.protocol.TType.STRUCT, (short)1);
    private static final org.apache.thrift.protocol.TField ACE_FIELD_DESC = new org.apache.thrift.protocol.TField("ace", org.apache.thrift.protocol.TType.STRUCT, (short)2);
    private static final org.apache.thrift.protocol.TField ASE_FIELD_DESC = new org.apache.thrift.protocol.TField("ase", org.apache.thrift.protocol.TType.STRUCT, (short)3);
    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)4);

    private static final Map<Class<? extends IScheme>, SchemeFactory> schemes = new HashMap<Class<? extends IScheme>, SchemeFactory>();
    static {
      schemes.put(StandardScheme.class, new deleteDataMovementInterface_resultStandardSchemeFactory());
      schemes.put(TupleScheme.class, new deleteDataMovementInterface_resultTupleSchemeFactory());
    }

    public boolean success; // required
    public org.apache.airavata.model.error.InvalidRequestException ire; // required
    public org.apache.airavata.model.error.AiravataClientException ace; // required
    public org.apache.airavata.model.error.AiravataSystemException ase; // 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"),
      IRE((short)1, "ire"),
      ACE((short)2, "ace"),
      ASE((short)3, "ase"),
      AE((short)4, "ae");

      private static final Map<String, _Fields> byName = new HashMap<String, _Fields>();

      static {
        for (_Fields field : EnumSet.allOf(_Fields.class)) {
          byName.put(field.getFieldName(), field);
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, or null if its not found.
       */
      public static _Fields findByThriftId(int fieldId) {
        switch(fieldId) {
          case 0: // SUCCESS
            return SUCCESS;
          case 1: // IRE
            return IRE;
          case 2: // ACE
            return ACE;
          case 3: // ASE
            return ASE;
          case 4: // 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 IllegalArgumentException("Field " + fieldId + " doesn't exist!");
        return fields;
      }

      /**
       * Find the _Fields constant that matches name, or null if its not found.
       */
      public static _Fields findByName(String name) {
        return byName.get(name);
      }

      private final short _thriftId;
      private final String _fieldName;

      _Fields(short thriftId, String fieldName) {
        _thriftId = thriftId;
        _fieldName = fieldName;
      }

      public short getThriftFieldId() {
        return _thriftId;
      }

      public String getFieldName() {
        return _fieldName;
      }
    }

    // isset id assignments
    private static final int __SUCCESS_ISSET_ID = 0;
    private byte __isset_bitfield = 0;
    public static final Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
    static {
      Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new EnumMap<_Fields, org.apache.thrift.meta_data.FieldMetaData>(_Fields.class);
      tmpMap.put(_Fields.SUCCESS, new org.apache.thrift.meta_data.FieldMetaData("success", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.BOOL)));
      tmpMap.put(_Fields.IRE, new org.apache.thrift.meta_data.FieldMetaData("ire", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRUCT)));
      tmpMap.put(_Fields.ACE, new org.apache.thrift.meta_data.FieldMetaData("ace", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRUCT)));
      tmpMap.put(_Fields.ASE, new org.apache.thrift.meta_data.FieldMetaData("ase", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRUCT)));
      tmpMap.put(_Fields.AE, new org.apache.thrift.meta_data.FieldMetaData("ae", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRUCT)));
      metaDataMap = Collections.unmodifiableMap(tmpMap);
      org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(deleteDataMovementInterface_result.class, metaDataMap);
    }

    public deleteDataMovementInterface_result() {
    }

    public deleteDataMovementInterface_result(
      boolean success,
      org.apache.airavata.model.error.InvalidRequestException ire,
      org.apache.airavata.model.error.AiravataClientException ace,
      org.apache.airavata.model.error.AiravataSystemException ase,
      org.apache.airavata.model.error.AuthorizationException ae)
    {
      this();
      this.success = success;
      setSuccessIsSet(true);
      this.ire = ire;
      this.ace = ace;
      this.ase = ase;
      this.ae = ae;
    }

    /**
     * Performs a deep copy on <i>other</i>.
     */
    public deleteDataMovementInterface_result(deleteDataMovementInterface_result other) {
      __isset_bitfield = other.__isset_bitfield;
      this.success = other.success;
      if (other.isSetIre()) {
        this.ire = new org.apache.airavata.model.error.InvalidRequestException(other.ire);
      }
      if (other.isSetAce()) {
        this.ace = new org.apache.airavata.model.error.AiravataClientException(other.ace);
      }
      if (other.isSetAse()) {
        this.ase = new org.apache.airavata.model.error.AiravataSystemException(other.ase);
      }
      if (other.isSetAe()) {
        this.ae = new org.apache.airavata.model.error.AuthorizationException(other.ae);
      }
    }

    public deleteDataMovementInterface_result deepCopy() {
      return new deleteDataMovementInterface_result(this);
    }

    @Override
    public void clear() {
      setSuccessIsSet(false);
      this.success = false;
      this.ire = null;
      this.ace = null;
      this.ase = null;
      this.ae = null;
    }

    public boolean isSuccess() {
      return this.success;
    }

    public deleteDataMovementInterface_result setSuccess(boolean success) {
      this.success = success;
      setSuccessIsSet(true);
      return this;
    }

    public void unsetSuccess() {
      __isset_bitfield = EncodingUtils.clearBit(__isset_bitfield, __SUCCESS_ISSET_ID);
    }

    /** Returns true if field success is set (has been assigned a value) and false otherwise */
    public boolean isSetSuccess() {
      return EncodingUtils.testBit(__isset_bitfield, __SUCCESS_ISSET_ID);
    }

    public void setSuccessIsSet(boolean value) {
      __isset_bitfield = EncodingUtils.setBit(__isset_bitfield, __SUCCESS_ISSET_ID, value);
    }

    public org.apache.airavata.model.error.InvalidRequestException getIre() {
      return this.ire;
    }

    public deleteDataMovementInterface_result setIre(org.apache.airavata.model.error.InvalidRequestException ire) {
      this.ire = ire;
      return this;
    }

    public void unsetIre() {
      this.ire = null;
    }

    /** Returns true if field ire is set (has been assigned a value) and false otherwise */
    public boolean isSetIre() {
      return this.ire != null;
    }

    public void setIreIsSet(boolean value) {
      if (!value) {
        this.ire = null;
      }
    }

    public org.apache.airavata.model.error.AiravataClientException getAce() {
      return this.ace;
    }

    public deleteDataMovementInterface_result setAce(org.apache.airavata.model.error.AiravataClientException ace) {
      this.ace = ace;
      return this;
    }

    public void unsetAce() {
      this.ace = null;
    }

    /** Returns true if field ace is set (has been assigned a value) and false otherwise */
    public boolean isSetAce() {
      return this.ace != null;
    }

    public void setAceIsSet(boolean value) {
      if (!value) {
        this.ace = null;
      }
    }

    public org.apache.airavata.model.error.AiravataSystemException getAse() {
      return this.ase;
    }

    public deleteDataMovementInterface_result setAse(org.apache.airavata.model.error.AiravataSystemException ase) {
      this.ase = ase;
      return this;
    }

    public void unsetAse() {
      this.ase = null;
    }

    /** Returns true if field ase is set (has been assigned a value) and false otherwise */
    public boolean isSetAse() {
      return this.ase != null;
    }

    public void setAseIsSet(boolean value) {
      if (!value) {
        this.ase = null;
      }
    }

    public org.apache.airavata.model.error.AuthorizationException getAe() {
      return this.ae;
    }

    public deleteDataMovementInterface_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, Object value) {
      switch (field) {
      case SUCCESS:
        if (value == null) {
          unsetSuccess();
        } else {
          setSuccess((Boolean)value);
        }
        break;

      case IRE:
        if (value == null) {
          unsetIre();
        } else {
          setIre((org.apache.airavata.model.error.InvalidRequestException)value);
        }
        break;

      case ACE:
        if (value == null) {
          unsetAce();
        } else {
          setAce((org.apache.airavata.model.error.AiravataClientException)value);
        }
        break;

      case ASE:
        if (value == null) {
          unsetAse();
        } else {
          setAse((org.apache.airavata.model.error.AiravataSystemException)value);
        }
        break;

      case AE:
        if (value == null) {
          unsetAe();
        } else {
          setAe((org.apache.airavata.model.error.AuthorizationException)value);
        }
        break;

      }
    }

    public Object getFieldValue(_Fields field) {
      switch (field) {
      case SUCCESS:
        return Boolean.valueOf(isSuccess());

      case IRE:
        return getIre();

      case ACE:
        return getAce();

      case ASE:
        return getAse();

      case AE:
        return getAe();

      }
      throw new IllegalStateException();
    }

    /** Returns true if field corresponding to fieldID is set (has been assigned a value) and false otherwise */
    public boolean isSet(_Fields field) {
      if (field == null) {
        throw new IllegalArgumentException();
      }

      switch (field) {
      case SUCCESS:
        return isSetSuccess();
      case IRE:
        return isSetIre();
      case ACE:
        return isSetAce();
      case ASE:
        return isSetAse();
      case AE:
        return isSetAe();
      }
      throw new IllegalStateException();
    }

    @Override
    public boolean equals(Object that) {
      if (that == null)
        return false;
      if (that instanceof deleteDataMovementInterface_result)
        return this.equals((deleteDataMovementInterface_result)that);
      return false;
    }

    public boolean equals(deleteDataMovementInterface_result that) {
      if (that == null)
        return false;

      boolean this_present_success = true;
      boolean that_present_success = true;
      if (this_present_success || that_present_success) {
        if (!(this_present_success && that_present_success))
          return false;
        if (this.success != that.success)
          return false;
      }

      boolean this_present_ire = true && this.isSetIre();
      boolean that_present_ire = true && that.isSetIre();
      if (this_present_ire || that_present_ire) {
        if (!(this_present_ire && that_present_ire))
          return false;
        if (!this.ire.equals(that.ire))
          return false;
      }

      boolean this_present_ace = true && this.isSetAce();
      boolean that_present_ace = true && that.isSetAce();
      if (this_present_ace || that_present_ace) {
        if (!(this_present_ace && that_present_ace))
          return false;
        if (!this.ace.equals(that.ace))
          return false;
      }

      boolean this_present_ase = true && this.isSetAse();
      boolean that_present_ase = true && that.isSetAse();
      if (this_present_ase || that_present_ase) {
        if (!(this_present_ase && that_present_ase))
          return false;
        if (!this.ase.equals(that.ase))
          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() {
      List<Object> list = new ArrayList<Object>();

      boolean present_success = true;
      list.add(present_success);
      if (present_success)
        list.add(success);

      boolean present_ire = true && (isSetIre());
      list.add(present_ire);
      if (present_ire)
        list.add(ire);

      boolean present_ace = true && (isSetAce());
      list.add(present_ace);
      if (present_ace)
        list.add(ace);

      boolean present_ase = true && (isSetAse());
      list.add(present_ase);
      if (present_ase)
        list.add(ase);

      boolean present_ae = true && (isSetAe());
      list.add(present_ae);
      if (present_ae)
        list.add(ae);

      return list.hashCode();
    }

    @Override
    public int compareTo(deleteDataMovementInterface_result other) {
      if (!getClass().equals(other.getClass())) {
        return getClass().getName().compareTo(other.getClass().getName());
      }

      int lastComparison = 0;

      lastComparison = Boolean.valueOf(isSetSuccess()).compareTo(other.isSetSuccess());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetSuccess()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.success, other.success);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = Boolean.valueOf(isSetIre()).compareTo(other.isSetIre());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetIre()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.ire, other.ire);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = Boolean.valueOf(isSetAce()).compareTo(other.isSetAce());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetAce()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.ace, other.ace);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = Boolean.valueOf(isSetAse()).compareTo(other.isSetAse());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetAse()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.ase, other.ase);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = 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 {
      schemes.get(iprot.getScheme()).getScheme().read(iprot, this);
    }

    public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException {
      schemes.get(oprot.getScheme()).getScheme().write(oprot, this);
      }

    @Override
    public String toString() {
      StringBuilder sb = new StringBuilder("deleteDataMovementInterface_result(");
      boolean first = true;

      sb.append("success:");
      sb.append(this.success);
      first = false;
      if (!first) sb.append(", ");
      sb.append("ire:");
      if (this.ire == null) {
        sb.append("null");
      } else {
        sb.append(this.ire);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("ace:");
      if (this.ace == null) {
        sb.append("null");
      } else {
        sb.append(this.ace);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("ase:");
      if (this.ase == null) {
        sb.append("null");
      } else {
        sb.append(this.ase);
      }
      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, 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 deleteDataMovementInterface_resultStandardSchemeFactory implements SchemeFactory {
      public deleteDataMovementInterface_resultStandardScheme getScheme() {
        return new deleteDataMovementInterface_resultStandardScheme();
      }
    }

    private static class deleteDataMovementInterface_resultStandardScheme extends StandardScheme<deleteDataMovementInterface_result> {

      public void read(org.apache.thrift.protocol.TProtocol iprot, deleteDataMovementInterface_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: // IRE
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.ire = new org.apache.airavata.model.error.InvalidRequestException();
                struct.ire.read(iprot);
                struct.setIreIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 2: // ACE
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.ace = new org.apache.airavata.model.error.AiravataClientException();
                struct.ace.read(iprot);
                struct.setAceIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 3: // ASE
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.ase = new org.apache.airavata.model.error.AiravataSystemException();
                struct.ase.read(iprot);
                struct.setAseIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 4: // 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, deleteDataMovementInterface_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.ire != null) {
          oprot.writeFieldBegin(IRE_FIELD_DESC);
          struct.ire.write(oprot);
          oprot.writeFieldEnd();
        }
        if (struct.ace != null) {
          oprot.writeFieldBegin(ACE_FIELD_DESC);
          struct.ace.write(oprot);
          oprot.writeFieldEnd();
        }
        if (struct.ase != null) {
          oprot.writeFieldBegin(ASE_FIELD_DESC);
          struct.ase.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 deleteDataMovementInterface_resultTupleSchemeFactory implements SchemeFactory {
      public deleteDataMovementInterface_resultTupleScheme getScheme() {
        return new deleteDataMovementInterface_resultTupleScheme();
      }
    }

    private static class deleteDataMovementInterface_resultTupleScheme extends TupleScheme<deleteDataMovementInterface_result> {

      @Override
      public void write(org.apache.thrift.protocol.TProtocol prot, deleteDataMovementInterface_result struct) throws org.apache.thrift.TException {
        TTupleProtocol oprot = (TTupleProtocol) prot;
        BitSet optionals = new BitSet();
        if (struct.isSetSuccess()) {
          optionals.set(0);
        }
        if (struct.isSetIre()) {
          optionals.set(1);
        }
        if (struct.isSetAce()) {
          optionals.set(2);
        }
        if (struct.isSetAse()) {
          optionals.set(3);
        }
        if (struct.isSetAe()) {
          optionals.set(4);
        }
        oprot.writeBitSet(optionals, 5);
        if (struct.isSetSuccess()) {
          oprot.writeBool(struct.success);
        }
        if (struct.isSetIre()) {
          struct.ire.write(oprot);
        }
        if (struct.isSetAce()) {
          struct.ace.write(oprot);
        }
        if (struct.isSetAse()) {
          struct.ase.write(oprot);
        }
        if (struct.isSetAe()) {
          struct.ae.write(oprot);
        }
      }

      @Override
      public void read(org.apache.thrift.protocol.TProtocol prot, deleteDataMovementInterface_result struct) throws org.apache.thrift.TException {
        TTupleProtocol iprot = (TTupleProtocol) prot;
        BitSet incoming = iprot.readBitSet(5);
        if (incoming.get(0)) {
          struct.success = iprot.readBool();
          struct.setSuccessIsSet(true);
        }
        if (incoming.get(1)) {
          struct.ire = new org.apache.airavata.model.error.InvalidRequestException();
          struct.ire.read(iprot);
          struct.setIreIsSet(true);
        }
        if (incoming.get(2)) {
          struct.ace = new org.apache.airavata.model.error.AiravataClientException();
          struct.ace.read(iprot);
          struct.setAceIsSet(true);
        }
        if (incoming.get(3)) {
          struct.ase = new org.apache.airavata.model.error.AiravataSystemException();
          struct.ase.read(iprot);
          struct.setAseIsSet(true);
        }
        if (incoming.get(4)) {
          struct.ae = new org.apache.airavata.model.error.AuthorizationException();
          struct.ae.read(iprot);
          struct.setAeIsSet(true);
        }
      }
    }

  }

  public static class registerResourceJobManager_args implements org.apache.thrift.TBase<registerResourceJobManager_args, registerResourceJobManager_args._Fields>, java.io.Serializable, Cloneable, Comparable<registerResourceJobManager_args>   {
    private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("registerResourceJobManager_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 RESOURCE_JOB_MANAGER_FIELD_DESC = new org.apache.thrift.protocol.TField("resourceJobManager", org.apache.thrift.protocol.TType.STRUCT, (short)2);

    private static final Map<Class<? extends IScheme>, SchemeFactory> schemes = new HashMap<Class<? extends IScheme>, SchemeFactory>();
    static {
      schemes.put(StandardScheme.class, new registerResourceJobManager_argsStandardSchemeFactory());
      schemes.put(TupleScheme.class, new registerResourceJobManager_argsTupleSchemeFactory());
    }

    public org.apache.airavata.model.security.AuthzToken authzToken; // required
    public org.apache.airavata.model.appcatalog.computeresource.ResourceJobManager resourceJobManager; // required

    /** 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"),
      RESOURCE_JOB_MANAGER((short)2, "resourceJobManager");

      private static final Map<String, _Fields> byName = new HashMap<String, _Fields>();

      static {
        for (_Fields field : EnumSet.allOf(_Fields.class)) {
          byName.put(field.getFieldName(), field);
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, or null if its not found.
       */
      public static _Fields findByThriftId(int fieldId) {
        switch(fieldId) {
          case 1: // AUTHZ_TOKEN
            return AUTHZ_TOKEN;
          case 2: // RESOURCE_JOB_MANAGER
            return RESOURCE_JOB_MANAGER;
          default:
            return null;
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, throwing an exception
       * if it is not found.
       */
      public static _Fields findByThriftIdOrThrow(int fieldId) {
        _Fields fields = findByThriftId(fieldId);
        if (fields == null) throw new IllegalArgumentException("Field " + fieldId + " doesn't exist!");
        return fields;
      }

      /**
       * Find the _Fields constant that matches name, or null if its not found.
       */
      public static _Fields findByName(String name) {
        return byName.get(name);
      }

      private final short _thriftId;
      private final String _fieldName;

      _Fields(short thriftId, String fieldName) {
        _thriftId = thriftId;
        _fieldName = fieldName;
      }

      public short getThriftFieldId() {
        return _thriftId;
      }

      public String getFieldName() {
        return _fieldName;
      }
    }

    // isset id assignments
    public static final Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
    static {
      Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new EnumMap<_Fields, org.apache.thrift.meta_data.FieldMetaData>(_Fields.class);
      tmpMap.put(_Fields.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.RESOURCE_JOB_MANAGER, new org.apache.thrift.meta_data.FieldMetaData("resourceJobManager", org.apache.thrift.TFieldRequirementType.REQUIRED, 
          new org.apache.thrift.meta_data.StructMetaData(org.apache.thrift.protocol.TType.STRUCT, org.apache.airavata.model.appcatalog.computeresource.ResourceJobManager.class)));
      metaDataMap = Collections.unmodifiableMap(tmpMap);
      org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(registerResourceJobManager_args.class, metaDataMap);
    }

    public registerResourceJobManager_args() {
    }

    public registerResourceJobManager_args(
      org.apache.airavata.model.security.AuthzToken authzToken,
      org.apache.airavata.model.appcatalog.computeresource.ResourceJobManager resourceJobManager)
    {
      this();
      this.authzToken = authzToken;
      this.resourceJobManager = resourceJobManager;
    }

    /**
     * Performs a deep copy on <i>other</i>.
     */
    public registerResourceJobManager_args(registerResourceJobManager_args other) {
      if (other.isSetAuthzToken()) {
        this.authzToken = new org.apache.airavata.model.security.AuthzToken(other.authzToken);
      }
      if (other.isSetResourceJobManager()) {
        this.resourceJobManager = new org.apache.airavata.model.appcatalog.computeresource.ResourceJobManager(other.resourceJobManager);
      }
    }

    public registerResourceJobManager_args deepCopy() {
      return new registerResourceJobManager_args(this);
    }

    @Override
    public void clear() {
      this.authzToken = null;
      this.resourceJobManager = null;
    }

    public org.apache.airavata.model.security.AuthzToken getAuthzToken() {
      return this.authzToken;
    }

    public registerResourceJobManager_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.appcatalog.computeresource.ResourceJobManager getResourceJobManager() {
      return this.resourceJobManager;
    }

    public registerResourceJobManager_args setResourceJobManager(org.apache.airavata.model.appcatalog.computeresource.ResourceJobManager resourceJobManager) {
      this.resourceJobManager = resourceJobManager;
      return this;
    }

    public void unsetResourceJobManager() {
      this.resourceJobManager = null;
    }

    /** Returns true if field resourceJobManager is set (has been assigned a value) and false otherwise */
    public boolean isSetResourceJobManager() {
      return this.resourceJobManager != null;
    }

    public void setResourceJobManagerIsSet(boolean value) {
      if (!value) {
        this.resourceJobManager = null;
      }
    }

    public void setFieldValue(_Fields field, Object value) {
      switch (field) {
      case AUTHZ_TOKEN:
        if (value == null) {
          unsetAuthzToken();
        } else {
          setAuthzToken((org.apache.airavata.model.security.AuthzToken)value);
        }
        break;

      case RESOURCE_JOB_MANAGER:
        if (value == null) {
          unsetResourceJobManager();
        } else {
          setResourceJobManager((org.apache.airavata.model.appcatalog.computeresource.ResourceJobManager)value);
        }
        break;

      }
    }

    public Object getFieldValue(_Fields field) {
      switch (field) {
      case AUTHZ_TOKEN:
        return getAuthzToken();

      case RESOURCE_JOB_MANAGER:
        return getResourceJobManager();

      }
      throw new IllegalStateException();
    }

    /** Returns true if field corresponding to fieldID is set (has been assigned a value) and false otherwise */
    public boolean isSet(_Fields field) {
      if (field == null) {
        throw new IllegalArgumentException();
      }

      switch (field) {
      case AUTHZ_TOKEN:
        return isSetAuthzToken();
      case RESOURCE_JOB_MANAGER:
        return isSetResourceJobManager();
      }
      throw new IllegalStateException();
    }

    @Override
    public boolean equals(Object that) {
      if (that == null)
        return false;
      if (that instanceof registerResourceJobManager_args)
        return this.equals((registerResourceJobManager_args)that);
      return false;
    }

    public boolean equals(registerResourceJobManager_args that) {
      if (that == null)
        return false;

      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_resourceJobManager = true && this.isSetResourceJobManager();
      boolean that_present_resourceJobManager = true && that.isSetResourceJobManager();
      if (this_present_resourceJobManager || that_present_resourceJobManager) {
        if (!(this_present_resourceJobManager && that_present_resourceJobManager))
          return false;
        if (!this.resourceJobManager.equals(that.resourceJobManager))
          return false;
      }

      return true;
    }

    @Override
    public int hashCode() {
      List<Object> list = new ArrayList<Object>();

      boolean present_authzToken = true && (isSetAuthzToken());
      list.add(present_authzToken);
      if (present_authzToken)
        list.add(authzToken);

      boolean present_resourceJobManager = true && (isSetResourceJobManager());
      list.add(present_resourceJobManager);
      if (present_resourceJobManager)
        list.add(resourceJobManager);

      return list.hashCode();
    }

    @Override
    public int compareTo(registerResourceJobManager_args other) {
      if (!getClass().equals(other.getClass())) {
        return getClass().getName().compareTo(other.getClass().getName());
      }

      int lastComparison = 0;

      lastComparison = 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 = Boolean.valueOf(isSetResourceJobManager()).compareTo(other.isSetResourceJobManager());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetResourceJobManager()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.resourceJobManager, other.resourceJobManager);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      return 0;
    }

    public _Fields fieldForId(int fieldId) {
      return _Fields.findByThriftId(fieldId);
    }

    public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
      schemes.get(iprot.getScheme()).getScheme().read(iprot, this);
    }

    public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException {
      schemes.get(oprot.getScheme()).getScheme().write(oprot, this);
    }

    @Override
    public String toString() {
      StringBuilder sb = new StringBuilder("registerResourceJobManager_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("resourceJobManager:");
      if (this.resourceJobManager == null) {
        sb.append("null");
      } else {
        sb.append(this.resourceJobManager);
      }
      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 (resourceJobManager == null) {
        throw new org.apache.thrift.protocol.TProtocolException("Required field 'resourceJobManager' was not present! Struct: " + toString());
      }
      // check for sub-struct validity
      if (authzToken != null) {
        authzToken.validate();
      }
      if (resourceJobManager != null) {
        resourceJobManager.validate();
      }
    }

    private void writeObject(java.io.ObjectOutputStream out) throws java.io.IOException {
      try {
        write(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(out)));
      } catch (org.apache.thrift.TException te) {
        throw new java.io.IOException(te);
      }
    }

    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, ClassNotFoundException {
      try {
        read(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(in)));
      } catch (org.apache.thrift.TException te) {
        throw new java.io.IOException(te);
      }
    }

    private static class registerResourceJobManager_argsStandardSchemeFactory implements SchemeFactory {
      public registerResourceJobManager_argsStandardScheme getScheme() {
        return new registerResourceJobManager_argsStandardScheme();
      }
    }

    private static class registerResourceJobManager_argsStandardScheme extends StandardScheme<registerResourceJobManager_args> {

      public void read(org.apache.thrift.protocol.TProtocol iprot, registerResourceJobManager_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: // RESOURCE_JOB_MANAGER
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.resourceJobManager = new org.apache.airavata.model.appcatalog.computeresource.ResourceJobManager();
                struct.resourceJobManager.read(iprot);
                struct.setResourceJobManagerIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            default:
              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
          }
          iprot.readFieldEnd();
        }
        iprot.readStructEnd();

        // check for required fields of primitive type, which can't be checked in the validate method
        struct.validate();
      }

      public void write(org.apache.thrift.protocol.TProtocol oprot, registerResourceJobManager_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.resourceJobManager != null) {
          oprot.writeFieldBegin(RESOURCE_JOB_MANAGER_FIELD_DESC);
          struct.resourceJobManager.write(oprot);
          oprot.writeFieldEnd();
        }
        oprot.writeFieldStop();
        oprot.writeStructEnd();
      }

    }

    private static class registerResourceJobManager_argsTupleSchemeFactory implements SchemeFactory {
      public registerResourceJobManager_argsTupleScheme getScheme() {
        return new registerResourceJobManager_argsTupleScheme();
      }
    }

    private static class registerResourceJobManager_argsTupleScheme extends TupleScheme<registerResourceJobManager_args> {

      @Override
      public void write(org.apache.thrift.protocol.TProtocol prot, registerResourceJobManager_args struct) throws org.apache.thrift.TException {
        TTupleProtocol oprot = (TTupleProtocol) prot;
        struct.authzToken.write(oprot);
        struct.resourceJobManager.write(oprot);
      }

      @Override
      public void read(org.apache.thrift.protocol.TProtocol prot, registerResourceJobManager_args struct) throws org.apache.thrift.TException {
        TTupleProtocol iprot = (TTupleProtocol) prot;
        struct.authzToken = new org.apache.airavata.model.security.AuthzToken();
        struct.authzToken.read(iprot);
        struct.setAuthzTokenIsSet(true);
        struct.resourceJobManager = new org.apache.airavata.model.appcatalog.computeresource.ResourceJobManager();
        struct.resourceJobManager.read(iprot);
        struct.setResourceJobManagerIsSet(true);
      }
    }

  }

  public static class registerResourceJobManager_result implements org.apache.thrift.TBase<registerResourceJobManager_result, registerResourceJobManager_result._Fields>, java.io.Serializable, Cloneable, Comparable<registerResourceJobManager_result>   {
    private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("registerResourceJobManager_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 IRE_FIELD_DESC = new org.apache.thrift.protocol.TField("ire", org.apache.thrift.protocol.TType.STRUCT, (short)1);
    private static final org.apache.thrift.protocol.TField ACE_FIELD_DESC = new org.apache.thrift.protocol.TField("ace", org.apache.thrift.protocol.TType.STRUCT, (short)2);
    private static final org.apache.thrift.protocol.TField ASE_FIELD_DESC = new org.apache.thrift.protocol.TField("ase", org.apache.thrift.protocol.TType.STRUCT, (short)3);
    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)4);

    private static final Map<Class<? extends IScheme>, SchemeFactory> schemes = new HashMap<Class<? extends IScheme>, SchemeFactory>();
    static {
      schemes.put(StandardScheme.class, new registerResourceJobManager_resultStandardSchemeFactory());
      schemes.put(TupleScheme.class, new registerResourceJobManager_resultTupleSchemeFactory());
    }

    public String success; // required
    public org.apache.airavata.model.error.InvalidRequestException ire; // required
    public org.apache.airavata.model.error.AiravataClientException ace; // required
    public org.apache.airavata.model.error.AiravataSystemException ase; // 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"),
      IRE((short)1, "ire"),
      ACE((short)2, "ace"),
      ASE((short)3, "ase"),
      AE((short)4, "ae");

      private static final Map<String, _Fields> byName = new HashMap<String, _Fields>();

      static {
        for (_Fields field : EnumSet.allOf(_Fields.class)) {
          byName.put(field.getFieldName(), field);
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, or null if its not found.
       */
      public static _Fields findByThriftId(int fieldId) {
        switch(fieldId) {
          case 0: // SUCCESS
            return SUCCESS;
          case 1: // IRE
            return IRE;
          case 2: // ACE
            return ACE;
          case 3: // ASE
            return ASE;
          case 4: // 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 IllegalArgumentException("Field " + fieldId + " doesn't exist!");
        return fields;
      }

      /**
       * Find the _Fields constant that matches name, or null if its not found.
       */
      public static _Fields findByName(String name) {
        return byName.get(name);
      }

      private final short _thriftId;
      private final String _fieldName;

      _Fields(short thriftId, String fieldName) {
        _thriftId = thriftId;
        _fieldName = fieldName;
      }

      public short getThriftFieldId() {
        return _thriftId;
      }

      public String getFieldName() {
        return _fieldName;
      }
    }

    // isset id assignments
    public static final Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
    static {
      Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new EnumMap<_Fields, org.apache.thrift.meta_data.FieldMetaData>(_Fields.class);
      tmpMap.put(_Fields.SUCCESS, new org.apache.thrift.meta_data.FieldMetaData("success", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING)));
      tmpMap.put(_Fields.IRE, new org.apache.thrift.meta_data.FieldMetaData("ire", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRUCT)));
      tmpMap.put(_Fields.ACE, new org.apache.thrift.meta_data.FieldMetaData("ace", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRUCT)));
      tmpMap.put(_Fields.ASE, new org.apache.thrift.meta_data.FieldMetaData("ase", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRUCT)));
      tmpMap.put(_Fields.AE, new org.apache.thrift.meta_data.FieldMetaData("ae", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRUCT)));
      metaDataMap = Collections.unmodifiableMap(tmpMap);
      org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(registerResourceJobManager_result.class, metaDataMap);
    }

    public registerResourceJobManager_result() {
    }

    public registerResourceJobManager_result(
      String success,
      org.apache.airavata.model.error.InvalidRequestException ire,
      org.apache.airavata.model.error.AiravataClientException ace,
      org.apache.airavata.model.error.AiravataSystemException ase,
      org.apache.airavata.model.error.AuthorizationException ae)
    {
      this();
      this.success = success;
      this.ire = ire;
      this.ace = ace;
      this.ase = ase;
      this.ae = ae;
    }

    /**
     * Performs a deep copy on <i>other</i>.
     */
    public registerResourceJobManager_result(registerResourceJobManager_result other) {
      if (other.isSetSuccess()) {
        this.success = other.success;
      }
      if (other.isSetIre()) {
        this.ire = new org.apache.airavata.model.error.InvalidRequestException(other.ire);
      }
      if (other.isSetAce()) {
        this.ace = new org.apache.airavata.model.error.AiravataClientException(other.ace);
      }
      if (other.isSetAse()) {
        this.ase = new org.apache.airavata.model.error.AiravataSystemException(other.ase);
      }
      if (other.isSetAe()) {
        this.ae = new org.apache.airavata.model.error.AuthorizationException(other.ae);
      }
    }

    public registerResourceJobManager_result deepCopy() {
      return new registerResourceJobManager_result(this);
    }

    @Override
    public void clear() {
      this.success = null;
      this.ire = null;
      this.ace = null;
      this.ase = null;
      this.ae = null;
    }

    public String getSuccess() {
      return this.success;
    }

    public registerResourceJobManager_result setSuccess(String success) {
      this.success = success;
      return this;
    }

    public void unsetSuccess() {
      this.success = null;
    }

    /** Returns true if field success is set (has been assigned a value) and false otherwise */
    public boolean isSetSuccess() {
      return this.success != null;
    }

    public void setSuccessIsSet(boolean value) {
      if (!value) {
        this.success = null;
      }
    }

    public org.apache.airavata.model.error.InvalidRequestException getIre() {
      return this.ire;
    }

    public registerResourceJobManager_result setIre(org.apache.airavata.model.error.InvalidRequestException ire) {
      this.ire = ire;
      return this;
    }

    public void unsetIre() {
      this.ire = null;
    }

    /** Returns true if field ire is set (has been assigned a value) and false otherwise */
    public boolean isSetIre() {
      return this.ire != null;
    }

    public void setIreIsSet(boolean value) {
      if (!value) {
        this.ire = null;
      }
    }

    public org.apache.airavata.model.error.AiravataClientException getAce() {
      return this.ace;
    }

    public registerResourceJobManager_result setAce(org.apache.airavata.model.error.AiravataClientException ace) {
      this.ace = ace;
      return this;
    }

    public void unsetAce() {
      this.ace = null;
    }

    /** Returns true if field ace is set (has been assigned a value) and false otherwise */
    public boolean isSetAce() {
      return this.ace != null;
    }

    public void setAceIsSet(boolean value) {
      if (!value) {
        this.ace = null;
      }
    }

    public org.apache.airavata.model.error.AiravataSystemException getAse() {
      return this.ase;
    }

    public registerResourceJobManager_result setAse(org.apache.airavata.model.error.AiravataSystemException ase) {
      this.ase = ase;
      return this;
    }

    public void unsetAse() {
      this.ase = null;
    }

    /** Returns true if field ase is set (has been assigned a value) and false otherwise */
    public boolean isSetAse() {
      return this.ase != null;
    }

    public void setAseIsSet(boolean value) {
      if (!value) {
        this.ase = null;
      }
    }

    public org.apache.airavata.model.error.AuthorizationException getAe() {
      return this.ae;
    }

    public registerResourceJobManager_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, Object value) {
      switch (field) {
      case SUCCESS:
        if (value == null) {
          unsetSuccess();
        } else {
          setSuccess((String)value);
        }
        break;

      case IRE:
        if (value == null) {
          unsetIre();
        } else {
          setIre((org.apache.airavata.model.error.InvalidRequestException)value);
        }
        break;

      case ACE:
        if (value == null) {
          unsetAce();
        } else {
          setAce((org.apache.airavata.model.error.AiravataClientException)value);
        }
        break;

      case ASE:
        if (value == null) {
          unsetAse();
        } else {
          setAse((org.apache.airavata.model.error.AiravataSystemException)value);
        }
        break;

      case AE:
        if (value == null) {
          unsetAe();
        } else {
          setAe((org.apache.airavata.model.error.AuthorizationException)value);
        }
        break;

      }
    }

    public Object getFieldValue(_Fields field) {
      switch (field) {
      case SUCCESS:
        return getSuccess();

      case IRE:
        return getIre();

      case ACE:
        return getAce();

      case ASE:
        return getAse();

      case AE:
        return getAe();

      }
      throw new IllegalStateException();
    }

    /** Returns true if field corresponding to fieldID is set (has been assigned a value) and false otherwise */
    public boolean isSet(_Fields field) {
      if (field == null) {
        throw new IllegalArgumentException();
      }

      switch (field) {
      case SUCCESS:
        return isSetSuccess();
      case IRE:
        return isSetIre();
      case ACE:
        return isSetAce();
      case ASE:
        return isSetAse();
      case AE:
        return isSetAe();
      }
      throw new IllegalStateException();
    }

    @Override
    public boolean equals(Object that) {
      if (that == null)
        return false;
      if (that instanceof registerResourceJobManager_result)
        return this.equals((registerResourceJobManager_result)that);
      return false;
    }

    public boolean equals(registerResourceJobManager_result that) {
      if (that == null)
        return false;

      boolean this_present_success = true && this.isSetSuccess();
      boolean that_present_success = true && that.isSetSuccess();
      if (this_present_success || that_present_success) {
        if (!(this_present_success && that_present_success))
          return false;
        if (!this.success.equals(that.success))
          return false;
      }

      boolean this_present_ire = true && this.isSetIre();
      boolean that_present_ire = true && that.isSetIre();
      if (this_present_ire || that_present_ire) {
        if (!(this_present_ire && that_present_ire))
          return false;
        if (!this.ire.equals(that.ire))
          return false;
      }

      boolean this_present_ace = true && this.isSetAce();
      boolean that_present_ace = true && that.isSetAce();
      if (this_present_ace || that_present_ace) {
        if (!(this_present_ace && that_present_ace))
          return false;
        if (!this.ace.equals(that.ace))
          return false;
      }

      boolean this_present_ase = true && this.isSetAse();
      boolean that_present_ase = true && that.isSetAse();
      if (this_present_ase || that_present_ase) {
        if (!(this_present_ase && that_present_ase))
          return false;
        if (!this.ase.equals(that.ase))
          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() {
      List<Object> list = new ArrayList<Object>();

      boolean present_success = true && (isSetSuccess());
      list.add(present_success);
      if (present_success)
        list.add(success);

      boolean present_ire = true && (isSetIre());
      list.add(present_ire);
      if (present_ire)
        list.add(ire);

      boolean present_ace = true && (isSetAce());
      list.add(present_ace);
      if (present_ace)
        list.add(ace);

      boolean present_ase = true && (isSetAse());
      list.add(present_ase);
      if (present_ase)
        list.add(ase);

      boolean present_ae = true && (isSetAe());
      list.add(present_ae);
      if (present_ae)
        list.add(ae);

      return list.hashCode();
    }

    @Override
    public int compareTo(registerResourceJobManager_result other) {
      if (!getClass().equals(other.getClass())) {
        return getClass().getName().compareTo(other.getClass().getName());
      }

      int lastComparison = 0;

      lastComparison = Boolean.valueOf(isSetSuccess()).compareTo(other.isSetSuccess());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetSuccess()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.success, other.success);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = Boolean.valueOf(isSetIre()).compareTo(other.isSetIre());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetIre()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.ire, other.ire);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = Boolean.valueOf(isSetAce()).compareTo(other.isSetAce());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetAce()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.ace, other.ace);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = Boolean.valueOf(isSetAse()).compareTo(other.isSetAse());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetAse()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.ase, other.ase);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = 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 {
      schemes.get(iprot.getScheme()).getScheme().read(iprot, this);
    }

    public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException {
      schemes.get(oprot.getScheme()).getScheme().write(oprot, this);
      }

    @Override
    public String toString() {
      StringBuilder sb = new StringBuilder("registerResourceJobManager_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("ire:");
      if (this.ire == null) {
        sb.append("null");
      } else {
        sb.append(this.ire);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("ace:");
      if (this.ace == null) {
        sb.append("null");
      } else {
        sb.append(this.ace);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("ase:");
      if (this.ase == null) {
        sb.append("null");
      } else {
        sb.append(this.ase);
      }
      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, 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 registerResourceJobManager_resultStandardSchemeFactory implements SchemeFactory {
      public registerResourceJobManager_resultStandardScheme getScheme() {
        return new registerResourceJobManager_resultStandardScheme();
      }
    }

    private static class registerResourceJobManager_resultStandardScheme extends StandardScheme<registerResourceJobManager_result> {

      public void read(org.apache.thrift.protocol.TProtocol iprot, registerResourceJobManager_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: // IRE
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.ire = new org.apache.airavata.model.error.InvalidRequestException();
                struct.ire.read(iprot);
                struct.setIreIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 2: // ACE
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.ace = new org.apache.airavata.model.error.AiravataClientException();
                struct.ace.read(iprot);
                struct.setAceIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 3: // ASE
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.ase = new org.apache.airavata.model.error.AiravataSystemException();
                struct.ase.read(iprot);
                struct.setAseIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 4: // 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, registerResourceJobManager_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.ire != null) {
          oprot.writeFieldBegin(IRE_FIELD_DESC);
          struct.ire.write(oprot);
          oprot.writeFieldEnd();
        }
        if (struct.ace != null) {
          oprot.writeFieldBegin(ACE_FIELD_DESC);
          struct.ace.write(oprot);
          oprot.writeFieldEnd();
        }
        if (struct.ase != null) {
          oprot.writeFieldBegin(ASE_FIELD_DESC);
          struct.ase.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 registerResourceJobManager_resultTupleSchemeFactory implements SchemeFactory {
      public registerResourceJobManager_resultTupleScheme getScheme() {
        return new registerResourceJobManager_resultTupleScheme();
      }
    }

    private static class registerResourceJobManager_resultTupleScheme extends TupleScheme<registerResourceJobManager_result> {

      @Override
      public void write(org.apache.thrift.protocol.TProtocol prot, registerResourceJobManager_result struct) throws org.apache.thrift.TException {
        TTupleProtocol oprot = (TTupleProtocol) prot;
        BitSet optionals = new BitSet();
        if (struct.isSetSuccess()) {
          optionals.set(0);
        }
        if (struct.isSetIre()) {
          optionals.set(1);
        }
        if (struct.isSetAce()) {
          optionals.set(2);
        }
        if (struct.isSetAse()) {
          optionals.set(3);
        }
        if (struct.isSetAe()) {
          optionals.set(4);
        }
        oprot.writeBitSet(optionals, 5);
        if (struct.isSetSuccess()) {
          oprot.writeString(struct.success);
        }
        if (struct.isSetIre()) {
          struct.ire.write(oprot);
        }
        if (struct.isSetAce()) {
          struct.ace.write(oprot);
        }
        if (struct.isSetAse()) {
          struct.ase.write(oprot);
        }
        if (struct.isSetAe()) {
          struct.ae.write(oprot);
        }
      }

      @Override
      public void read(org.apache.thrift.protocol.TProtocol prot, registerResourceJobManager_result struct) throws org.apache.thrift.TException {
        TTupleProtocol iprot = (TTupleProtocol) prot;
        BitSet incoming = iprot.readBitSet(5);
        if (incoming.get(0)) {
          struct.success = iprot.readString();
          struct.setSuccessIsSet(true);
        }
        if (incoming.get(1)) {
          struct.ire = new org.apache.airavata.model.error.InvalidRequestException();
          struct.ire.read(iprot);
          struct.setIreIsSet(true);
        }
        if (incoming.get(2)) {
          struct.ace = new org.apache.airavata.model.error.AiravataClientException();
          struct.ace.read(iprot);
          struct.setAceIsSet(true);
        }
        if (incoming.get(3)) {
          struct.ase = new org.apache.airavata.model.error.AiravataSystemException();
          struct.ase.read(iprot);
          struct.setAseIsSet(true);
        }
        if (incoming.get(4)) {
          struct.ae = new org.apache.airavata.model.error.AuthorizationException();
          struct.ae.read(iprot);
          struct.setAeIsSet(true);
        }
      }
    }

  }

  public static class updateResourceJobManager_args implements org.apache.thrift.TBase<updateResourceJobManager_args, updateResourceJobManager_args._Fields>, java.io.Serializable, Cloneable, Comparable<updateResourceJobManager_args>   {
    private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("updateResourceJobManager_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 RESOURCE_JOB_MANAGER_ID_FIELD_DESC = new org.apache.thrift.protocol.TField("resourceJobManagerId", org.apache.thrift.protocol.TType.STRING, (short)2);
    private static final org.apache.thrift.protocol.TField UPDATED_RESOURCE_JOB_MANAGER_FIELD_DESC = new org.apache.thrift.protocol.TField("updatedResourceJobManager", org.apache.thrift.protocol.TType.STRUCT, (short)3);

    private static final Map<Class<? extends IScheme>, SchemeFactory> schemes = new HashMap<Class<? extends IScheme>, SchemeFactory>();
    static {
      schemes.put(StandardScheme.class, new updateResourceJobManager_argsStandardSchemeFactory());
      schemes.put(TupleScheme.class, new updateResourceJobManager_argsTupleSchemeFactory());
    }

    public org.apache.airavata.model.security.AuthzToken authzToken; // required
    public String resourceJobManagerId; // required
    public org.apache.airavata.model.appcatalog.computeresource.ResourceJobManager updatedResourceJobManager; // required

    /** 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"),
      RESOURCE_JOB_MANAGER_ID((short)2, "resourceJobManagerId"),
      UPDATED_RESOURCE_JOB_MANAGER((short)3, "updatedResourceJobManager");

      private static final Map<String, _Fields> byName = new HashMap<String, _Fields>();

      static {
        for (_Fields field : EnumSet.allOf(_Fields.class)) {
          byName.put(field.getFieldName(), field);
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, or null if its not found.
       */
      public static _Fields findByThriftId(int fieldId) {
        switch(fieldId) {
          case 1: // AUTHZ_TOKEN
            return AUTHZ_TOKEN;
          case 2: // RESOURCE_JOB_MANAGER_ID
            return RESOURCE_JOB_MANAGER_ID;
          case 3: // UPDATED_RESOURCE_JOB_MANAGER
            return UPDATED_RESOURCE_JOB_MANAGER;
          default:
            return null;
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, throwing an exception
       * if it is not found.
       */
      public static _Fields findByThriftIdOrThrow(int fieldId) {
        _Fields fields = findByThriftId(fieldId);
        if (fields == null) throw new IllegalArgumentException("Field " + fieldId + " doesn't exist!");
        return fields;
      }

      /**
       * Find the _Fields constant that matches name, or null if its not found.
       */
      public static _Fields findByName(String name) {
        return byName.get(name);
      }

      private final short _thriftId;
      private final String _fieldName;

      _Fields(short thriftId, String fieldName) {
        _thriftId = thriftId;
        _fieldName = fieldName;
      }

      public short getThriftFieldId() {
        return _thriftId;
      }

      public String getFieldName() {
        return _fieldName;
      }
    }

    // isset id assignments
    public static final Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
    static {
      Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new EnumMap<_Fields, org.apache.thrift.meta_data.FieldMetaData>(_Fields.class);
      tmpMap.put(_Fields.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.RESOURCE_JOB_MANAGER_ID, new org.apache.thrift.meta_data.FieldMetaData("resourceJobManagerId", org.apache.thrift.TFieldRequirementType.REQUIRED, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING)));
      tmpMap.put(_Fields.UPDATED_RESOURCE_JOB_MANAGER, new org.apache.thrift.meta_data.FieldMetaData("updatedResourceJobManager", org.apache.thrift.TFieldRequirementType.REQUIRED, 
          new org.apache.thrift.meta_data.StructMetaData(org.apache.thrift.protocol.TType.STRUCT, org.apache.airavata.model.appcatalog.computeresource.ResourceJobManager.class)));
      metaDataMap = Collections.unmodifiableMap(tmpMap);
      org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(updateResourceJobManager_args.class, metaDataMap);
    }

    public updateResourceJobManager_args() {
    }

    public updateResourceJobManager_args(
      org.apache.airavata.model.security.AuthzToken authzToken,
      String resourceJobManagerId,
      org.apache.airavata.model.appcatalog.computeresource.ResourceJobManager updatedResourceJobManager)
    {
      this();
      this.authzToken = authzToken;
      this.resourceJobManagerId = resourceJobManagerId;
      this.updatedResourceJobManager = updatedResourceJobManager;
    }

    /**
     * Performs a deep copy on <i>other</i>.
     */
    public updateResourceJobManager_args(updateResourceJobManager_args other) {
      if (other.isSetAuthzToken()) {
        this.authzToken = new org.apache.airavata.model.security.AuthzToken(other.authzToken);
      }
      if (other.isSetResourceJobManagerId()) {
        this.resourceJobManagerId = other.resourceJobManagerId;
      }
      if (other.isSetUpdatedResourceJobManager()) {
        this.updatedResourceJobManager = new org.apache.airavata.model.appcatalog.computeresource.ResourceJobManager(other.updatedResourceJobManager);
      }
    }

    public updateResourceJobManager_args deepCopy() {
      return new updateResourceJobManager_args(this);
    }

    @Override
    public void clear() {
      this.authzToken = null;
      this.resourceJobManagerId = null;
      this.updatedResourceJobManager = null;
    }

    public org.apache.airavata.model.security.AuthzToken getAuthzToken() {
      return this.authzToken;
    }

    public updateResourceJobManager_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 String getResourceJobManagerId() {
      return this.resourceJobManagerId;
    }

    public updateResourceJobManager_args setResourceJobManagerId(String resourceJobManagerId) {
      this.resourceJobManagerId = resourceJobManagerId;
      return this;
    }

    public void unsetResourceJobManagerId() {
      this.resourceJobManagerId = null;
    }

    /** Returns true if field resourceJobManagerId is set (has been assigned a value) and false otherwise */
    public boolean isSetResourceJobManagerId() {
      return this.resourceJobManagerId != null;
    }

    public void setResourceJobManagerIdIsSet(boolean value) {
      if (!value) {
        this.resourceJobManagerId = null;
      }
    }

    public org.apache.airavata.model.appcatalog.computeresource.ResourceJobManager getUpdatedResourceJobManager() {
      return this.updatedResourceJobManager;
    }

    public updateResourceJobManager_args setUpdatedResourceJobManager(org.apache.airavata.model.appcatalog.computeresource.ResourceJobManager updatedResourceJobManager) {
      this.updatedResourceJobManager = updatedResourceJobManager;
      return this;
    }

    public void unsetUpdatedResourceJobManager() {
      this.updatedResourceJobManager = null;
    }

    /** Returns true if field updatedResourceJobManager is set (has been assigned a value) and false otherwise */
    public boolean isSetUpdatedResourceJobManager() {
      return this.updatedResourceJobManager != null;
    }

    public void setUpdatedResourceJobManagerIsSet(boolean value) {
      if (!value) {
        this.updatedResourceJobManager = null;
      }
    }

    public void setFieldValue(_Fields field, Object value) {
      switch (field) {
      case AUTHZ_TOKEN:
        if (value == null) {
          unsetAuthzToken();
        } else {
          setAuthzToken((org.apache.airavata.model.security.AuthzToken)value);
        }
        break;

      case RESOURCE_JOB_MANAGER_ID:
        if (value == null) {
          unsetResourceJobManagerId();
        } else {
          setResourceJobManagerId((String)value);
        }
        break;

      case UPDATED_RESOURCE_JOB_MANAGER:
        if (value == null) {
          unsetUpdatedResourceJobManager();
        } else {
          setUpdatedResourceJobManager((org.apache.airavata.model.appcatalog.computeresource.ResourceJobManager)value);
        }
        break;

      }
    }

    public Object getFieldValue(_Fields field) {
      switch (field) {
      case AUTHZ_TOKEN:
        return getAuthzToken();

      case RESOURCE_JOB_MANAGER_ID:
        return getResourceJobManagerId();

      case UPDATED_RESOURCE_JOB_MANAGER:
        return getUpdatedResourceJobManager();

      }
      throw new IllegalStateException();
    }

    /** Returns true if field corresponding to fieldID is set (has been assigned a value) and false otherwise */
    public boolean isSet(_Fields field) {
      if (field == null) {
        throw new IllegalArgumentException();
      }

      switch (field) {
      case AUTHZ_TOKEN:
        return isSetAuthzToken();
      case RESOURCE_JOB_MANAGER_ID:
        return isSetResourceJobManagerId();
      case UPDATED_RESOURCE_JOB_MANAGER:
        return isSetUpdatedResourceJobManager();
      }
      throw new IllegalStateException();
    }

    @Override
    public boolean equals(Object that) {
      if (that == null)
        return false;
      if (that instanceof updateResourceJobManager_args)
        return this.equals((updateResourceJobManager_args)that);
      return false;
    }

    public boolean equals(updateResourceJobManager_args that) {
      if (that == null)
        return false;

      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_resourceJobManagerId = true && this.isSetResourceJobManagerId();
      boolean that_present_resourceJobManagerId = true && that.isSetResourceJobManagerId();
      if (this_present_resourceJobManagerId || that_present_resourceJobManagerId) {
        if (!(this_present_resourceJobManagerId && that_present_resourceJobManagerId))
          return false;
        if (!this.resourceJobManagerId.equals(that.resourceJobManagerId))
          return false;
      }

      boolean this_present_updatedResourceJobManager = true && this.isSetUpdatedResourceJobManager();
      boolean that_present_updatedResourceJobManager = true && that.isSetUpdatedResourceJobManager();
      if (this_present_updatedResourceJobManager || that_present_updatedResourceJobManager) {
        if (!(this_present_updatedResourceJobManager && that_present_updatedResourceJobManager))
          return false;
        if (!this.updatedResourceJobManager.equals(that.updatedResourceJobManager))
          return false;
      }

      return true;
    }

    @Override
    public int hashCode() {
      List<Object> list = new ArrayList<Object>();

      boolean present_authzToken = true && (isSetAuthzToken());
      list.add(present_authzToken);
      if (present_authzToken)
        list.add(authzToken);

      boolean present_resourceJobManagerId = true && (isSetResourceJobManagerId());
      list.add(present_resourceJobManagerId);
      if (present_resourceJobManagerId)
        list.add(resourceJobManagerId);

      boolean present_updatedResourceJobManager = true && (isSetUpdatedResourceJobManager());
      list.add(present_updatedResourceJobManager);
      if (present_updatedResourceJobManager)
        list.add(updatedResourceJobManager);

      return list.hashCode();
    }

    @Override
    public int compareTo(updateResourceJobManager_args other) {
      if (!getClass().equals(other.getClass())) {
        return getClass().getName().compareTo(other.getClass().getName());
      }

      int lastComparison = 0;

      lastComparison = 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 = Boolean.valueOf(isSetResourceJobManagerId()).compareTo(other.isSetResourceJobManagerId());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetResourceJobManagerId()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.resourceJobManagerId, other.resourceJobManagerId);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = Boolean.valueOf(isSetUpdatedResourceJobManager()).compareTo(other.isSetUpdatedResourceJobManager());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetUpdatedResourceJobManager()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.updatedResourceJobManager, other.updatedResourceJobManager);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      return 0;
    }

    public _Fields fieldForId(int fieldId) {
      return _Fields.findByThriftId(fieldId);
    }

    public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
      schemes.get(iprot.getScheme()).getScheme().read(iprot, this);
    }

    public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException {
      schemes.get(oprot.getScheme()).getScheme().write(oprot, this);
    }

    @Override
    public String toString() {
      StringBuilder sb = new StringBuilder("updateResourceJobManager_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("resourceJobManagerId:");
      if (this.resourceJobManagerId == null) {
        sb.append("null");
      } else {
        sb.append(this.resourceJobManagerId);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("updatedResourceJobManager:");
      if (this.updatedResourceJobManager == null) {
        sb.append("null");
      } else {
        sb.append(this.updatedResourceJobManager);
      }
      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 (resourceJobManagerId == null) {
        throw new org.apache.thrift.protocol.TProtocolException("Required field 'resourceJobManagerId' was not present! Struct: " + toString());
      }
      if (updatedResourceJobManager == null) {
        throw new org.apache.thrift.protocol.TProtocolException("Required field 'updatedResourceJobManager' was not present! Struct: " + toString());
      }
      // check for sub-struct validity
      if (authzToken != null) {
        authzToken.validate();
      }
      if (updatedResourceJobManager != null) {
        updatedResourceJobManager.validate();
      }
    }

    private void writeObject(java.io.ObjectOutputStream out) throws java.io.IOException {
      try {
        write(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(out)));
      } catch (org.apache.thrift.TException te) {
        throw new java.io.IOException(te);
      }
    }

    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, ClassNotFoundException {
      try {
        read(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(in)));
      } catch (org.apache.thrift.TException te) {
        throw new java.io.IOException(te);
      }
    }

    private static class updateResourceJobManager_argsStandardSchemeFactory implements SchemeFactory {
      public updateResourceJobManager_argsStandardScheme getScheme() {
        return new updateResourceJobManager_argsStandardScheme();
      }
    }

    private static class updateResourceJobManager_argsStandardScheme extends StandardScheme<updateResourceJobManager_args> {

      public void read(org.apache.thrift.protocol.TProtocol iprot, updateResourceJobManager_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: // RESOURCE_JOB_MANAGER_ID
              if (schemeField.type == org.apache.thrift.protocol.TType.STRING) {
                struct.resourceJobManagerId = iprot.readString();
                struct.setResourceJobManagerIdIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 3: // UPDATED_RESOURCE_JOB_MANAGER
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.updatedResourceJobManager = new org.apache.airavata.model.appcatalog.computeresource.ResourceJobManager();
                struct.updatedResourceJobManager.read(iprot);
                struct.setUpdatedResourceJobManagerIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            default:
              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
          }
          iprot.readFieldEnd();
        }
        iprot.readStructEnd();

        // check for required fields of primitive type, which can't be checked in the validate method
        struct.validate();
      }

      public void write(org.apache.thrift.protocol.TProtocol oprot, updateResourceJobManager_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.resourceJobManagerId != null) {
          oprot.writeFieldBegin(RESOURCE_JOB_MANAGER_ID_FIELD_DESC);
          oprot.writeString(struct.resourceJobManagerId);
          oprot.writeFieldEnd();
        }
        if (struct.updatedResourceJobManager != null) {
          oprot.writeFieldBegin(UPDATED_RESOURCE_JOB_MANAGER_FIELD_DESC);
          struct.updatedResourceJobManager.write(oprot);
          oprot.writeFieldEnd();
        }
        oprot.writeFieldStop();
        oprot.writeStructEnd();
      }

    }

    private static class updateResourceJobManager_argsTupleSchemeFactory implements SchemeFactory {
      public updateResourceJobManager_argsTupleScheme getScheme() {
        return new updateResourceJobManager_argsTupleScheme();
      }
    }

    private static class updateResourceJobManager_argsTupleScheme extends TupleScheme<updateResourceJobManager_args> {

      @Override
      public void write(org.apache.thrift.protocol.TProtocol prot, updateResourceJobManager_args struct) throws org.apache.thrift.TException {
        TTupleProtocol oprot = (TTupleProtocol) prot;
        struct.authzToken.write(oprot);
        oprot.writeString(struct.resourceJobManagerId);
        struct.updatedResourceJobManager.write(oprot);
      }

      @Override
      public void read(org.apache.thrift.protocol.TProtocol prot, updateResourceJobManager_args struct) throws org.apache.thrift.TException {
        TTupleProtocol iprot = (TTupleProtocol) prot;
        struct.authzToken = new org.apache.airavata.model.security.AuthzToken();
        struct.authzToken.read(iprot);
        struct.setAuthzTokenIsSet(true);
        struct.resourceJobManagerId = iprot.readString();
        struct.setResourceJobManagerIdIsSet(true);
        struct.updatedResourceJobManager = new org.apache.airavata.model.appcatalog.computeresource.ResourceJobManager();
        struct.updatedResourceJobManager.read(iprot);
        struct.setUpdatedResourceJobManagerIsSet(true);
      }
    }

  }

  public static class updateResourceJobManager_result implements org.apache.thrift.TBase<updateResourceJobManager_result, updateResourceJobManager_result._Fields>, java.io.Serializable, Cloneable, Comparable<updateResourceJobManager_result>   {
    private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("updateResourceJobManager_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 IRE_FIELD_DESC = new org.apache.thrift.protocol.TField("ire", org.apache.thrift.protocol.TType.STRUCT, (short)1);
    private static final org.apache.thrift.protocol.TField ACE_FIELD_DESC = new org.apache.thrift.protocol.TField("ace", org.apache.thrift.protocol.TType.STRUCT, (short)2);
    private static final org.apache.thrift.protocol.TField ASE_FIELD_DESC = new org.apache.thrift.protocol.TField("ase", org.apache.thrift.protocol.TType.STRUCT, (short)3);
    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)4);

    private static final Map<Class<? extends IScheme>, SchemeFactory> schemes = new HashMap<Class<? extends IScheme>, SchemeFactory>();
    static {
      schemes.put(StandardScheme.class, new updateResourceJobManager_resultStandardSchemeFactory());
      schemes.put(TupleScheme.class, new updateResourceJobManager_resultTupleSchemeFactory());
    }

    public boolean success; // required
    public org.apache.airavata.model.error.InvalidRequestException ire; // required
    public org.apache.airavata.model.error.AiravataClientException ace; // required
    public org.apache.airavata.model.error.AiravataSystemException ase; // 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"),
      IRE((short)1, "ire"),
      ACE((short)2, "ace"),
      ASE((short)3, "ase"),
      AE((short)4, "ae");

      private static final Map<String, _Fields> byName = new HashMap<String, _Fields>();

      static {
        for (_Fields field : EnumSet.allOf(_Fields.class)) {
          byName.put(field.getFieldName(), field);
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, or null if its not found.
       */
      public static _Fields findByThriftId(int fieldId) {
        switch(fieldId) {
          case 0: // SUCCESS
            return SUCCESS;
          case 1: // IRE
            return IRE;
          case 2: // ACE
            return ACE;
          case 3: // ASE
            return ASE;
          case 4: // 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 IllegalArgumentException("Field " + fieldId + " doesn't exist!");
        return fields;
      }

      /**
       * Find the _Fields constant that matches name, or null if its not found.
       */
      public static _Fields findByName(String name) {
        return byName.get(name);
      }

      private final short _thriftId;
      private final String _fieldName;

      _Fields(short thriftId, String fieldName) {
        _thriftId = thriftId;
        _fieldName = fieldName;
      }

      public short getThriftFieldId() {
        return _thriftId;
      }

      public String getFieldName() {
        return _fieldName;
      }
    }

    // isset id assignments
    private static final int __SUCCESS_ISSET_ID = 0;
    private byte __isset_bitfield = 0;
    public static final Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
    static {
      Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new EnumMap<_Fields, org.apache.thrift.meta_data.FieldMetaData>(_Fields.class);
      tmpMap.put(_Fields.SUCCESS, new org.apache.thrift.meta_data.FieldMetaData("success", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.BOOL)));
      tmpMap.put(_Fields.IRE, new org.apache.thrift.meta_data.FieldMetaData("ire", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRUCT)));
      tmpMap.put(_Fields.ACE, new org.apache.thrift.meta_data.FieldMetaData("ace", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRUCT)));
      tmpMap.put(_Fields.ASE, new org.apache.thrift.meta_data.FieldMetaData("ase", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRUCT)));
      tmpMap.put(_Fields.AE, new org.apache.thrift.meta_data.FieldMetaData("ae", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRUCT)));
      metaDataMap = Collections.unmodifiableMap(tmpMap);
      org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(updateResourceJobManager_result.class, metaDataMap);
    }

    public updateResourceJobManager_result() {
    }

    public updateResourceJobManager_result(
      boolean success,
      org.apache.airavata.model.error.InvalidRequestException ire,
      org.apache.airavata.model.error.AiravataClientException ace,
      org.apache.airavata.model.error.AiravataSystemException ase,
      org.apache.airavata.model.error.AuthorizationException ae)
    {
      this();
      this.success = success;
      setSuccessIsSet(true);
      this.ire = ire;
      this.ace = ace;
      this.ase = ase;
      this.ae = ae;
    }

    /**
     * Performs a deep copy on <i>other</i>.
     */
    public updateResourceJobManager_result(updateResourceJobManager_result other) {
      __isset_bitfield = other.__isset_bitfield;
      this.success = other.success;
      if (other.isSetIre()) {
        this.ire = new org.apache.airavata.model.error.InvalidRequestException(other.ire);
      }
      if (other.isSetAce()) {
        this.ace = new org.apache.airavata.model.error.AiravataClientException(other.ace);
      }
      if (other.isSetAse()) {
        this.ase = new org.apache.airavata.model.error.AiravataSystemException(other.ase);
      }
      if (other.isSetAe()) {
        this.ae = new org.apache.airavata.model.error.AuthorizationException(other.ae);
      }
    }

    public updateResourceJobManager_result deepCopy() {
      return new updateResourceJobManager_result(this);
    }

    @Override
    public void clear() {
      setSuccessIsSet(false);
      this.success = false;
      this.ire = null;
      this.ace = null;
      this.ase = null;
      this.ae = null;
    }

    public boolean isSuccess() {
      return this.success;
    }

    public updateResourceJobManager_result setSuccess(boolean success) {
      this.success = success;
      setSuccessIsSet(true);
      return this;
    }

    public void unsetSuccess() {
      __isset_bitfield = EncodingUtils.clearBit(__isset_bitfield, __SUCCESS_ISSET_ID);
    }

    /** Returns true if field success is set (has been assigned a value) and false otherwise */
    public boolean isSetSuccess() {
      return EncodingUtils.testBit(__isset_bitfield, __SUCCESS_ISSET_ID);
    }

    public void setSuccessIsSet(boolean value) {
      __isset_bitfield = EncodingUtils.setBit(__isset_bitfield, __SUCCESS_ISSET_ID, value);
    }

    public org.apache.airavata.model.error.InvalidRequestException getIre() {
      return this.ire;
    }

    public updateResourceJobManager_result setIre(org.apache.airavata.model.error.InvalidRequestException ire) {
      this.ire = ire;
      return this;
    }

    public void unsetIre() {
      this.ire = null;
    }

    /** Returns true if field ire is set (has been assigned a value) and false otherwise */
    public boolean isSetIre() {
      return this.ire != null;
    }

    public void setIreIsSet(boolean value) {
      if (!value) {
        this.ire = null;
      }
    }

    public org.apache.airavata.model.error.AiravataClientException getAce() {
      return this.ace;
    }

    public updateResourceJobManager_result setAce(org.apache.airavata.model.error.AiravataClientException ace) {
      this.ace = ace;
      return this;
    }

    public void unsetAce() {
      this.ace = null;
    }

    /** Returns true if field ace is set (has been assigned a value) and false otherwise */
    public boolean isSetAce() {
      return this.ace != null;
    }

    public void setAceIsSet(boolean value) {
      if (!value) {
        this.ace = null;
      }
    }

    public org.apache.airavata.model.error.AiravataSystemException getAse() {
      return this.ase;
    }

    public updateResourceJobManager_result setAse(org.apache.airavata.model.error.AiravataSystemException ase) {
      this.ase = ase;
      return this;
    }

    public void unsetAse() {
      this.ase = null;
    }

    /** Returns true if field ase is set (has been assigned a value) and false otherwise */
    public boolean isSetAse() {
      return this.ase != null;
    }

    public void setAseIsSet(boolean value) {
      if (!value) {
        this.ase = null;
      }
    }

    public org.apache.airavata.model.error.AuthorizationException getAe() {
      return this.ae;
    }

    public updateResourceJobManager_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, Object value) {
      switch (field) {
      case SUCCESS:
        if (value == null) {
          unsetSuccess();
        } else {
          setSuccess((Boolean)value);
        }
        break;

      case IRE:
        if (value == null) {
          unsetIre();
        } else {
          setIre((org.apache.airavata.model.error.InvalidRequestException)value);
        }
        break;

      case ACE:
        if (value == null) {
          unsetAce();
        } else {
          setAce((org.apache.airavata.model.error.AiravataClientException)value);
        }
        break;

      case ASE:
        if (value == null) {
          unsetAse();
        } else {
          setAse((org.apache.airavata.model.error.AiravataSystemException)value);
        }
        break;

      case AE:
        if (value == null) {
          unsetAe();
        } else {
          setAe((org.apache.airavata.model.error.AuthorizationException)value);
        }
        break;

      }
    }

    public Object getFieldValue(_Fields field) {
      switch (field) {
      case SUCCESS:
        return Boolean.valueOf(isSuccess());

      case IRE:
        return getIre();

      case ACE:
        return getAce();

      case ASE:
        return getAse();

      case AE:
        return getAe();

      }
      throw new IllegalStateException();
    }

    /** Returns true if field corresponding to fieldID is set (has been assigned a value) and false otherwise */
    public boolean isSet(_Fields field) {
      if (field == null) {
        throw new IllegalArgumentException();
      }

      switch (field) {
      case SUCCESS:
        return isSetSuccess();
      case IRE:
        return isSetIre();
      case ACE:
        return isSetAce();
      case ASE:
        return isSetAse();
      case AE:
        return isSetAe();
      }
      throw new IllegalStateException();
    }

    @Override
    public boolean equals(Object that) {
      if (that == null)
        return false;
      if (that instanceof updateResourceJobManager_result)
        return this.equals((updateResourceJobManager_result)that);
      return false;
    }

    public boolean equals(updateResourceJobManager_result that) {
      if (that == null)
        return false;

      boolean this_present_success = true;
      boolean that_present_success = true;
      if (this_present_success || that_present_success) {
        if (!(this_present_success && that_present_success))
          return false;
        if (this.success != that.success)
          return false;
      }

      boolean this_present_ire = true && this.isSetIre();
      boolean that_present_ire = true && that.isSetIre();
      if (this_present_ire || that_present_ire) {
        if (!(this_present_ire && that_present_ire))
          return false;
        if (!this.ire.equals(that.ire))
          return false;
      }

      boolean this_present_ace = true && this.isSetAce();
      boolean that_present_ace = true && that.isSetAce();
      if (this_present_ace || that_present_ace) {
        if (!(this_present_ace && that_present_ace))
          return false;
        if (!this.ace.equals(that.ace))
          return false;
      }

      boolean this_present_ase = true && this.isSetAse();
      boolean that_present_ase = true && that.isSetAse();
      if (this_present_ase || that_present_ase) {
        if (!(this_present_ase && that_present_ase))
          return false;
        if (!this.ase.equals(that.ase))
          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() {
      List<Object> list = new ArrayList<Object>();

      boolean present_success = true;
      list.add(present_success);
      if (present_success)
        list.add(success);

      boolean present_ire = true && (isSetIre());
      list.add(present_ire);
      if (present_ire)
        list.add(ire);

      boolean present_ace = true && (isSetAce());
      list.add(present_ace);
      if (present_ace)
        list.add(ace);

      boolean present_ase = true && (isSetAse());
      list.add(present_ase);
      if (present_ase)
        list.add(ase);

      boolean present_ae = true && (isSetAe());
      list.add(present_ae);
      if (present_ae)
        list.add(ae);

      return list.hashCode();
    }

    @Override
    public int compareTo(updateResourceJobManager_result other) {
      if (!getClass().equals(other.getClass())) {
        return getClass().getName().compareTo(other.getClass().getName());
      }

      int lastComparison = 0;

      lastComparison = Boolean.valueOf(isSetSuccess()).compareTo(other.isSetSuccess());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetSuccess()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.success, other.success);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = Boolean.valueOf(isSetIre()).compareTo(other.isSetIre());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetIre()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.ire, other.ire);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = Boolean.valueOf(isSetAce()).compareTo(other.isSetAce());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetAce()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.ace, other.ace);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = Boolean.valueOf(isSetAse()).compareTo(other.isSetAse());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetAse()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.ase, other.ase);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = 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 {
      schemes.get(iprot.getScheme()).getScheme().read(iprot, this);
    }

    public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException {
      schemes.get(oprot.getScheme()).getScheme().write(oprot, this);
      }

    @Override
    public String toString() {
      StringBuilder sb = new StringBuilder("updateResourceJobManager_result(");
      boolean first = true;

      sb.append("success:");
      sb.append(this.success);
      first = false;
      if (!first) sb.append(", ");
      sb.append("ire:");
      if (this.ire == null) {
        sb.append("null");
      } else {
        sb.append(this.ire);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("ace:");
      if (this.ace == null) {
        sb.append("null");
      } else {
        sb.append(this.ace);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("ase:");
      if (this.ase == null) {
        sb.append("null");
      } else {
        sb.append(this.ase);
      }
      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, 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 updateResourceJobManager_resultStandardSchemeFactory implements SchemeFactory {
      public updateResourceJobManager_resultStandardScheme getScheme() {
        return new updateResourceJobManager_resultStandardScheme();
      }
    }

    private static class updateResourceJobManager_resultStandardScheme extends StandardScheme<updateResourceJobManager_result> {

      public void read(org.apache.thrift.protocol.TProtocol iprot, updateResourceJobManager_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: // IRE
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.ire = new org.apache.airavata.model.error.InvalidRequestException();
                struct.ire.read(iprot);
                struct.setIreIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 2: // ACE
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.ace = new org.apache.airavata.model.error.AiravataClientException();
                struct.ace.read(iprot);
                struct.setAceIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 3: // ASE
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.ase = new org.apache.airavata.model.error.AiravataSystemException();
                struct.ase.read(iprot);
                struct.setAseIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 4: // 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, updateResourceJobManager_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.ire != null) {
          oprot.writeFieldBegin(IRE_FIELD_DESC);
          struct.ire.write(oprot);
          oprot.writeFieldEnd();
        }
        if (struct.ace != null) {
          oprot.writeFieldBegin(ACE_FIELD_DESC);
          struct.ace.write(oprot);
          oprot.writeFieldEnd();
        }
        if (struct.ase != null) {
          oprot.writeFieldBegin(ASE_FIELD_DESC);
          struct.ase.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 updateResourceJobManager_resultTupleSchemeFactory implements SchemeFactory {
      public updateResourceJobManager_resultTupleScheme getScheme() {
        return new updateResourceJobManager_resultTupleScheme();
      }
    }

    private static class updateResourceJobManager_resultTupleScheme extends TupleScheme<updateResourceJobManager_result> {

      @Override
      public void write(org.apache.thrift.protocol.TProtocol prot, updateResourceJobManager_result struct) throws org.apache.thrift.TException {
        TTupleProtocol oprot = (TTupleProtocol) prot;
        BitSet optionals = new BitSet();
        if (struct.isSetSuccess()) {
          optionals.set(0);
        }
        if (struct.isSetIre()) {
          optionals.set(1);
        }
        if (struct.isSetAce()) {
          optionals.set(2);
        }
        if (struct.isSetAse()) {
          optionals.set(3);
        }
        if (struct.isSetAe()) {
          optionals.set(4);
        }
        oprot.writeBitSet(optionals, 5);
        if (struct.isSetSuccess()) {
          oprot.writeBool(struct.success);
        }
        if (struct.isSetIre()) {
          struct.ire.write(oprot);
        }
        if (struct.isSetAce()) {
          struct.ace.write(oprot);
        }
        if (struct.isSetAse()) {
          struct.ase.write(oprot);
        }
        if (struct.isSetAe()) {
          struct.ae.write(oprot);
        }
      }

      @Override
      public void read(org.apache.thrift.protocol.TProtocol prot, updateResourceJobManager_result struct) throws org.apache.thrift.TException {
        TTupleProtocol iprot = (TTupleProtocol) prot;
        BitSet incoming = iprot.readBitSet(5);
        if (incoming.get(0)) {
          struct.success = iprot.readBool();
          struct.setSuccessIsSet(true);
        }
        if (incoming.get(1)) {
          struct.ire = new org.apache.airavata.model.error.InvalidRequestException();
          struct.ire.read(iprot);
          struct.setIreIsSet(true);
        }
        if (incoming.get(2)) {
          struct.ace = new org.apache.airavata.model.error.AiravataClientException();
          struct.ace.read(iprot);
          struct.setAceIsSet(true);
        }
        if (incoming.get(3)) {
          struct.ase = new org.apache.airavata.model.error.AiravataSystemException();
          struct.ase.read(iprot);
          struct.setAseIsSet(true);
        }
        if (incoming.get(4)) {
          struct.ae = new org.apache.airavata.model.error.AuthorizationException();
          struct.ae.read(iprot);
          struct.setAeIsSet(true);
        }
      }
    }

  }

  public static class getResourceJobManager_args implements org.apache.thrift.TBase<getResourceJobManager_args, getResourceJobManager_args._Fields>, java.io.Serializable, Cloneable, Comparable<getResourceJobManager_args>   {
    private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("getResourceJobManager_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 RESOURCE_JOB_MANAGER_ID_FIELD_DESC = new org.apache.thrift.protocol.TField("resourceJobManagerId", org.apache.thrift.protocol.TType.STRING, (short)2);

    private static final Map<Class<? extends IScheme>, SchemeFactory> schemes = new HashMap<Class<? extends IScheme>, SchemeFactory>();
    static {
      schemes.put(StandardScheme.class, new getResourceJobManager_argsStandardSchemeFactory());
      schemes.put(TupleScheme.class, new getResourceJobManager_argsTupleSchemeFactory());
    }

    public org.apache.airavata.model.security.AuthzToken authzToken; // required
    public String resourceJobManagerId; // required

    /** 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"),
      RESOURCE_JOB_MANAGER_ID((short)2, "resourceJobManagerId");

      private static final Map<String, _Fields> byName = new HashMap<String, _Fields>();

      static {
        for (_Fields field : EnumSet.allOf(_Fields.class)) {
          byName.put(field.getFieldName(), field);
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, or null if its not found.
       */
      public static _Fields findByThriftId(int fieldId) {
        switch(fieldId) {
          case 1: // AUTHZ_TOKEN
            return AUTHZ_TOKEN;
          case 2: // RESOURCE_JOB_MANAGER_ID
            return RESOURCE_JOB_MANAGER_ID;
          default:
            return null;
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, throwing an exception
       * if it is not found.
       */
      public static _Fields findByThriftIdOrThrow(int fieldId) {
        _Fields fields = findByThriftId(fieldId);
        if (fields == null) throw new IllegalArgumentException("Field " + fieldId + " doesn't exist!");
        return fields;
      }

      /**
       * Find the _Fields constant that matches name, or null if its not found.
       */
      public static _Fields findByName(String name) {
        return byName.get(name);
      }

      private final short _thriftId;
      private final String _fieldName;

      _Fields(short thriftId, String fieldName) {
        _thriftId = thriftId;
        _fieldName = fieldName;
      }

      public short getThriftFieldId() {
        return _thriftId;
      }

      public String getFieldName() {
        return _fieldName;
      }
    }

    // isset id assignments
    public static final Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
    static {
      Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new EnumMap<_Fields, org.apache.thrift.meta_data.FieldMetaData>(_Fields.class);
      tmpMap.put(_Fields.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.RESOURCE_JOB_MANAGER_ID, new org.apache.thrift.meta_data.FieldMetaData("resourceJobManagerId", org.apache.thrift.TFieldRequirementType.REQUIRED, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING)));
      metaDataMap = Collections.unmodifiableMap(tmpMap);
      org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(getResourceJobManager_args.class, metaDataMap);
    }

    public getResourceJobManager_args() {
    }

    public getResourceJobManager_args(
      org.apache.airavata.model.security.AuthzToken authzToken,
      String resourceJobManagerId)
    {
      this();
      this.authzToken = authzToken;
      this.resourceJobManagerId = resourceJobManagerId;
    }

    /**
     * Performs a deep copy on <i>other</i>.
     */
    public getResourceJobManager_args(getResourceJobManager_args other) {
      if (other.isSetAuthzToken()) {
        this.authzToken = new org.apache.airavata.model.security.AuthzToken(other.authzToken);
      }
      if (other.isSetResourceJobManagerId()) {
        this.resourceJobManagerId = other.resourceJobManagerId;
      }
    }

    public getResourceJobManager_args deepCopy() {
      return new getResourceJobManager_args(this);
    }

    @Override
    public void clear() {
      this.authzToken = null;
      this.resourceJobManagerId = null;
    }

    public org.apache.airavata.model.security.AuthzToken getAuthzToken() {
      return this.authzToken;
    }

    public getResourceJobManager_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 String getResourceJobManagerId() {
      return this.resourceJobManagerId;
    }

    public getResourceJobManager_args setResourceJobManagerId(String resourceJobManagerId) {
      this.resourceJobManagerId = resourceJobManagerId;
      return this;
    }

    public void unsetResourceJobManagerId() {
      this.resourceJobManagerId = null;
    }

    /** Returns true if field resourceJobManagerId is set (has been assigned a value) and false otherwise */
    public boolean isSetResourceJobManagerId() {
      return this.resourceJobManagerId != null;
    }

    public void setResourceJobManagerIdIsSet(boolean value) {
      if (!value) {
        this.resourceJobManagerId = null;
      }
    }

    public void setFieldValue(_Fields field, Object value) {
      switch (field) {
      case AUTHZ_TOKEN:
        if (value == null) {
          unsetAuthzToken();
        } else {
          setAuthzToken((org.apache.airavata.model.security.AuthzToken)value);
        }
        break;

      case RESOURCE_JOB_MANAGER_ID:
        if (value == null) {
          unsetResourceJobManagerId();
        } else {
          setResourceJobManagerId((String)value);
        }
        break;

      }
    }

    public Object getFieldValue(_Fields field) {
      switch (field) {
      case AUTHZ_TOKEN:
        return getAuthzToken();

      case RESOURCE_JOB_MANAGER_ID:
        return getResourceJobManagerId();

      }
      throw new IllegalStateException();
    }

    /** Returns true if field corresponding to fieldID is set (has been assigned a value) and false otherwise */
    public boolean isSet(_Fields field) {
      if (field == null) {
        throw new IllegalArgumentException();
      }

      switch (field) {
      case AUTHZ_TOKEN:
        return isSetAuthzToken();
      case RESOURCE_JOB_MANAGER_ID:
        return isSetResourceJobManagerId();
      }
      throw new IllegalStateException();
    }

    @Override
    public boolean equals(Object that) {
      if (that == null)
        return false;
      if (that instanceof getResourceJobManager_args)
        return this.equals((getResourceJobManager_args)that);
      return false;
    }

    public boolean equals(getResourceJobManager_args that) {
      if (that == null)
        return false;

      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_resourceJobManagerId = true && this.isSetResourceJobManagerId();
      boolean that_present_resourceJobManagerId = true && that.isSetResourceJobManagerId();
      if (this_present_resourceJobManagerId || that_present_resourceJobManagerId) {
        if (!(this_present_resourceJobManagerId && that_present_resourceJobManagerId))
          return false;
        if (!this.resourceJobManagerId.equals(that.resourceJobManagerId))
          return false;
      }

      return true;
    }

    @Override
    public int hashCode() {
      List<Object> list = new ArrayList<Object>();

      boolean present_authzToken = true && (isSetAuthzToken());
      list.add(present_authzToken);
      if (present_authzToken)
        list.add(authzToken);

      boolean present_resourceJobManagerId = true && (isSetResourceJobManagerId());
      list.add(present_resourceJobManagerId);
      if (present_resourceJobManagerId)
        list.add(resourceJobManagerId);

      return list.hashCode();
    }

    @Override
    public int compareTo(getResourceJobManager_args other) {
      if (!getClass().equals(other.getClass())) {
        return getClass().getName().compareTo(other.getClass().getName());
      }

      int lastComparison = 0;

      lastComparison = 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 = Boolean.valueOf(isSetResourceJobManagerId()).compareTo(other.isSetResourceJobManagerId());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetResourceJobManagerId()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.resourceJobManagerId, other.resourceJobManagerId);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      return 0;
    }

    public _Fields fieldForId(int fieldId) {
      return _Fields.findByThriftId(fieldId);
    }

    public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
      schemes.get(iprot.getScheme()).getScheme().read(iprot, this);
    }

    public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException {
      schemes.get(oprot.getScheme()).getScheme().write(oprot, this);
    }

    @Override
    public String toString() {
      StringBuilder sb = new StringBuilder("getResourceJobManager_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("resourceJobManagerId:");
      if (this.resourceJobManagerId == null) {
        sb.append("null");
      } else {
        sb.append(this.resourceJobManagerId);
      }
      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 (resourceJobManagerId == null) {
        throw new org.apache.thrift.protocol.TProtocolException("Required field 'resourceJobManagerId' 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, 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 getResourceJobManager_argsStandardSchemeFactory implements SchemeFactory {
      public getResourceJobManager_argsStandardScheme getScheme() {
        return new getResourceJobManager_argsStandardScheme();
      }
    }

    private static class getResourceJobManager_argsStandardScheme extends StandardScheme<getResourceJobManager_args> {

      public void read(org.apache.thrift.protocol.TProtocol iprot, getResourceJobManager_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: // RESOURCE_JOB_MANAGER_ID
              if (schemeField.type == org.apache.thrift.protocol.TType.STRING) {
                struct.resourceJobManagerId = iprot.readString();
                struct.setResourceJobManagerIdIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            default:
              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
          }
          iprot.readFieldEnd();
        }
        iprot.readStructEnd();

        // check for required fields of primitive type, which can't be checked in the validate method
        struct.validate();
      }

      public void write(org.apache.thrift.protocol.TProtocol oprot, getResourceJobManager_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.resourceJobManagerId != null) {
          oprot.writeFieldBegin(RESOURCE_JOB_MANAGER_ID_FIELD_DESC);
          oprot.writeString(struct.resourceJobManagerId);
          oprot.writeFieldEnd();
        }
        oprot.writeFieldStop();
        oprot.writeStructEnd();
      }

    }

    private static class getResourceJobManager_argsTupleSchemeFactory implements SchemeFactory {
      public getResourceJobManager_argsTupleScheme getScheme() {
        return new getResourceJobManager_argsTupleScheme();
      }
    }

    private static class getResourceJobManager_argsTupleScheme extends TupleScheme<getResourceJobManager_args> {

      @Override
      public void write(org.apache.thrift.protocol.TProtocol prot, getResourceJobManager_args struct) throws org.apache.thrift.TException {
        TTupleProtocol oprot = (TTupleProtocol) prot;
        struct.authzToken.write(oprot);
        oprot.writeString(struct.resourceJobManagerId);
      }

      @Override
      public void read(org.apache.thrift.protocol.TProtocol prot, getResourceJobManager_args struct) throws org.apache.thrift.TException {
        TTupleProtocol iprot = (TTupleProtocol) prot;
        struct.authzToken = new org.apache.airavata.model.security.AuthzToken();
        struct.authzToken.read(iprot);
        struct.setAuthzTokenIsSet(true);
        struct.resourceJobManagerId = iprot.readString();
        struct.setResourceJobManagerIdIsSet(true);
      }
    }

  }

  public static class getResourceJobManager_result implements org.apache.thrift.TBase<getResourceJobManager_result, getResourceJobManager_result._Fields>, java.io.Serializable, Cloneable, Comparable<getResourceJobManager_result>   {
    private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("getResourceJobManager_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 IRE_FIELD_DESC = new org.apache.thrift.protocol.TField("ire", org.apache.thrift.protocol.TType.STRUCT, (short)1);
    private static final org.apache.thrift.protocol.TField ACE_FIELD_DESC = new org.apache.thrift.protocol.TField("ace", org.apache.thrift.protocol.TType.STRUCT, (short)2);
    private static final org.apache.thrift.protocol.TField ASE_FIELD_DESC = new org.apache.thrift.protocol.TField("ase", org.apache.thrift.protocol.TType.STRUCT, (short)3);
    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)4);

    private static final Map<Class<? extends IScheme>, SchemeFactory> schemes = new HashMap<Class<? extends IScheme>, SchemeFactory>();
    static {
      schemes.put(StandardScheme.class, new getResourceJobManager_resultStandardSchemeFactory());
      schemes.put(TupleScheme.class, new getResourceJobManager_resultTupleSchemeFactory());
    }

    public org.apache.airavata.model.appcatalog.computeresource.ResourceJobManager success; // required
    public org.apache.airavata.model.error.InvalidRequestException ire; // required
    public org.apache.airavata.model.error.AiravataClientException ace; // required
    public org.apache.airavata.model.error.AiravataSystemException ase; // 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"),
      IRE((short)1, "ire"),
      ACE((short)2, "ace"),
      ASE((short)3, "ase"),
      AE((short)4, "ae");

      private static final Map<String, _Fields> byName = new HashMap<String, _Fields>();

      static {
        for (_Fields field : EnumSet.allOf(_Fields.class)) {
          byName.put(field.getFieldName(), field);
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, or null if its not found.
       */
      public static _Fields findByThriftId(int fieldId) {
        switch(fieldId) {
          case 0: // SUCCESS
            return SUCCESS;
          case 1: // IRE
            return IRE;
          case 2: // ACE
            return ACE;
          case 3: // ASE
            return ASE;
          case 4: // 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 IllegalArgumentException("Field " + fieldId + " doesn't exist!");
        return fields;
      }

      /**
       * Find the _Fields constant that matches name, or null if its not found.
       */
      public static _Fields findByName(String name) {
        return byName.get(name);
      }

      private final short _thriftId;
      private final String _fieldName;

      _Fields(short thriftId, String fieldName) {
        _thriftId = thriftId;
        _fieldName = fieldName;
      }

      public short getThriftFieldId() {
        return _thriftId;
      }

      public String getFieldName() {
        return _fieldName;
      }
    }

    // isset id assignments
    public static final Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
    static {
      Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new EnumMap<_Fields, org.apache.thrift.meta_data.FieldMetaData>(_Fields.class);
      tmpMap.put(_Fields.SUCCESS, new org.apache.thrift.meta_data.FieldMetaData("success", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.StructMetaData(org.apache.thrift.protocol.TType.STRUCT, org.apache.airavata.model.appcatalog.computeresource.ResourceJobManager.class)));
      tmpMap.put(_Fields.IRE, new org.apache.thrift.meta_data.FieldMetaData("ire", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRUCT)));
      tmpMap.put(_Fields.ACE, new org.apache.thrift.meta_data.FieldMetaData("ace", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRUCT)));
      tmpMap.put(_Fields.ASE, new org.apache.thrift.meta_data.FieldMetaData("ase", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRUCT)));
      tmpMap.put(_Fields.AE, new org.apache.thrift.meta_data.FieldMetaData("ae", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRUCT)));
      metaDataMap = Collections.unmodifiableMap(tmpMap);
      org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(getResourceJobManager_result.class, metaDataMap);
    }

    public getResourceJobManager_result() {
    }

    public getResourceJobManager_result(
      org.apache.airavata.model.appcatalog.computeresource.ResourceJobManager success,
      org.apache.airavata.model.error.InvalidRequestException ire,
      org.apache.airavata.model.error.AiravataClientException ace,
      org.apache.airavata.model.error.AiravataSystemException ase,
      org.apache.airavata.model.error.AuthorizationException ae)
    {
      this();
      this.success = success;
      this.ire = ire;
      this.ace = ace;
      this.ase = ase;
      this.ae = ae;
    }

    /**
     * Performs a deep copy on <i>other</i>.
     */
    public getResourceJobManager_result(getResourceJobManager_result other) {
      if (other.isSetSuccess()) {
        this.success = new org.apache.airavata.model.appcatalog.computeresource.ResourceJobManager(other.success);
      }
      if (other.isSetIre()) {
        this.ire = new org.apache.airavata.model.error.InvalidRequestException(other.ire);
      }
      if (other.isSetAce()) {
        this.ace = new org.apache.airavata.model.error.AiravataClientException(other.ace);
      }
      if (other.isSetAse()) {
        this.ase = new org.apache.airavata.model.error.AiravataSystemException(other.ase);
      }
      if (other.isSetAe()) {
        this.ae = new org.apache.airavata.model.error.AuthorizationException(other.ae);
      }
    }

    public getResourceJobManager_result deepCopy() {
      return new getResourceJobManager_result(this);
    }

    @Override
    public void clear() {
      this.success = null;
      this.ire = null;
      this.ace = null;
      this.ase = null;
      this.ae = null;
    }

    public org.apache.airavata.model.appcatalog.computeresource.ResourceJobManager getSuccess() {
      return this.success;
    }

    public getResourceJobManager_result setSuccess(org.apache.airavata.model.appcatalog.computeresource.ResourceJobManager 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.model.error.InvalidRequestException getIre() {
      return this.ire;
    }

    public getResourceJobManager_result setIre(org.apache.airavata.model.error.InvalidRequestException ire) {
      this.ire = ire;
      return this;
    }

    public void unsetIre() {
      this.ire = null;
    }

    /** Returns true if field ire is set (has been assigned a value) and false otherwise */
    public boolean isSetIre() {
      return this.ire != null;
    }

    public void setIreIsSet(boolean value) {
      if (!value) {
        this.ire = null;
      }
    }

    public org.apache.airavata.model.error.AiravataClientException getAce() {
      return this.ace;
    }

    public getResourceJobManager_result setAce(org.apache.airavata.model.error.AiravataClientException ace) {
      this.ace = ace;
      return this;
    }

    public void unsetAce() {
      this.ace = null;
    }

    /** Returns true if field ace is set (has been assigned a value) and false otherwise */
    public boolean isSetAce() {
      return this.ace != null;
    }

    public void setAceIsSet(boolean value) {
      if (!value) {
        this.ace = null;
      }
    }

    public org.apache.airavata.model.error.AiravataSystemException getAse() {
      return this.ase;
    }

    public getResourceJobManager_result setAse(org.apache.airavata.model.error.AiravataSystemException ase) {
      this.ase = ase;
      return this;
    }

    public void unsetAse() {
      this.ase = null;
    }

    /** Returns true if field ase is set (has been assigned a value) and false otherwise */
    public boolean isSetAse() {
      return this.ase != null;
    }

    public void setAseIsSet(boolean value) {
      if (!value) {
        this.ase = null;
      }
    }

    public org.apache.airavata.model.error.AuthorizationException getAe() {
      return this.ae;
    }

    public getResourceJobManager_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, Object value) {
      switch (field) {
      case SUCCESS:
        if (value == null) {
          unsetSuccess();
        } else {
          setSuccess((org.apache.airavata.model.appcatalog.computeresource.ResourceJobManager)value);
        }
        break;

      case IRE:
        if (value == null) {
          unsetIre();
        } else {
          setIre((org.apache.airavata.model.error.InvalidRequestException)value);
        }
        break;

      case ACE:
        if (value == null) {
          unsetAce();
        } else {
          setAce((org.apache.airavata.model.error.AiravataClientException)value);
        }
        break;

      case ASE:
        if (value == null) {
          unsetAse();
        } else {
          setAse((org.apache.airavata.model.error.AiravataSystemException)value);
        }
        break;

      case AE:
        if (value == null) {
          unsetAe();
        } else {
          setAe((org.apache.airavata.model.error.AuthorizationException)value);
        }
        break;

      }
    }

    public Object getFieldValue(_Fields field) {
      switch (field) {
      case SUCCESS:
        return getSuccess();

      case IRE:
        return getIre();

      case ACE:
        return getAce();

      case ASE:
        return getAse();

      case AE:
        return getAe();

      }
      throw new IllegalStateException();
    }

    /** Returns true if field corresponding to fieldID is set (has been assigned a value) and false otherwise */
    public boolean isSet(_Fields field) {
      if (field == null) {
        throw new IllegalArgumentException();
      }

      switch (field) {
      case SUCCESS:
        return isSetSuccess();
      case IRE:
        return isSetIre();
      case ACE:
        return isSetAce();
      case ASE:
        return isSetAse();
      case AE:
        return isSetAe();
      }
      throw new IllegalStateException();
    }

    @Override
    public boolean equals(Object that) {
      if (that == null)
        return false;
      if (that instanceof getResourceJobManager_result)
        return this.equals((getResourceJobManager_result)that);
      return false;
    }

    public boolean equals(getResourceJobManager_result that) {
      if (that == null)
        return false;

      boolean this_present_success = true && this.isSetSuccess();
      boolean that_present_success = true && that.isSetSuccess();
      if (this_present_success || that_present_success) {
        if (!(this_present_success && that_present_success))
          return false;
        if (!this.success.equals(that.success))
          return false;
      }

      boolean this_present_ire = true && this.isSetIre();
      boolean that_present_ire = true && that.isSetIre();
      if (this_present_ire || that_present_ire) {
        if (!(this_present_ire && that_present_ire))
          return false;
        if (!this.ire.equals(that.ire))
          return false;
      }

      boolean this_present_ace = true && this.isSetAce();
      boolean that_present_ace = true && that.isSetAce();
      if (this_present_ace || that_present_ace) {
        if (!(this_present_ace && that_present_ace))
          return false;
        if (!this.ace.equals(that.ace))
          return false;
      }

      boolean this_present_ase = true && this.isSetAse();
      boolean that_present_ase = true && that.isSetAse();
      if (this_present_ase || that_present_ase) {
        if (!(this_present_ase && that_present_ase))
          return false;
        if (!this.ase.equals(that.ase))
          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() {
      List<Object> list = new ArrayList<Object>();

      boolean present_success = true && (isSetSuccess());
      list.add(present_success);
      if (present_success)
        list.add(success);

      boolean present_ire = true && (isSetIre());
      list.add(present_ire);
      if (present_ire)
        list.add(ire);

      boolean present_ace = true && (isSetAce());
      list.add(present_ace);
      if (present_ace)
        list.add(ace);

      boolean present_ase = true && (isSetAse());
      list.add(present_ase);
      if (present_ase)
        list.add(ase);

      boolean present_ae = true && (isSetAe());
      list.add(present_ae);
      if (present_ae)
        list.add(ae);

      return list.hashCode();
    }

    @Override
    public int compareTo(getResourceJobManager_result other) {
      if (!getClass().equals(other.getClass())) {
        return getClass().getName().compareTo(other.getClass().getName());
      }

      int lastComparison = 0;

      lastComparison = Boolean.valueOf(isSetSuccess()).compareTo(other.isSetSuccess());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetSuccess()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.success, other.success);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = Boolean.valueOf(isSetIre()).compareTo(other.isSetIre());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetIre()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.ire, other.ire);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = Boolean.valueOf(isSetAce()).compareTo(other.isSetAce());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetAce()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.ace, other.ace);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = Boolean.valueOf(isSetAse()).compareTo(other.isSetAse());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetAse()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.ase, other.ase);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = 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 {
      schemes.get(iprot.getScheme()).getScheme().read(iprot, this);
    }

    public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException {
      schemes.get(oprot.getScheme()).getScheme().write(oprot, this);
      }

    @Override
    public String toString() {
      StringBuilder sb = new StringBuilder("getResourceJobManager_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("ire:");
      if (this.ire == null) {
        sb.append("null");
      } else {
        sb.append(this.ire);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("ace:");
      if (this.ace == null) {
        sb.append("null");
      } else {
        sb.append(this.ace);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("ase:");
      if (this.ase == null) {
        sb.append("null");
      } else {
        sb.append(this.ase);
      }
      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, 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 getResourceJobManager_resultStandardSchemeFactory implements SchemeFactory {
      public getResourceJobManager_resultStandardScheme getScheme() {
        return new getResourceJobManager_resultStandardScheme();
      }
    }

    private static class getResourceJobManager_resultStandardScheme extends StandardScheme<getResourceJobManager_result> {

      public void read(org.apache.thrift.protocol.TProtocol iprot, getResourceJobManager_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.appcatalog.computeresource.ResourceJobManager();
                struct.success.read(iprot);
                struct.setSuccessIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 1: // IRE
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.ire = new org.apache.airavata.model.error.InvalidRequestException();
                struct.ire.read(iprot);
                struct.setIreIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 2: // ACE
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.ace = new org.apache.airavata.model.error.AiravataClientException();
                struct.ace.read(iprot);
                struct.setAceIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 3: // ASE
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.ase = new org.apache.airavata.model.error.AiravataSystemException();
                struct.ase.read(iprot);
                struct.setAseIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 4: // 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, getResourceJobManager_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.ire != null) {
          oprot.writeFieldBegin(IRE_FIELD_DESC);
          struct.ire.write(oprot);
          oprot.writeFieldEnd();
        }
        if (struct.ace != null) {
          oprot.writeFieldBegin(ACE_FIELD_DESC);
          struct.ace.write(oprot);
          oprot.writeFieldEnd();
        }
        if (struct.ase != null) {
          oprot.writeFieldBegin(ASE_FIELD_DESC);
          struct.ase.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 getResourceJobManager_resultTupleSchemeFactory implements SchemeFactory {
      public getResourceJobManager_resultTupleScheme getScheme() {
        return new getResourceJobManager_resultTupleScheme();
      }
    }

    private static class getResourceJobManager_resultTupleScheme extends TupleScheme<getResourceJobManager_result> {

      @Override
      public void write(org.apache.thrift.protocol.TProtocol prot, getResourceJobManager_result struct) throws org.apache.thrift.TException {
        TTupleProtocol oprot = (TTupleProtocol) prot;
        BitSet optionals = new BitSet();
        if (struct.isSetSuccess()) {
          optionals.set(0);
        }
        if (struct.isSetIre()) {
          optionals.set(1);
        }
        if (struct.isSetAce()) {
          optionals.set(2);
        }
        if (struct.isSetAse()) {
          optionals.set(3);
        }
        if (struct.isSetAe()) {
          optionals.set(4);
        }
        oprot.writeBitSet(optionals, 5);
        if (struct.isSetSuccess()) {
          struct.success.write(oprot);
        }
        if (struct.isSetIre()) {
          struct.ire.write(oprot);
        }
        if (struct.isSetAce()) {
          struct.ace.write(oprot);
        }
        if (struct.isSetAse()) {
          struct.ase.write(oprot);
        }
        if (struct.isSetAe()) {
          struct.ae.write(oprot);
        }
      }

      @Override
      public void read(org.apache.thrift.protocol.TProtocol prot, getResourceJobManager_result struct) throws org.apache.thrift.TException {
        TTupleProtocol iprot = (TTupleProtocol) prot;
        BitSet incoming = iprot.readBitSet(5);
        if (incoming.get(0)) {
          struct.success = new org.apache.airavata.model.appcatalog.computeresource.ResourceJobManager();
          struct.success.read(iprot);
          struct.setSuccessIsSet(true);
        }
        if (incoming.get(1)) {
          struct.ire = new org.apache.airavata.model.error.InvalidRequestException();
          struct.ire.read(iprot);
          struct.setIreIsSet(true);
        }
        if (incoming.get(2)) {
          struct.ace = new org.apache.airavata.model.error.AiravataClientException();
          struct.ace.read(iprot);
          struct.setAceIsSet(true);
        }
        if (incoming.get(3)) {
          struct.ase = new org.apache.airavata.model.error.AiravataSystemException();
          struct.ase.read(iprot);
          struct.setAseIsSet(true);
        }
        if (incoming.get(4)) {
          struct.ae = new org.apache.airavata.model.error.AuthorizationException();
          struct.ae.read(iprot);
          struct.setAeIsSet(true);
        }
      }
    }

  }

  public static class deleteResourceJobManager_args implements org.apache.thrift.TBase<deleteResourceJobManager_args, deleteResourceJobManager_args._Fields>, java.io.Serializable, Cloneable, Comparable<deleteResourceJobManager_args>   {
    private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("deleteResourceJobManager_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 RESOURCE_JOB_MANAGER_ID_FIELD_DESC = new org.apache.thrift.protocol.TField("resourceJobManagerId", org.apache.thrift.protocol.TType.STRING, (short)2);

    private static final Map<Class<? extends IScheme>, SchemeFactory> schemes = new HashMap<Class<? extends IScheme>, SchemeFactory>();
    static {
      schemes.put(StandardScheme.class, new deleteResourceJobManager_argsStandardSchemeFactory());
      schemes.put(TupleScheme.class, new deleteResourceJobManager_argsTupleSchemeFactory());
    }

    public org.apache.airavata.model.security.AuthzToken authzToken; // required
    public String resourceJobManagerId; // required

    /** 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"),
      RESOURCE_JOB_MANAGER_ID((short)2, "resourceJobManagerId");

      private static final Map<String, _Fields> byName = new HashMap<String, _Fields>();

      static {
        for (_Fields field : EnumSet.allOf(_Fields.class)) {
          byName.put(field.getFieldName(), field);
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, or null if its not found.
       */
      public static _Fields findByThriftId(int fieldId) {
        switch(fieldId) {
          case 1: // AUTHZ_TOKEN
            return AUTHZ_TOKEN;
          case 2: // RESOURCE_JOB_MANAGER_ID
            return RESOURCE_JOB_MANAGER_ID;
          default:
            return null;
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, throwing an exception
       * if it is not found.
       */
      public static _Fields findByThriftIdOrThrow(int fieldId) {
        _Fields fields = findByThriftId(fieldId);
        if (fields == null) throw new IllegalArgumentException("Field " + fieldId + " doesn't exist!");
        return fields;
      }

      /**
       * Find the _Fields constant that matches name, or null if its not found.
       */
      public static _Fields findByName(String name) {
        return byName.get(name);
      }

      private final short _thriftId;
      private final String _fieldName;

      _Fields(short thriftId, String fieldName) {
        _thriftId = thriftId;
        _fieldName = fieldName;
      }

      public short getThriftFieldId() {
        return _thriftId;
      }

      public String getFieldName() {
        return _fieldName;
      }
    }

    // isset id assignments
    public static final Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
    static {
      Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new EnumMap<_Fields, org.apache.thrift.meta_data.FieldMetaData>(_Fields.class);
      tmpMap.put(_Fields.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.RESOURCE_JOB_MANAGER_ID, new org.apache.thrift.meta_data.FieldMetaData("resourceJobManagerId", org.apache.thrift.TFieldRequirementType.REQUIRED, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING)));
      metaDataMap = Collections.unmodifiableMap(tmpMap);
      org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(deleteResourceJobManager_args.class, metaDataMap);
    }

    public deleteResourceJobManager_args() {
    }

    public deleteResourceJobManager_args(
      org.apache.airavata.model.security.AuthzToken authzToken,
      String resourceJobManagerId)
    {
      this();
      this.authzToken = authzToken;
      this.resourceJobManagerId = resourceJobManagerId;
    }

    /**
     * Performs a deep copy on <i>other</i>.
     */
    public deleteResourceJobManager_args(deleteResourceJobManager_args other) {
      if (other.isSetAuthzToken()) {
        this.authzToken = new org.apache.airavata.model.security.AuthzToken(other.authzToken);
      }
      if (other.isSetResourceJobManagerId()) {
        this.resourceJobManagerId = other.resourceJobManagerId;
      }
    }

    public deleteResourceJobManager_args deepCopy() {
      return new deleteResourceJobManager_args(this);
    }

    @Override
    public void clear() {
      this.authzToken = null;
      this.resourceJobManagerId = null;
    }

    public org.apache.airavata.model.security.AuthzToken getAuthzToken() {
      return this.authzToken;
    }

    public deleteResourceJobManager_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 String getResourceJobManagerId() {
      return this.resourceJobManagerId;
    }

    public deleteResourceJobManager_args setResourceJobManagerId(String resourceJobManagerId) {
      this.resourceJobManagerId = resourceJobManagerId;
      return this;
    }

    public void unsetResourceJobManagerId() {
      this.resourceJobManagerId = null;
    }

    /** Returns true if field resourceJobManagerId is set (has been assigned a value) and false otherwise */
    public boolean isSetResourceJobManagerId() {
      return this.resourceJobManagerId != null;
    }

    public void setResourceJobManagerIdIsSet(boolean value) {
      if (!value) {
        this.resourceJobManagerId = null;
      }
    }

    public void setFieldValue(_Fields field, Object value) {
      switch (field) {
      case AUTHZ_TOKEN:
        if (value == null) {
          unsetAuthzToken();
        } else {
          setAuthzToken((org.apache.airavata.model.security.AuthzToken)value);
        }
        break;

      case RESOURCE_JOB_MANAGER_ID:
        if (value == null) {
          unsetResourceJobManagerId();
        } else {
          setResourceJobManagerId((String)value);
        }
        break;

      }
    }

    public Object getFieldValue(_Fields field) {
      switch (field) {
      case AUTHZ_TOKEN:
        return getAuthzToken();

      case RESOURCE_JOB_MANAGER_ID:
        return getResourceJobManagerId();

      }
      throw new IllegalStateException();
    }

    /** Returns true if field corresponding to fieldID is set (has been assigned a value) and false otherwise */
    public boolean isSet(_Fields field) {
      if (field == null) {
        throw new IllegalArgumentException();
      }

      switch (field) {
      case AUTHZ_TOKEN:
        return isSetAuthzToken();
      case RESOURCE_JOB_MANAGER_ID:
        return isSetResourceJobManagerId();
      }
      throw new IllegalStateException();
    }

    @Override
    public boolean equals(Object that) {
      if (that == null)
        return false;
      if (that instanceof deleteResourceJobManager_args)
        return this.equals((deleteResourceJobManager_args)that);
      return false;
    }

    public boolean equals(deleteResourceJobManager_args that) {
      if (that == null)
        return false;

      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_resourceJobManagerId = true && this.isSetResourceJobManagerId();
      boolean that_present_resourceJobManagerId = true && that.isSetResourceJobManagerId();
      if (this_present_resourceJobManagerId || that_present_resourceJobManagerId) {
        if (!(this_present_resourceJobManagerId && that_present_resourceJobManagerId))
          return false;
        if (!this.resourceJobManagerId.equals(that.resourceJobManagerId))
          return false;
      }

      return true;
    }

    @Override
    public int hashCode() {
      List<Object> list = new ArrayList<Object>();

      boolean present_authzToken = true && (isSetAuthzToken());
      list.add(present_authzToken);
      if (present_authzToken)
        list.add(authzToken);

      boolean present_resourceJobManagerId = true && (isSetResourceJobManagerId());
      list.add(present_resourceJobManagerId);
      if (present_resourceJobManagerId)
        list.add(resourceJobManagerId);

      return list.hashCode();
    }

    @Override
    public int compareTo(deleteResourceJobManager_args other) {
      if (!getClass().equals(other.getClass())) {
        return getClass().getName().compareTo(other.getClass().getName());
      }

      int lastComparison = 0;

      lastComparison = 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 = Boolean.valueOf(isSetResourceJobManagerId()).compareTo(other.isSetResourceJobManagerId());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetResourceJobManagerId()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.resourceJobManagerId, other.resourceJobManagerId);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      return 0;
    }

    public _Fields fieldForId(int fieldId) {
      return _Fields.findByThriftId(fieldId);
    }

    public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
      schemes.get(iprot.getScheme()).getScheme().read(iprot, this);
    }

    public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException {
      schemes.get(oprot.getScheme()).getScheme().write(oprot, this);
    }

    @Override
    public String toString() {
      StringBuilder sb = new StringBuilder("deleteResourceJobManager_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("resourceJobManagerId:");
      if (this.resourceJobManagerId == null) {
        sb.append("null");
      } else {
        sb.append(this.resourceJobManagerId);
      }
      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 (resourceJobManagerId == null) {
        throw new org.apache.thrift.protocol.TProtocolException("Required field 'resourceJobManagerId' 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, 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 deleteResourceJobManager_argsStandardSchemeFactory implements SchemeFactory {
      public deleteResourceJobManager_argsStandardScheme getScheme() {
        return new deleteResourceJobManager_argsStandardScheme();
      }
    }

    private static class deleteResourceJobManager_argsStandardScheme extends StandardScheme<deleteResourceJobManager_args> {

      public void read(org.apache.thrift.protocol.TProtocol iprot, deleteResourceJobManager_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: // RESOURCE_JOB_MANAGER_ID
              if (schemeField.type == org.apache.thrift.protocol.TType.STRING) {
                struct.resourceJobManagerId = iprot.readString();
                struct.setResourceJobManagerIdIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            default:
              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
          }
          iprot.readFieldEnd();
        }
        iprot.readStructEnd();

        // check for required fields of primitive type, which can't be checked in the validate method
        struct.validate();
      }

      public void write(org.apache.thrift.protocol.TProtocol oprot, deleteResourceJobManager_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.resourceJobManagerId != null) {
          oprot.writeFieldBegin(RESOURCE_JOB_MANAGER_ID_FIELD_DESC);
          oprot.writeString(struct.resourceJobManagerId);
          oprot.writeFieldEnd();
        }
        oprot.writeFieldStop();
        oprot.writeStructEnd();
      }

    }

    private static class deleteResourceJobManager_argsTupleSchemeFactory implements SchemeFactory {
      public deleteResourceJobManager_argsTupleScheme getScheme() {
        return new deleteResourceJobManager_argsTupleScheme();
      }
    }

    private static class deleteResourceJobManager_argsTupleScheme extends TupleScheme<deleteResourceJobManager_args> {

      @Override
      public void write(org.apache.thrift.protocol.TProtocol prot, deleteResourceJobManager_args struct) throws org.apache.thrift.TException {
        TTupleProtocol oprot = (TTupleProtocol) prot;
        struct.authzToken.write(oprot);
        oprot.writeString(struct.resourceJobManagerId);
      }

      @Override
      public void read(org.apache.thrift.protocol.TProtocol prot, deleteResourceJobManager_args struct) throws org.apache.thrift.TException {
        TTupleProtocol iprot = (TTupleProtocol) prot;
        struct.authzToken = new org.apache.airavata.model.security.AuthzToken();
        struct.authzToken.read(iprot);
        struct.setAuthzTokenIsSet(true);
        struct.resourceJobManagerId = iprot.readString();
        struct.setResourceJobManagerIdIsSet(true);
      }
    }

  }

  public static class deleteResourceJobManager_result implements org.apache.thrift.TBase<deleteResourceJobManager_result, deleteResourceJobManager_result._Fields>, java.io.Serializable, Cloneable, Comparable<deleteResourceJobManager_result>   {
    private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("deleteResourceJobManager_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 IRE_FIELD_DESC = new org.apache.thrift.protocol.TField("ire", org.apache.thrift.protocol.TType.STRUCT, (short)1);
    private static final org.apache.thrift.protocol.TField ACE_FIELD_DESC = new org.apache.thrift.protocol.TField("ace", org.apache.thrift.protocol.TType.STRUCT, (short)2);
    private static final org.apache.thrift.protocol.TField ASE_FIELD_DESC = new org.apache.thrift.protocol.TField("ase", org.apache.thrift.protocol.TType.STRUCT, (short)3);
    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)4);

    private static final Map<Class<? extends IScheme>, SchemeFactory> schemes = new HashMap<Class<? extends IScheme>, SchemeFactory>();
    static {
      schemes.put(StandardScheme.class, new deleteResourceJobManager_resultStandardSchemeFactory());
      schemes.put(TupleScheme.class, new deleteResourceJobManager_resultTupleSchemeFactory());
    }

    public boolean success; // required
    public org.apache.airavata.model.error.InvalidRequestException ire; // required
    public org.apache.airavata.model.error.AiravataClientException ace; // required
    public org.apache.airavata.model.error.AiravataSystemException ase; // 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"),
      IRE((short)1, "ire"),
      ACE((short)2, "ace"),
      ASE((short)3, "ase"),
      AE((short)4, "ae");

      private static final Map<String, _Fields> byName = new HashMap<String, _Fields>();

      static {
        for (_Fields field : EnumSet.allOf(_Fields.class)) {
          byName.put(field.getFieldName(), field);
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, or null if its not found.
       */
      public static _Fields findByThriftId(int fieldId) {
        switch(fieldId) {
          case 0: // SUCCESS
            return SUCCESS;
          case 1: // IRE
            return IRE;
          case 2: // ACE
            return ACE;
          case 3: // ASE
            return ASE;
          case 4: // 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 IllegalArgumentException("Field " + fieldId + " doesn't exist!");
        return fields;
      }

      /**
       * Find the _Fields constant that matches name, or null if its not found.
       */
      public static _Fields findByName(String name) {
        return byName.get(name);
      }

      private final short _thriftId;
      private final String _fieldName;

      _Fields(short thriftId, String fieldName) {
        _thriftId = thriftId;
        _fieldName = fieldName;
      }

      public short getThriftFieldId() {
        return _thriftId;
      }

      public String getFieldName() {
        return _fieldName;
      }
    }

    // isset id assignments
    private static final int __SUCCESS_ISSET_ID = 0;
    private byte __isset_bitfield = 0;
    public static final Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
    static {
      Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new EnumMap<_Fields, org.apache.thrift.meta_data.FieldMetaData>(_Fields.class);
      tmpMap.put(_Fields.SUCCESS, new org.apache.thrift.meta_data.FieldMetaData("success", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.BOOL)));
      tmpMap.put(_Fields.IRE, new org.apache.thrift.meta_data.FieldMetaData("ire", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRUCT)));
      tmpMap.put(_Fields.ACE, new org.apache.thrift.meta_data.FieldMetaData("ace", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRUCT)));
      tmpMap.put(_Fields.ASE, new org.apache.thrift.meta_data.FieldMetaData("ase", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRUCT)));
      tmpMap.put(_Fields.AE, new org.apache.thrift.meta_data.FieldMetaData("ae", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRUCT)));
      metaDataMap = Collections.unmodifiableMap(tmpMap);
      org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(deleteResourceJobManager_result.class, metaDataMap);
    }

    public deleteResourceJobManager_result() {
    }

    public deleteResourceJobManager_result(
      boolean success,
      org.apache.airavata.model.error.InvalidRequestException ire,
      org.apache.airavata.model.error.AiravataClientException ace,
      org.apache.airavata.model.error.AiravataSystemException ase,
      org.apache.airavata.model.error.AuthorizationException ae)
    {
      this();
      this.success = success;
      setSuccessIsSet(true);
      this.ire = ire;
      this.ace = ace;
      this.ase = ase;
      this.ae = ae;
    }

    /**
     * Performs a deep copy on <i>other</i>.
     */
    public deleteResourceJobManager_result(deleteResourceJobManager_result other) {
      __isset_bitfield = other.__isset_bitfield;
      this.success = other.success;
      if (other.isSetIre()) {
        this.ire = new org.apache.airavata.model.error.InvalidRequestException(other.ire);
      }
      if (other.isSetAce()) {
        this.ace = new org.apache.airavata.model.error.AiravataClientException(other.ace);
      }
      if (other.isSetAse()) {
        this.ase = new org.apache.airavata.model.error.AiravataSystemException(other.ase);
      }
      if (other.isSetAe()) {
        this.ae = new org.apache.airavata.model.error.AuthorizationException(other.ae);
      }
    }

    public deleteResourceJobManager_result deepCopy() {
      return new deleteResourceJobManager_result(this);
    }

    @Override
    public void clear() {
      setSuccessIsSet(false);
      this.success = false;
      this.ire = null;
      this.ace = null;
      this.ase = null;
      this.ae = null;
    }

    public boolean isSuccess() {
      return this.success;
    }

    public deleteResourceJobManager_result setSuccess(boolean success) {
      this.success = success;
      setSuccessIsSet(true);
      return this;
    }

    public void unsetSuccess() {
      __isset_bitfield = EncodingUtils.clearBit(__isset_bitfield, __SUCCESS_ISSET_ID);
    }

    /** Returns true if field success is set (has been assigned a value) and false otherwise */
    public boolean isSetSuccess() {
      return EncodingUtils.testBit(__isset_bitfield, __SUCCESS_ISSET_ID);
    }

    public void setSuccessIsSet(boolean value) {
      __isset_bitfield = EncodingUtils.setBit(__isset_bitfield, __SUCCESS_ISSET_ID, value);
    }

    public org.apache.airavata.model.error.InvalidRequestException getIre() {
      return this.ire;
    }

    public deleteResourceJobManager_result setIre(org.apache.airavata.model.error.InvalidRequestException ire) {
      this.ire = ire;
      return this;
    }

    public void unsetIre() {
      this.ire = null;
    }

    /** Returns true if field ire is set (has been assigned a value) and false otherwise */
    public boolean isSetIre() {
      return this.ire != null;
    }

    public void setIreIsSet(boolean value) {
      if (!value) {
        this.ire = null;
      }
    }

    public org.apache.airavata.model.error.AiravataClientException getAce() {
      return this.ace;
    }

    public deleteResourceJobManager_result setAce(org.apache.airavata.model.error.AiravataClientException ace) {
      this.ace = ace;
      return this;
    }

    public void unsetAce() {
      this.ace = null;
    }

    /** Returns true if field ace is set (has been assigned a value) and false otherwise */
    public boolean isSetAce() {
      return this.ace != null;
    }

    public void setAceIsSet(boolean value) {
      if (!value) {
        this.ace = null;
      }
    }

    public org.apache.airavata.model.error.AiravataSystemException getAse() {
      return this.ase;
    }

    public deleteResourceJobManager_result setAse(org.apache.airavata.model.error.AiravataSystemException ase) {
      this.ase = ase;
      return this;
    }

    public void unsetAse() {
      this.ase = null;
    }

    /** Returns true if field ase is set (has been assigned a value) and false otherwise */
    public boolean isSetAse() {
      return this.ase != null;
    }

    public void setAseIsSet(boolean value) {
      if (!value) {
        this.ase = null;
      }
    }

    public org.apache.airavata.model.error.AuthorizationException getAe() {
      return this.ae;
    }

    public deleteResourceJobManager_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, Object value) {
      switch (field) {
      case SUCCESS:
        if (value == null) {
          unsetSuccess();
        } else {
          setSuccess((Boolean)value);
        }
        break;

      case IRE:
        if (value == null) {
          unsetIre();
        } else {
          setIre((org.apache.airavata.model.error.InvalidRequestException)value);
        }
        break;

      case ACE:
        if (value == null) {
          unsetAce();
        } else {
          setAce((org.apache.airavata.model.error.AiravataClientException)value);
        }
        break;

      case ASE:
        if (value == null) {
          unsetAse();
        } else {
          setAse((org.apache.airavata.model.error.AiravataSystemException)value);
        }
        break;

      case AE:
        if (value == null) {
          unsetAe();
        } else {
          setAe((org.apache.airavata.model.error.AuthorizationException)value);
        }
        break;

      }
    }

    public Object getFieldValue(_Fields field) {
      switch (field) {
      case SUCCESS:
        return Boolean.valueOf(isSuccess());

      case IRE:
        return getIre();

      case ACE:
        return getAce();

      case ASE:
        return getAse();

      case AE:
        return getAe();

      }
      throw new IllegalStateException();
    }

    /** Returns true if field corresponding to fieldID is set (has been assigned a value) and false otherwise */
    public boolean isSet(_Fields field) {
      if (field == null) {
        throw new IllegalArgumentException();
      }

      switch (field) {
      case SUCCESS:
        return isSetSuccess();
      case IRE:
        return isSetIre();
      case ACE:
        return isSetAce();
      case ASE:
        return isSetAse();
      case AE:
        return isSetAe();
      }
      throw new IllegalStateException();
    }

    @Override
    public boolean equals(Object that) {
      if (that == null)
        return false;
      if (that instanceof deleteResourceJobManager_result)
        return this.equals((deleteResourceJobManager_result)that);
      return false;
    }

    public boolean equals(deleteResourceJobManager_result that) {
      if (that == null)
        return false;

      boolean this_present_success = true;
      boolean that_present_success = true;
      if (this_present_success || that_present_success) {
        if (!(this_present_success && that_present_success))
          return false;
        if (this.success != that.success)
          return false;
      }

      boolean this_present_ire = true && this.isSetIre();
      boolean that_present_ire = true && that.isSetIre();
      if (this_present_ire || that_present_ire) {
        if (!(this_present_ire && that_present_ire))
          return false;
        if (!this.ire.equals(that.ire))
          return false;
      }

      boolean this_present_ace = true && this.isSetAce();
      boolean that_present_ace = true && that.isSetAce();
      if (this_present_ace || that_present_ace) {
        if (!(this_present_ace && that_present_ace))
          return false;
        if (!this.ace.equals(that.ace))
          return false;
      }

      boolean this_present_ase = true && this.isSetAse();
      boolean that_present_ase = true && that.isSetAse();
      if (this_present_ase || that_present_ase) {
        if (!(this_present_ase && that_present_ase))
          return false;
        if (!this.ase.equals(that.ase))
          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() {
      List<Object> list = new ArrayList<Object>();

      boolean present_success = true;
      list.add(present_success);
      if (present_success)
        list.add(success);

      boolean present_ire = true && (isSetIre());
      list.add(present_ire);
      if (present_ire)
        list.add(ire);

      boolean present_ace = true && (isSetAce());
      list.add(present_ace);
      if (present_ace)
        list.add(ace);

      boolean present_ase = true && (isSetAse());
      list.add(present_ase);
      if (present_ase)
        list.add(ase);

      boolean present_ae = true && (isSetAe());
      list.add(present_ae);
      if (present_ae)
        list.add(ae);

      return list.hashCode();
    }

    @Override
    public int compareTo(deleteResourceJobManager_result other) {
      if (!getClass().equals(other.getClass())) {
        return getClass().getName().compareTo(other.getClass().getName());
      }

      int lastComparison = 0;

      lastComparison = Boolean.valueOf(isSetSuccess()).compareTo(other.isSetSuccess());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetSuccess()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.success, other.success);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = Boolean.valueOf(isSetIre()).compareTo(other.isSetIre());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetIre()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.ire, other.ire);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = Boolean.valueOf(isSetAce()).compareTo(other.isSetAce());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetAce()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.ace, other.ace);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = Boolean.valueOf(isSetAse()).compareTo(other.isSetAse());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetAse()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.ase, other.ase);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = 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 {
      schemes.get(iprot.getScheme()).getScheme().read(iprot, this);
    }

    public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException {
      schemes.get(oprot.getScheme()).getScheme().write(oprot, this);
      }

    @Override
    public String toString() {
      StringBuilder sb = new StringBuilder("deleteResourceJobManager_result(");
      boolean first = true;

      sb.append("success:");
      sb.append(this.success);
      first = false;
      if (!first) sb.append(", ");
      sb.append("ire:");
      if (this.ire == null) {
        sb.append("null");
      } else {
        sb.append(this.ire);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("ace:");
      if (this.ace == null) {
        sb.append("null");
      } else {
        sb.append(this.ace);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("ase:");
      if (this.ase == null) {
        sb.append("null");
      } else {
        sb.append(this.ase);
      }
      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, 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 deleteResourceJobManager_resultStandardSchemeFactory implements SchemeFactory {
      public deleteResourceJobManager_resultStandardScheme getScheme() {
        return new deleteResourceJobManager_resultStandardScheme();
      }
    }

    private static class deleteResourceJobManager_resultStandardScheme extends StandardScheme<deleteResourceJobManager_result> {

      public void read(org.apache.thrift.protocol.TProtocol iprot, deleteResourceJobManager_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: // IRE
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.ire = new org.apache.airavata.model.error.InvalidRequestException();
                struct.ire.read(iprot);
                struct.setIreIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 2: // ACE
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.ace = new org.apache.airavata.model.error.AiravataClientException();
                struct.ace.read(iprot);
                struct.setAceIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 3: // ASE
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.ase = new org.apache.airavata.model.error.AiravataSystemException();
                struct.ase.read(iprot);
                struct.setAseIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 4: // 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, deleteResourceJobManager_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.ire != null) {
          oprot.writeFieldBegin(IRE_FIELD_DESC);
          struct.ire.write(oprot);
          oprot.writeFieldEnd();
        }
        if (struct.ace != null) {
          oprot.writeFieldBegin(ACE_FIELD_DESC);
          struct.ace.write(oprot);
          oprot.writeFieldEnd();
        }
        if (struct.ase != null) {
          oprot.writeFieldBegin(ASE_FIELD_DESC);
          struct.ase.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 deleteResourceJobManager_resultTupleSchemeFactory implements SchemeFactory {
      public deleteResourceJobManager_resultTupleScheme getScheme() {
        return new deleteResourceJobManager_resultTupleScheme();
      }
    }

    private static class deleteResourceJobManager_resultTupleScheme extends TupleScheme<deleteResourceJobManager_result> {

      @Override
      public void write(org.apache.thrift.protocol.TProtocol prot, deleteResourceJobManager_result struct) throws org.apache.thrift.TException {
        TTupleProtocol oprot = (TTupleProtocol) prot;
        BitSet optionals = new BitSet();
        if (struct.isSetSuccess()) {
          optionals.set(0);
        }
        if (struct.isSetIre()) {
          optionals.set(1);
        }
        if (struct.isSetAce()) {
          optionals.set(2);
        }
        if (struct.isSetAse()) {
          optionals.set(3);
        }
        if (struct.isSetAe()) {
          optionals.set(4);
        }
        oprot.writeBitSet(optionals, 5);
        if (struct.isSetSuccess()) {
          oprot.writeBool(struct.success);
        }
        if (struct.isSetIre()) {
          struct.ire.write(oprot);
        }
        if (struct.isSetAce()) {
          struct.ace.write(oprot);
        }
        if (struct.isSetAse()) {
          struct.ase.write(oprot);
        }
        if (struct.isSetAe()) {
          struct.ae.write(oprot);
        }
      }

      @Override
      public void read(org.apache.thrift.protocol.TProtocol prot, deleteResourceJobManager_result struct) throws org.apache.thrift.TException {
        TTupleProtocol iprot = (TTupleProtocol) prot;
        BitSet incoming = iprot.readBitSet(5);
        if (incoming.get(0)) {
          struct.success = iprot.readBool();
          struct.setSuccessIsSet(true);
        }
        if (incoming.get(1)) {
          struct.ire = new org.apache.airavata.model.error.InvalidRequestException();
          struct.ire.read(iprot);
          struct.setIreIsSet(true);
        }
        if (incoming.get(2)) {
          struct.ace = new org.apache.airavata.model.error.AiravataClientException();
          struct.ace.read(iprot);
          struct.setAceIsSet(true);
        }
        if (incoming.get(3)) {
          struct.ase = new org.apache.airavata.model.error.AiravataSystemException();
          struct.ase.read(iprot);
          struct.setAseIsSet(true);
        }
        if (incoming.get(4)) {
          struct.ae = new org.apache.airavata.model.error.AuthorizationException();
          struct.ae.read(iprot);
          struct.setAeIsSet(true);
        }
      }
    }

  }

  public static class deleteBatchQueue_args implements org.apache.thrift.TBase<deleteBatchQueue_args, deleteBatchQueue_args._Fields>, java.io.Serializable, Cloneable, Comparable<deleteBatchQueue_args>   {
    private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("deleteBatchQueue_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 COMPUTE_RESOURCE_ID_FIELD_DESC = new org.apache.thrift.protocol.TField("computeResourceId", org.apache.thrift.protocol.TType.STRING, (short)2);
    private static final org.apache.thrift.protocol.TField QUEUE_NAME_FIELD_DESC = new org.apache.thrift.protocol.TField("queueName", org.apache.thrift.protocol.TType.STRING, (short)3);

    private static final Map<Class<? extends IScheme>, SchemeFactory> schemes = new HashMap<Class<? extends IScheme>, SchemeFactory>();
    static {
      schemes.put(StandardScheme.class, new deleteBatchQueue_argsStandardSchemeFactory());
      schemes.put(TupleScheme.class, new deleteBatchQueue_argsTupleSchemeFactory());
    }

    public org.apache.airavata.model.security.AuthzToken authzToken; // required
    public String computeResourceId; // required
    public String queueName; // required

    /** 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"),
      COMPUTE_RESOURCE_ID((short)2, "computeResourceId"),
      QUEUE_NAME((short)3, "queueName");

      private static final Map<String, _Fields> byName = new HashMap<String, _Fields>();

      static {
        for (_Fields field : EnumSet.allOf(_Fields.class)) {
          byName.put(field.getFieldName(), field);
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, or null if its not found.
       */
      public static _Fields findByThriftId(int fieldId) {
        switch(fieldId) {
          case 1: // AUTHZ_TOKEN
            return AUTHZ_TOKEN;
          case 2: // COMPUTE_RESOURCE_ID
            return COMPUTE_RESOURCE_ID;
          case 3: // QUEUE_NAME
            return QUEUE_NAME;
          default:
            return null;
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, throwing an exception
       * if it is not found.
       */
      public static _Fields findByThriftIdOrThrow(int fieldId) {
        _Fields fields = findByThriftId(fieldId);
        if (fields == null) throw new IllegalArgumentException("Field " + fieldId + " doesn't exist!");
        return fields;
      }

      /**
       * Find the _Fields constant that matches name, or null if its not found.
       */
      public static _Fields findByName(String name) {
        return byName.get(name);
      }

      private final short _thriftId;
      private final String _fieldName;

      _Fields(short thriftId, String fieldName) {
        _thriftId = thriftId;
        _fieldName = fieldName;
      }

      public short getThriftFieldId() {
        return _thriftId;
      }

      public String getFieldName() {
        return _fieldName;
      }
    }

    // isset id assignments
    public static final Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
    static {
      Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new EnumMap<_Fields, org.apache.thrift.meta_data.FieldMetaData>(_Fields.class);
      tmpMap.put(_Fields.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.COMPUTE_RESOURCE_ID, new org.apache.thrift.meta_data.FieldMetaData("computeResourceId", org.apache.thrift.TFieldRequirementType.REQUIRED, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING)));
      tmpMap.put(_Fields.QUEUE_NAME, new org.apache.thrift.meta_data.FieldMetaData("queueName", org.apache.thrift.TFieldRequirementType.REQUIRED, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING)));
      metaDataMap = Collections.unmodifiableMap(tmpMap);
      org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(deleteBatchQueue_args.class, metaDataMap);
    }

    public deleteBatchQueue_args() {
    }

    public deleteBatchQueue_args(
      org.apache.airavata.model.security.AuthzToken authzToken,
      String computeResourceId,
      String queueName)
    {
      this();
      this.authzToken = authzToken;
      this.computeResourceId = computeResourceId;
      this.queueName = queueName;
    }

    /**
     * Performs a deep copy on <i>other</i>.
     */
    public deleteBatchQueue_args(deleteBatchQueue_args other) {
      if (other.isSetAuthzToken()) {
        this.authzToken = new org.apache.airavata.model.security.AuthzToken(other.authzToken);
      }
      if (other.isSetComputeResourceId()) {
        this.computeResourceId = other.computeResourceId;
      }
      if (other.isSetQueueName()) {
        this.queueName = other.queueName;
      }
    }

    public deleteBatchQueue_args deepCopy() {
      return new deleteBatchQueue_args(this);
    }

    @Override
    public void clear() {
      this.authzToken = null;
      this.computeResourceId = null;
      this.queueName = null;
    }

    public org.apache.airavata.model.security.AuthzToken getAuthzToken() {
      return this.authzToken;
    }

    public deleteBatchQueue_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 String getComputeResourceId() {
      return this.computeResourceId;
    }

    public deleteBatchQueue_args setComputeResourceId(String computeResourceId) {
      this.computeResourceId = computeResourceId;
      return this;
    }

    public void unsetComputeResourceId() {
      this.computeResourceId = null;
    }

    /** Returns true if field computeResourceId is set (has been assigned a value) and false otherwise */
    public boolean isSetComputeResourceId() {
      return this.computeResourceId != null;
    }

    public void setComputeResourceIdIsSet(boolean value) {
      if (!value) {
        this.computeResourceId = null;
      }
    }

    public String getQueueName() {
      return this.queueName;
    }

    public deleteBatchQueue_args setQueueName(String queueName) {
      this.queueName = queueName;
      return this;
    }

    public void unsetQueueName() {
      this.queueName = null;
    }

    /** Returns true if field queueName is set (has been assigned a value) and false otherwise */
    public boolean isSetQueueName() {
      return this.queueName != null;
    }

    public void setQueueNameIsSet(boolean value) {
      if (!value) {
        this.queueName = null;
      }
    }

    public void setFieldValue(_Fields field, Object value) {
      switch (field) {
      case AUTHZ_TOKEN:
        if (value == null) {
          unsetAuthzToken();
        } else {
          setAuthzToken((org.apache.airavata.model.security.AuthzToken)value);
        }
        break;

      case COMPUTE_RESOURCE_ID:
        if (value == null) {
          unsetComputeResourceId();
        } else {
          setComputeResourceId((String)value);
        }
        break;

      case QUEUE_NAME:
        if (value == null) {
          unsetQueueName();
        } else {
          setQueueName((String)value);
        }
        break;

      }
    }

    public Object getFieldValue(_Fields field) {
      switch (field) {
      case AUTHZ_TOKEN:
        return getAuthzToken();

      case COMPUTE_RESOURCE_ID:
        return getComputeResourceId();

      case QUEUE_NAME:
        return getQueueName();

      }
      throw new IllegalStateException();
    }

    /** Returns true if field corresponding to fieldID is set (has been assigned a value) and false otherwise */
    public boolean isSet(_Fields field) {
      if (field == null) {
        throw new IllegalArgumentException();
      }

      switch (field) {
      case AUTHZ_TOKEN:
        return isSetAuthzToken();
      case COMPUTE_RESOURCE_ID:
        return isSetComputeResourceId();
      case QUEUE_NAME:
        return isSetQueueName();
      }
      throw new IllegalStateException();
    }

    @Override
    public boolean equals(Object that) {
      if (that == null)
        return false;
      if (that instanceof deleteBatchQueue_args)
        return this.equals((deleteBatchQueue_args)that);
      return false;
    }

    public boolean equals(deleteBatchQueue_args that) {
      if (that == null)
        return false;

      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_computeResourceId = true && this.isSetComputeResourceId();
      boolean that_present_computeResourceId = true && that.isSetComputeResourceId();
      if (this_present_computeResourceId || that_present_computeResourceId) {
        if (!(this_present_computeResourceId && that_present_computeResourceId))
          return false;
        if (!this.computeResourceId.equals(that.computeResourceId))
          return false;
      }

      boolean this_present_queueName = true && this.isSetQueueName();
      boolean that_present_queueName = true && that.isSetQueueName();
      if (this_present_queueName || that_present_queueName) {
        if (!(this_present_queueName && that_present_queueName))
          return false;
        if (!this.queueName.equals(that.queueName))
          return false;
      }

      return true;
    }

    @Override
    public int hashCode() {
      List<Object> list = new ArrayList<Object>();

      boolean present_authzToken = true && (isSetAuthzToken());
      list.add(present_authzToken);
      if (present_authzToken)
        list.add(authzToken);

      boolean present_computeResourceId = true && (isSetComputeResourceId());
      list.add(present_computeResourceId);
      if (present_computeResourceId)
        list.add(computeResourceId);

      boolean present_queueName = true && (isSetQueueName());
      list.add(present_queueName);
      if (present_queueName)
        list.add(queueName);

      return list.hashCode();
    }

    @Override
    public int compareTo(deleteBatchQueue_args other) {
      if (!getClass().equals(other.getClass())) {
        return getClass().getName().compareTo(other.getClass().getName());
      }

      int lastComparison = 0;

      lastComparison = 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 = Boolean.valueOf(isSetComputeResourceId()).compareTo(other.isSetComputeResourceId());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetComputeResourceId()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.computeResourceId, other.computeResourceId);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = Boolean.valueOf(isSetQueueName()).compareTo(other.isSetQueueName());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetQueueName()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.queueName, other.queueName);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      return 0;
    }

    public _Fields fieldForId(int fieldId) {
      return _Fields.findByThriftId(fieldId);
    }

    public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
      schemes.get(iprot.getScheme()).getScheme().read(iprot, this);
    }

    public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException {
      schemes.get(oprot.getScheme()).getScheme().write(oprot, this);
    }

    @Override
    public String toString() {
      StringBuilder sb = new StringBuilder("deleteBatchQueue_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("computeResourceId:");
      if (this.computeResourceId == null) {
        sb.append("null");
      } else {
        sb.append(this.computeResourceId);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("queueName:");
      if (this.queueName == null) {
        sb.append("null");
      } else {
        sb.append(this.queueName);
      }
      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 (computeResourceId == null) {
        throw new org.apache.thrift.protocol.TProtocolException("Required field 'computeResourceId' was not present! Struct: " + toString());
      }
      if (queueName == null) {
        throw new org.apache.thrift.protocol.TProtocolException("Required field 'queueName' 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, 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 deleteBatchQueue_argsStandardSchemeFactory implements SchemeFactory {
      public deleteBatchQueue_argsStandardScheme getScheme() {
        return new deleteBatchQueue_argsStandardScheme();
      }
    }

    private static class deleteBatchQueue_argsStandardScheme extends StandardScheme<deleteBatchQueue_args> {

      public void read(org.apache.thrift.protocol.TProtocol iprot, deleteBatchQueue_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: // COMPUTE_RESOURCE_ID
              if (schemeField.type == org.apache.thrift.protocol.TType.STRING) {
                struct.computeResourceId = iprot.readString();
                struct.setComputeResourceIdIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 3: // QUEUE_NAME
              if (schemeField.type == org.apache.thrift.protocol.TType.STRING) {
                struct.queueName = iprot.readString();
                struct.setQueueNameIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            default:
              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
          }
          iprot.readFieldEnd();
        }
        iprot.readStructEnd();

        // check for required fields of primitive type, which can't be checked in the validate method
        struct.validate();
      }

      public void write(org.apache.thrift.protocol.TProtocol oprot, deleteBatchQueue_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.computeResourceId != null) {
          oprot.writeFieldBegin(COMPUTE_RESOURCE_ID_FIELD_DESC);
          oprot.writeString(struct.computeResourceId);
          oprot.writeFieldEnd();
        }
        if (struct.queueName != null) {
          oprot.writeFieldBegin(QUEUE_NAME_FIELD_DESC);
          oprot.writeString(struct.queueName);
          oprot.writeFieldEnd();
        }
        oprot.writeFieldStop();
        oprot.writeStructEnd();
      }

    }

    private static class deleteBatchQueue_argsTupleSchemeFactory implements SchemeFactory {
      public deleteBatchQueue_argsTupleScheme getScheme() {
        return new deleteBatchQueue_argsTupleScheme();
      }
    }

    private static class deleteBatchQueue_argsTupleScheme extends TupleScheme<deleteBatchQueue_args> {

      @Override
      public void write(org.apache.thrift.protocol.TProtocol prot, deleteBatchQueue_args struct) throws org.apache.thrift.TException {
        TTupleProtocol oprot = (TTupleProtocol) prot;
        struct.authzToken.write(oprot);
        oprot.writeString(struct.computeResourceId);
        oprot.writeString(struct.queueName);
      }

      @Override
      public void read(org.apache.thrift.protocol.TProtocol prot, deleteBatchQueue_args struct) throws org.apache.thrift.TException {
        TTupleProtocol iprot = (TTupleProtocol) prot;
        struct.authzToken = new org.apache.airavata.model.security.AuthzToken();
        struct.authzToken.read(iprot);
        struct.setAuthzTokenIsSet(true);
        struct.computeResourceId = iprot.readString();
        struct.setComputeResourceIdIsSet(true);
        struct.queueName = iprot.readString();
        struct.setQueueNameIsSet(true);
      }
    }

  }

  public static class deleteBatchQueue_result implements org.apache.thrift.TBase<deleteBatchQueue_result, deleteBatchQueue_result._Fields>, java.io.Serializable, Cloneable, Comparable<deleteBatchQueue_result>   {
    private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("deleteBatchQueue_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 IRE_FIELD_DESC = new org.apache.thrift.protocol.TField("ire", org.apache.thrift.protocol.TType.STRUCT, (short)1);
    private static final org.apache.thrift.protocol.TField ACE_FIELD_DESC = new org.apache.thrift.protocol.TField("ace", org.apache.thrift.protocol.TType.STRUCT, (short)2);
    private static final org.apache.thrift.protocol.TField ASE_FIELD_DESC = new org.apache.thrift.protocol.TField("ase", org.apache.thrift.protocol.TType.STRUCT, (short)3);
    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)4);

    private static final Map<Class<? extends IScheme>, SchemeFactory> schemes = new HashMap<Class<? extends IScheme>, SchemeFactory>();
    static {
      schemes.put(StandardScheme.class, new deleteBatchQueue_resultStandardSchemeFactory());
      schemes.put(TupleScheme.class, new deleteBatchQueue_resultTupleSchemeFactory());
    }

    public boolean success; // required
    public org.apache.airavata.model.error.InvalidRequestException ire; // required
    public org.apache.airavata.model.error.AiravataClientException ace; // required
    public org.apache.airavata.model.error.AiravataSystemException ase; // 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"),
      IRE((short)1, "ire"),
      ACE((short)2, "ace"),
      ASE((short)3, "ase"),
      AE((short)4, "ae");

      private static final Map<String, _Fields> byName = new HashMap<String, _Fields>();

      static {
        for (_Fields field : EnumSet.allOf(_Fields.class)) {
          byName.put(field.getFieldName(), field);
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, or null if its not found.
       */
      public static _Fields findByThriftId(int fieldId) {
        switch(fieldId) {
          case 0: // SUCCESS
            return SUCCESS;
          case 1: // IRE
            return IRE;
          case 2: // ACE
            return ACE;
          case 3: // ASE
            return ASE;
          case 4: // 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 IllegalArgumentException("Field " + fieldId + " doesn't exist!");
        return fields;
      }

      /**
       * Find the _Fields constant that matches name, or null if its not found.
       */
      public static _Fields findByName(String name) {
        return byName.get(name);
      }

      private final short _thriftId;
      private final String _fieldName;

      _Fields(short thriftId, String fieldName) {
        _thriftId = thriftId;
        _fieldName = fieldName;
      }

      public short getThriftFieldId() {
        return _thriftId;
      }

      public String getFieldName() {
        return _fieldName;
      }
    }

    // isset id assignments
    private static final int __SUCCESS_ISSET_ID = 0;
    private byte __isset_bitfield = 0;
    public static final Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
    static {
      Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new EnumMap<_Fields, org.apache.thrift.meta_data.FieldMetaData>(_Fields.class);
      tmpMap.put(_Fields.SUCCESS, new org.apache.thrift.meta_data.FieldMetaData("success", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.BOOL)));
      tmpMap.put(_Fields.IRE, new org.apache.thrift.meta_data.FieldMetaData("ire", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRUCT)));
      tmpMap.put(_Fields.ACE, new org.apache.thrift.meta_data.FieldMetaData("ace", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRUCT)));
      tmpMap.put(_Fields.ASE, new org.apache.thrift.meta_data.FieldMetaData("ase", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRUCT)));
      tmpMap.put(_Fields.AE, new org.apache.thrift.meta_data.FieldMetaData("ae", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRUCT)));
      metaDataMap = Collections.unmodifiableMap(tmpMap);
      org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(deleteBatchQueue_result.class, metaDataMap);
    }

    public deleteBatchQueue_result() {
    }

    public deleteBatchQueue_result(
      boolean success,
      org.apache.airavata.model.error.InvalidRequestException ire,
      org.apache.airavata.model.error.AiravataClientException ace,
      org.apache.airavata.model.error.AiravataSystemException ase,
      org.apache.airavata.model.error.AuthorizationException ae)
    {
      this();
      this.success = success;
      setSuccessIsSet(true);
      this.ire = ire;
      this.ace = ace;
      this.ase = ase;
      this.ae = ae;
    }

    /**
     * Performs a deep copy on <i>other</i>.
     */
    public deleteBatchQueue_result(deleteBatchQueue_result other) {
      __isset_bitfield = other.__isset_bitfield;
      this.success = other.success;
      if (other.isSetIre()) {
        this.ire = new org.apache.airavata.model.error.InvalidRequestException(other.ire);
      }
      if (other.isSetAce()) {
        this.ace = new org.apache.airavata.model.error.AiravataClientException(other.ace);
      }
      if (other.isSetAse()) {
        this.ase = new org.apache.airavata.model.error.AiravataSystemException(other.ase);
      }
      if (other.isSetAe()) {
        this.ae = new org.apache.airavata.model.error.AuthorizationException(other.ae);
      }
    }

    public deleteBatchQueue_result deepCopy() {
      return new deleteBatchQueue_result(this);
    }

    @Override
    public void clear() {
      setSuccessIsSet(false);
      this.success = false;
      this.ire = null;
      this.ace = null;
      this.ase = null;
      this.ae = null;
    }

    public boolean isSuccess() {
      return this.success;
    }

    public deleteBatchQueue_result setSuccess(boolean success) {
      this.success = success;
      setSuccessIsSet(true);
      return this;
    }

    public void unsetSuccess() {
      __isset_bitfield = EncodingUtils.clearBit(__isset_bitfield, __SUCCESS_ISSET_ID);
    }

    /** Returns true if field success is set (has been assigned a value) and false otherwise */
    public boolean isSetSuccess() {
      return EncodingUtils.testBit(__isset_bitfield, __SUCCESS_ISSET_ID);
    }

    public void setSuccessIsSet(boolean value) {
      __isset_bitfield = EncodingUtils.setBit(__isset_bitfield, __SUCCESS_ISSET_ID, value);
    }

    public org.apache.airavata.model.error.InvalidRequestException getIre() {
      return this.ire;
    }

    public deleteBatchQueue_result setIre(org.apache.airavata.model.error.InvalidRequestException ire) {
      this.ire = ire;
      return this;
    }

    public void unsetIre() {
      this.ire = null;
    }

    /** Returns true if field ire is set (has been assigned a value) and false otherwise */
    public boolean isSetIre() {
      return this.ire != null;
    }

    public void setIreIsSet(boolean value) {
      if (!value) {
        this.ire = null;
      }
    }

    public org.apache.airavata.model.error.AiravataClientException getAce() {
      return this.ace;
    }

    public deleteBatchQueue_result setAce(org.apache.airavata.model.error.AiravataClientException ace) {
      this.ace = ace;
      return this;
    }

    public void unsetAce() {
      this.ace = null;
    }

    /** Returns true if field ace is set (has been assigned a value) and false otherwise */
    public boolean isSetAce() {
      return this.ace != null;
    }

    public void setAceIsSet(boolean value) {
      if (!value) {
        this.ace = null;
      }
    }

    public org.apache.airavata.model.error.AiravataSystemException getAse() {
      return this.ase;
    }

    public deleteBatchQueue_result setAse(org.apache.airavata.model.error.AiravataSystemException ase) {
      this.ase = ase;
      return this;
    }

    public void unsetAse() {
      this.ase = null;
    }

    /** Returns true if field ase is set (has been assigned a value) and false otherwise */
    public boolean isSetAse() {
      return this.ase != null;
    }

    public void setAseIsSet(boolean value) {
      if (!value) {
        this.ase = null;
      }
    }

    public org.apache.airavata.model.error.AuthorizationException getAe() {
      return this.ae;
    }

    public deleteBatchQueue_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, Object value) {
      switch (field) {
      case SUCCESS:
        if (value == null) {
          unsetSuccess();
        } else {
          setSuccess((Boolean)value);
        }
        break;

      case IRE:
        if (value == null) {
          unsetIre();
        } else {
          setIre((org.apache.airavata.model.error.InvalidRequestException)value);
        }
        break;

      case ACE:
        if (value == null) {
          unsetAce();
        } else {
          setAce((org.apache.airavata.model.error.AiravataClientException)value);
        }
        break;

      case ASE:
        if (value == null) {
          unsetAse();
        } else {
          setAse((org.apache.airavata.model.error.AiravataSystemException)value);
        }
        break;

      case AE:
        if (value == null) {
          unsetAe();
        } else {
          setAe((org.apache.airavata.model.error.AuthorizationException)value);
        }
        break;

      }
    }

    public Object getFieldValue(_Fields field) {
      switch (field) {
      case SUCCESS:
        return Boolean.valueOf(isSuccess());

      case IRE:
        return getIre();

      case ACE:
        return getAce();

      case ASE:
        return getAse();

      case AE:
        return getAe();

      }
      throw new IllegalStateException();
    }

    /** Returns true if field corresponding to fieldID is set (has been assigned a value) and false otherwise */
    public boolean isSet(_Fields field) {
      if (field == null) {
        throw new IllegalArgumentException();
      }

      switch (field) {
      case SUCCESS:
        return isSetSuccess();
      case IRE:
        return isSetIre();
      case ACE:
        return isSetAce();
      case ASE:
        return isSetAse();
      case AE:
        return isSetAe();
      }
      throw new IllegalStateException();
    }

    @Override
    public boolean equals(Object that) {
      if (that == null)
        return false;
      if (that instanceof deleteBatchQueue_result)
        return this.equals((deleteBatchQueue_result)that);
      return false;
    }

    public boolean equals(deleteBatchQueue_result that) {
      if (that == null)
        return false;

      boolean this_present_success = true;
      boolean that_present_success = true;
      if (this_present_success || that_present_success) {
        if (!(this_present_success && that_present_success))
          return false;
        if (this.success != that.success)
          return false;
      }

      boolean this_present_ire = true && this.isSetIre();
      boolean that_present_ire = true && that.isSetIre();
      if (this_present_ire || that_present_ire) {
        if (!(this_present_ire && that_present_ire))
          return false;
        if (!this.ire.equals(that.ire))
          return false;
      }

      boolean this_present_ace = true && this.isSetAce();
      boolean that_present_ace = true && that.isSetAce();
      if (this_present_ace || that_present_ace) {
        if (!(this_present_ace && that_present_ace))
          return false;
        if (!this.ace.equals(that.ace))
          return false;
      }

      boolean this_present_ase = true && this.isSetAse();
      boolean that_present_ase = true && that.isSetAse();
      if (this_present_ase || that_present_ase) {
        if (!(this_present_ase && that_present_ase))
          return false;
        if (!this.ase.equals(that.ase))
          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() {
      List<Object> list = new ArrayList<Object>();

      boolean present_success = true;
      list.add(present_success);
      if (present_success)
        list.add(success);

      boolean present_ire = true && (isSetIre());
      list.add(present_ire);
      if (present_ire)
        list.add(ire);

      boolean present_ace = true && (isSetAce());
      list.add(present_ace);
      if (present_ace)
        list.add(ace);

      boolean present_ase = true && (isSetAse());
      list.add(present_ase);
      if (present_ase)
        list.add(ase);

      boolean present_ae = true && (isSetAe());
      list.add(present_ae);
      if (present_ae)
        list.add(ae);

      return list.hashCode();
    }

    @Override
    public int compareTo(deleteBatchQueue_result other) {
      if (!getClass().equals(other.getClass())) {
        return getClass().getName().compareTo(other.getClass().getName());
      }

      int lastComparison = 0;

      lastComparison = Boolean.valueOf(isSetSuccess()).compareTo(other.isSetSuccess());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetSuccess()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.success, other.success);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = Boolean.valueOf(isSetIre()).compareTo(other.isSetIre());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetIre()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.ire, other.ire);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = Boolean.valueOf(isSetAce()).compareTo(other.isSetAce());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetAce()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.ace, other.ace);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = Boolean.valueOf(isSetAse()).compareTo(other.isSetAse());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetAse()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.ase, other.ase);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = 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 {
      schemes.get(iprot.getScheme()).getScheme().read(iprot, this);
    }

    public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException {
      schemes.get(oprot.getScheme()).getScheme().write(oprot, this);
      }

    @Override
    public String toString() {
      StringBuilder sb = new StringBuilder("deleteBatchQueue_result(");
      boolean first = true;

      sb.append("success:");
      sb.append(this.success);
      first = false;
      if (!first) sb.append(", ");
      sb.append("ire:");
      if (this.ire == null) {
        sb.append("null");
      } else {
        sb.append(this.ire);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("ace:");
      if (this.ace == null) {
        sb.append("null");
      } else {
        sb.append(this.ace);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("ase:");
      if (this.ase == null) {
        sb.append("null");
      } else {
        sb.append(this.ase);
      }
      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, 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 deleteBatchQueue_resultStandardSchemeFactory implements SchemeFactory {
      public deleteBatchQueue_resultStandardScheme getScheme() {
        return new deleteBatchQueue_resultStandardScheme();
      }
    }

    private static class deleteBatchQueue_resultStandardScheme extends StandardScheme<deleteBatchQueue_result> {

      public void read(org.apache.thrift.protocol.TProtocol iprot, deleteBatchQueue_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: // IRE
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.ire = new org.apache.airavata.model.error.InvalidRequestException();
                struct.ire.read(iprot);
                struct.setIreIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 2: // ACE
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.ace = new org.apache.airavata.model.error.AiravataClientException();
                struct.ace.read(iprot);
                struct.setAceIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 3: // ASE
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.ase = new org.apache.airavata.model.error.AiravataSystemException();
                struct.ase.read(iprot);
                struct.setAseIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 4: // 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, deleteBatchQueue_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.ire != null) {
          oprot.writeFieldBegin(IRE_FIELD_DESC);
          struct.ire.write(oprot);
          oprot.writeFieldEnd();
        }
        if (struct.ace != null) {
          oprot.writeFieldBegin(ACE_FIELD_DESC);
          struct.ace.write(oprot);
          oprot.writeFieldEnd();
        }
        if (struct.ase != null) {
          oprot.writeFieldBegin(ASE_FIELD_DESC);
          struct.ase.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 deleteBatchQueue_resultTupleSchemeFactory implements SchemeFactory {
      public deleteBatchQueue_resultTupleScheme getScheme() {
        return new deleteBatchQueue_resultTupleScheme();
      }
    }

    private static class deleteBatchQueue_resultTupleScheme extends TupleScheme<deleteBatchQueue_result> {

      @Override
      public void write(org.apache.thrift.protocol.TProtocol prot, deleteBatchQueue_result struct) throws org.apache.thrift.TException {
        TTupleProtocol oprot = (TTupleProtocol) prot;
        BitSet optionals = new BitSet();
        if (struct.isSetSuccess()) {
          optionals.set(0);
        }
        if (struct.isSetIre()) {
          optionals.set(1);
        }
        if (struct.isSetAce()) {
          optionals.set(2);
        }
        if (struct.isSetAse()) {
          optionals.set(3);
        }
        if (struct.isSetAe()) {
          optionals.set(4);
        }
        oprot.writeBitSet(optionals, 5);
        if (struct.isSetSuccess()) {
          oprot.writeBool(struct.success);
        }
        if (struct.isSetIre()) {
          struct.ire.write(oprot);
        }
        if (struct.isSetAce()) {
          struct.ace.write(oprot);
        }
        if (struct.isSetAse()) {
          struct.ase.write(oprot);
        }
        if (struct.isSetAe()) {
          struct.ae.write(oprot);
        }
      }

      @Override
      public void read(org.apache.thrift.protocol.TProtocol prot, deleteBatchQueue_result struct) throws org.apache.thrift.TException {
        TTupleProtocol iprot = (TTupleProtocol) prot;
        BitSet incoming = iprot.readBitSet(5);
        if (incoming.get(0)) {
          struct.success = iprot.readBool();
          struct.setSuccessIsSet(true);
        }
        if (incoming.get(1)) {
          struct.ire = new org.apache.airavata.model.error.InvalidRequestException();
          struct.ire.read(iprot);
          struct.setIreIsSet(true);
        }
        if (incoming.get(2)) {
          struct.ace = new org.apache.airavata.model.error.AiravataClientException();
          struct.ace.read(iprot);
          struct.setAceIsSet(true);
        }
        if (incoming.get(3)) {
          struct.ase = new org.apache.airavata.model.error.AiravataSystemException();
          struct.ase.read(iprot);
          struct.setAseIsSet(true);
        }
        if (incoming.get(4)) {
          struct.ae = new org.apache.airavata.model.error.AuthorizationException();
          struct.ae.read(iprot);
          struct.setAeIsSet(true);
        }
      }
    }

  }

  public static class registerGatewayResourceProfile_args implements org.apache.thrift.TBase<registerGatewayResourceProfile_args, registerGatewayResourceProfile_args._Fields>, java.io.Serializable, Cloneable, Comparable<registerGatewayResourceProfile_args>   {
    private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("registerGatewayResourceProfile_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_RESOURCE_PROFILE_FIELD_DESC = new org.apache.thrift.protocol.TField("gatewayResourceProfile", org.apache.thrift.protocol.TType.STRUCT, (short)2);

    private static final Map<Class<? extends IScheme>, SchemeFactory> schemes = new HashMap<Class<? extends IScheme>, SchemeFactory>();
    static {
      schemes.put(StandardScheme.class, new registerGatewayResourceProfile_argsStandardSchemeFactory());
      schemes.put(TupleScheme.class, new registerGatewayResourceProfile_argsTupleSchemeFactory());
    }

    public org.apache.airavata.model.security.AuthzToken authzToken; // required
    public org.apache.airavata.model.appcatalog.gatewayprofile.GatewayResourceProfile gatewayResourceProfile; // required

    /** 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_RESOURCE_PROFILE((short)2, "gatewayResourceProfile");

      private static final Map<String, _Fields> byName = new HashMap<String, _Fields>();

      static {
        for (_Fields field : EnumSet.allOf(_Fields.class)) {
          byName.put(field.getFieldName(), field);
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, or null if its not found.
       */
      public static _Fields findByThriftId(int fieldId) {
        switch(fieldId) {
          case 1: // AUTHZ_TOKEN
            return AUTHZ_TOKEN;
          case 2: // GATEWAY_RESOURCE_PROFILE
            return GATEWAY_RESOURCE_PROFILE;
          default:
            return null;
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, throwing an exception
       * if it is not found.
       */
      public static _Fields findByThriftIdOrThrow(int fieldId) {
        _Fields fields = findByThriftId(fieldId);
        if (fields == null) throw new IllegalArgumentException("Field " + fieldId + " doesn't exist!");
        return fields;
      }

      /**
       * Find the _Fields constant that matches name, or null if its not found.
       */
      public static _Fields findByName(String name) {
        return byName.get(name);
      }

      private final short _thriftId;
      private final String _fieldName;

      _Fields(short thriftId, String fieldName) {
        _thriftId = thriftId;
        _fieldName = fieldName;
      }

      public short getThriftFieldId() {
        return _thriftId;
      }

      public String getFieldName() {
        return _fieldName;
      }
    }

    // isset id assignments
    public static final Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
    static {
      Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new EnumMap<_Fields, org.apache.thrift.meta_data.FieldMetaData>(_Fields.class);
      tmpMap.put(_Fields.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_RESOURCE_PROFILE, new org.apache.thrift.meta_data.FieldMetaData("gatewayResourceProfile", org.apache.thrift.TFieldRequirementType.REQUIRED, 
          new org.apache.thrift.meta_data.StructMetaData(org.apache.thrift.protocol.TType.STRUCT, org.apache.airavata.model.appcatalog.gatewayprofile.GatewayResourceProfile.class)));
      metaDataMap = Collections.unmodifiableMap(tmpMap);
      org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(registerGatewayResourceProfile_args.class, metaDataMap);
    }

    public registerGatewayResourceProfile_args() {
    }

    public registerGatewayResourceProfile_args(
      org.apache.airavata.model.security.AuthzToken authzToken,
      org.apache.airavata.model.appcatalog.gatewayprofile.GatewayResourceProfile gatewayResourceProfile)
    {
      this();
      this.authzToken = authzToken;
      this.gatewayResourceProfile = gatewayResourceProfile;
    }

    /**
     * Performs a deep copy on <i>other</i>.
     */
    public registerGatewayResourceProfile_args(registerGatewayResourceProfile_args other) {
      if (other.isSetAuthzToken()) {
        this.authzToken = new org.apache.airavata.model.security.AuthzToken(other.authzToken);
      }
      if (other.isSetGatewayResourceProfile()) {
        this.gatewayResourceProfile = new org.apache.airavata.model.appcatalog.gatewayprofile.GatewayResourceProfile(other.gatewayResourceProfile);
      }
    }

    public registerGatewayResourceProfile_args deepCopy() {
      return new registerGatewayResourceProfile_args(this);
    }

    @Override
    public void clear() {
      this.authzToken = null;
      this.gatewayResourceProfile = null;
    }

    public org.apache.airavata.model.security.AuthzToken getAuthzToken() {
      return this.authzToken;
    }

    public registerGatewayResourceProfile_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.appcatalog.gatewayprofile.GatewayResourceProfile getGatewayResourceProfile() {
      return this.gatewayResourceProfile;
    }

    public registerGatewayResourceProfile_args setGatewayResourceProfile(org.apache.airavata.model.appcatalog.gatewayprofile.GatewayResourceProfile gatewayResourceProfile) {
      this.gatewayResourceProfile = gatewayResourceProfile;
      return this;
    }

    public void unsetGatewayResourceProfile() {
      this.gatewayResourceProfile = null;
    }

    /** Returns true if field gatewayResourceProfile is set (has been assigned a value) and false otherwise */
    public boolean isSetGatewayResourceProfile() {
      return this.gatewayResourceProfile != null;
    }

    public void setGatewayResourceProfileIsSet(boolean value) {
      if (!value) {
        this.gatewayResourceProfile = null;
      }
    }

    public void setFieldValue(_Fields field, Object value) {
      switch (field) {
      case AUTHZ_TOKEN:
        if (value == null) {
          unsetAuthzToken();
        } else {
          setAuthzToken((org.apache.airavata.model.security.AuthzToken)value);
        }
        break;

      case GATEWAY_RESOURCE_PROFILE:
        if (value == null) {
          unsetGatewayResourceProfile();
        } else {
          setGatewayResourceProfile((org.apache.airavata.model.appcatalog.gatewayprofile.GatewayResourceProfile)value);
        }
        break;

      }
    }

    public Object getFieldValue(_Fields field) {
      switch (field) {
      case AUTHZ_TOKEN:
        return getAuthzToken();

      case GATEWAY_RESOURCE_PROFILE:
        return getGatewayResourceProfile();

      }
      throw new IllegalStateException();
    }

    /** Returns true if field corresponding to fieldID is set (has been assigned a value) and false otherwise */
    public boolean isSet(_Fields field) {
      if (field == null) {
        throw new IllegalArgumentException();
      }

      switch (field) {
      case AUTHZ_TOKEN:
        return isSetAuthzToken();
      case GATEWAY_RESOURCE_PROFILE:
        return isSetGatewayResourceProfile();
      }
      throw new IllegalStateException();
    }

    @Override
    public boolean equals(Object that) {
      if (that == null)
        return false;
      if (that instanceof registerGatewayResourceProfile_args)
        return this.equals((registerGatewayResourceProfile_args)that);
      return false;
    }

    public boolean equals(registerGatewayResourceProfile_args that) {
      if (that == null)
        return false;

      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_gatewayResourceProfile = true && this.isSetGatewayResourceProfile();
      boolean that_present_gatewayResourceProfile = true && that.isSetGatewayResourceProfile();
      if (this_present_gatewayResourceProfile || that_present_gatewayResourceProfile) {
        if (!(this_present_gatewayResourceProfile && that_present_gatewayResourceProfile))
          return false;
        if (!this.gatewayResourceProfile.equals(that.gatewayResourceProfile))
          return false;
      }

      return true;
    }

    @Override
    public int hashCode() {
      List<Object> list = new ArrayList<Object>();

      boolean present_authzToken = true && (isSetAuthzToken());
      list.add(present_authzToken);
      if (present_authzToken)
        list.add(authzToken);

      boolean present_gatewayResourceProfile = true && (isSetGatewayResourceProfile());
      list.add(present_gatewayResourceProfile);
      if (present_gatewayResourceProfile)
        list.add(gatewayResourceProfile);

      return list.hashCode();
    }

    @Override
    public int compareTo(registerGatewayResourceProfile_args other) {
      if (!getClass().equals(other.getClass())) {
        return getClass().getName().compareTo(other.getClass().getName());
      }

      int lastComparison = 0;

      lastComparison = 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 = Boolean.valueOf(isSetGatewayResourceProfile()).compareTo(other.isSetGatewayResourceProfile());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetGatewayResourceProfile()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.gatewayResourceProfile, other.gatewayResourceProfile);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      return 0;
    }

    public _Fields fieldForId(int fieldId) {
      return _Fields.findByThriftId(fieldId);
    }

    public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
      schemes.get(iprot.getScheme()).getScheme().read(iprot, this);
    }

    public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException {
      schemes.get(oprot.getScheme()).getScheme().write(oprot, this);
    }

    @Override
    public String toString() {
      StringBuilder sb = new StringBuilder("registerGatewayResourceProfile_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("gatewayResourceProfile:");
      if (this.gatewayResourceProfile == null) {
        sb.append("null");
      } else {
        sb.append(this.gatewayResourceProfile);
      }
      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 (gatewayResourceProfile == null) {
        throw new org.apache.thrift.protocol.TProtocolException("Required field 'gatewayResourceProfile' was not present! Struct: " + toString());
      }
      // check for sub-struct validity
      if (authzToken != null) {
        authzToken.validate();
      }
      if (gatewayResourceProfile != null) {
        gatewayResourceProfile.validate();
      }
    }

    private void writeObject(java.io.ObjectOutputStream out) throws java.io.IOException {
      try {
        write(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(out)));
      } catch (org.apache.thrift.TException te) {
        throw new java.io.IOException(te);
      }
    }

    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, ClassNotFoundException {
      try {
        read(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(in)));
      } catch (org.apache.thrift.TException te) {
        throw new java.io.IOException(te);
      }
    }

    private static class registerGatewayResourceProfile_argsStandardSchemeFactory implements SchemeFactory {
      public registerGatewayResourceProfile_argsStandardScheme getScheme() {
        return new registerGatewayResourceProfile_argsStandardScheme();
      }
    }

    private static class registerGatewayResourceProfile_argsStandardScheme extends StandardScheme<registerGatewayResourceProfile_args> {

      public void read(org.apache.thrift.protocol.TProtocol iprot, registerGatewayResourceProfile_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_RESOURCE_PROFILE
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.gatewayResourceProfile = new org.apache.airavata.model.appcatalog.gatewayprofile.GatewayResourceProfile();
                struct.gatewayResourceProfile.read(iprot);
                struct.setGatewayResourceProfileIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            default:
              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
          }
          iprot.readFieldEnd();
        }
        iprot.readStructEnd();

        // check for required fields of primitive type, which can't be checked in the validate method
        struct.validate();
      }

      public void write(org.apache.thrift.protocol.TProtocol oprot, registerGatewayResourceProfile_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.gatewayResourceProfile != null) {
          oprot.writeFieldBegin(GATEWAY_RESOURCE_PROFILE_FIELD_DESC);
          struct.gatewayResourceProfile.write(oprot);
          oprot.writeFieldEnd();
        }
        oprot.writeFieldStop();
        oprot.writeStructEnd();
      }

    }

    private static class registerGatewayResourceProfile_argsTupleSchemeFactory implements SchemeFactory {
      public registerGatewayResourceProfile_argsTupleScheme getScheme() {
        return new registerGatewayResourceProfile_argsTupleScheme();
      }
    }

    private static class registerGatewayResourceProfile_argsTupleScheme extends TupleScheme<registerGatewayResourceProfile_args> {

      @Override
      public void write(org.apache.thrift.protocol.TProtocol prot, registerGatewayResourceProfile_args struct) throws org.apache.thrift.TException {
        TTupleProtocol oprot = (TTupleProtocol) prot;
        struct.authzToken.write(oprot);
        struct.gatewayResourceProfile.write(oprot);
      }

      @Override
      public void read(org.apache.thrift.protocol.TProtocol prot, registerGatewayResourceProfile_args struct) throws org.apache.thrift.TException {
        TTupleProtocol iprot = (TTupleProtocol) prot;
        struct.authzToken = new org.apache.airavata.model.security.AuthzToken();
        struct.authzToken.read(iprot);
        struct.setAuthzTokenIsSet(true);
        struct.gatewayResourceProfile = new org.apache.airavata.model.appcatalog.gatewayprofile.GatewayResourceProfile();
        struct.gatewayResourceProfile.read(iprot);
        struct.setGatewayResourceProfileIsSet(true);
      }
    }

  }

  public static class registerGatewayResourceProfile_result implements org.apache.thrift.TBase<registerGatewayResourceProfile_result, registerGatewayResourceProfile_result._Fields>, java.io.Serializable, Cloneable, Comparable<registerGatewayResourceProfile_result>   {
    private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("registerGatewayResourceProfile_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 IRE_FIELD_DESC = new org.apache.thrift.protocol.TField("ire", org.apache.thrift.protocol.TType.STRUCT, (short)1);
    private static final org.apache.thrift.protocol.TField ACE_FIELD_DESC = new org.apache.thrift.protocol.TField("ace", org.apache.thrift.protocol.TType.STRUCT, (short)2);
    private static final org.apache.thrift.protocol.TField ASE_FIELD_DESC = new org.apache.thrift.protocol.TField("ase", org.apache.thrift.protocol.TType.STRUCT, (short)3);
    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)4);

    private static final Map<Class<? extends IScheme>, SchemeFactory> schemes = new HashMap<Class<? extends IScheme>, SchemeFactory>();
    static {
      schemes.put(StandardScheme.class, new registerGatewayResourceProfile_resultStandardSchemeFactory());
      schemes.put(TupleScheme.class, new registerGatewayResourceProfile_resultTupleSchemeFactory());
    }

    public String success; // required
    public org.apache.airavata.model.error.InvalidRequestException ire; // required
    public org.apache.airavata.model.error.AiravataClientException ace; // required
    public org.apache.airavata.model.error.AiravataSystemException ase; // 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"),
      IRE((short)1, "ire"),
      ACE((short)2, "ace"),
      ASE((short)3, "ase"),
      AE((short)4, "ae");

      private static final Map<String, _Fields> byName = new HashMap<String, _Fields>();

      static {
        for (_Fields field : EnumSet.allOf(_Fields.class)) {
          byName.put(field.getFieldName(), field);
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, or null if its not found.
       */
      public static _Fields findByThriftId(int fieldId) {
        switch(fieldId) {
          case 0: // SUCCESS
            return SUCCESS;
          case 1: // IRE
            return IRE;
          case 2: // ACE
            return ACE;
          case 3: // ASE
            return ASE;
          case 4: // 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 IllegalArgumentException("Field " + fieldId + " doesn't exist!");
        return fields;
      }

      /**
       * Find the _Fields constant that matches name, or null if its not found.
       */
      public static _Fields findByName(String name) {
        return byName.get(name);
      }

      private final short _thriftId;
      private final String _fieldName;

      _Fields(short thriftId, String fieldName) {
        _thriftId = thriftId;
        _fieldName = fieldName;
      }

      public short getThriftFieldId() {
        return _thriftId;
      }

      public String getFieldName() {
        return _fieldName;
      }
    }

    // isset id assignments
    public static final Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
    static {
      Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new EnumMap<_Fields, org.apache.thrift.meta_data.FieldMetaData>(_Fields.class);
      tmpMap.put(_Fields.SUCCESS, new org.apache.thrift.meta_data.FieldMetaData("success", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING)));
      tmpMap.put(_Fields.IRE, new org.apache.thrift.meta_data.FieldMetaData("ire", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRUCT)));
      tmpMap.put(_Fields.ACE, new org.apache.thrift.meta_data.FieldMetaData("ace", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRUCT)));
      tmpMap.put(_Fields.ASE, new org.apache.thrift.meta_data.FieldMetaData("ase", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRUCT)));
      tmpMap.put(_Fields.AE, new org.apache.thrift.meta_data.FieldMetaData("ae", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRUCT)));
      metaDataMap = Collections.unmodifiableMap(tmpMap);
      org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(registerGatewayResourceProfile_result.class, metaDataMap);
    }

    public registerGatewayResourceProfile_result() {
    }

    public registerGatewayResourceProfile_result(
      String success,
      org.apache.airavata.model.error.InvalidRequestException ire,
      org.apache.airavata.model.error.AiravataClientException ace,
      org.apache.airavata.model.error.AiravataSystemException ase,
      org.apache.airavata.model.error.AuthorizationException ae)
    {
      this();
      this.success = success;
      this.ire = ire;
      this.ace = ace;
      this.ase = ase;
      this.ae = ae;
    }

    /**
     * Performs a deep copy on <i>other</i>.
     */
    public registerGatewayResourceProfile_result(registerGatewayResourceProfile_result other) {
      if (other.isSetSuccess()) {
        this.success = other.success;
      }
      if (other.isSetIre()) {
        this.ire = new org.apache.airavata.model.error.InvalidRequestException(other.ire);
      }
      if (other.isSetAce()) {
        this.ace = new org.apache.airavata.model.error.AiravataClientException(other.ace);
      }
      if (other.isSetAse()) {
        this.ase = new org.apache.airavata.model.error.AiravataSystemException(other.ase);
      }
      if (other.isSetAe()) {
        this.ae = new org.apache.airavata.model.error.AuthorizationException(other.ae);
      }
    }

    public registerGatewayResourceProfile_result deepCopy() {
      return new registerGatewayResourceProfile_result(this);
    }

    @Override
    public void clear() {
      this.success = null;
      this.ire = null;
      this.ace = null;
      this.ase = null;
      this.ae = null;
    }

    public String getSuccess() {
      return this.success;
    }

    public registerGatewayResourceProfile_result setSuccess(String success) {
      this.success = success;
      return this;
    }

    public void unsetSuccess() {
      this.success = null;
    }

    /** Returns true if field success is set (has been assigned a value) and false otherwise */
    public boolean isSetSuccess() {
      return this.success != null;
    }

    public void setSuccessIsSet(boolean value) {
      if (!value) {
        this.success = null;
      }
    }

    public org.apache.airavata.model.error.InvalidRequestException getIre() {
      return this.ire;
    }

    public registerGatewayResourceProfile_result setIre(org.apache.airavata.model.error.InvalidRequestException ire) {
      this.ire = ire;
      return this;
    }

    public void unsetIre() {
      this.ire = null;
    }

    /** Returns true if field ire is set (has been assigned a value) and false otherwise */
    public boolean isSetIre() {
      return this.ire != null;
    }

    public void setIreIsSet(boolean value) {
      if (!value) {
        this.ire = null;
      }
    }

    public org.apache.airavata.model.error.AiravataClientException getAce() {
      return this.ace;
    }

    public registerGatewayResourceProfile_result setAce(org.apache.airavata.model.error.AiravataClientException ace) {
      this.ace = ace;
      return this;
    }

    public void unsetAce() {
      this.ace = null;
    }

    /** Returns true if field ace is set (has been assigned a value) and false otherwise */
    public boolean isSetAce() {
      return this.ace != null;
    }

    public void setAceIsSet(boolean value) {
      if (!value) {
        this.ace = null;
      }
    }

    public org.apache.airavata.model.error.AiravataSystemException getAse() {
      return this.ase;
    }

    public registerGatewayResourceProfile_result setAse(org.apache.airavata.model.error.AiravataSystemException ase) {
      this.ase = ase;
      return this;
    }

    public void unsetAse() {
      this.ase = null;
    }

    /** Returns true if field ase is set (has been assigned a value) and false otherwise */
    public boolean isSetAse() {
      return this.ase != null;
    }

    public void setAseIsSet(boolean value) {
      if (!value) {
        this.ase = null;
      }
    }

    public org.apache.airavata.model.error.AuthorizationException getAe() {
      return this.ae;
    }

    public registerGatewayResourceProfile_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, Object value) {
      switch (field) {
      case SUCCESS:
        if (value == null) {
          unsetSuccess();
        } else {
          setSuccess((String)value);
        }
        break;

      case IRE:
        if (value == null) {
          unsetIre();
        } else {
          setIre((org.apache.airavata.model.error.InvalidRequestException)value);
        }
        break;

      case ACE:
        if (value == null) {
          unsetAce();
        } else {
          setAce((org.apache.airavata.model.error.AiravataClientException)value);
        }
        break;

      case ASE:
        if (value == null) {
          unsetAse();
        } else {
          setAse((org.apache.airavata.model.error.AiravataSystemException)value);
        }
        break;

      case AE:
        if (value == null) {
          unsetAe();
        } else {
          setAe((org.apache.airavata.model.error.AuthorizationException)value);
        }
        break;

      }
    }

    public Object getFieldValue(_Fields field) {
      switch (field) {
      case SUCCESS:
        return getSuccess();

      case IRE:
        return getIre();

      case ACE:
        return getAce();

      case ASE:
        return getAse();

      case AE:
        return getAe();

      }
      throw new IllegalStateException();
    }

    /** Returns true if field corresponding to fieldID is set (has been assigned a value) and false otherwise */
    public boolean isSet(_Fields field) {
      if (field == null) {
        throw new IllegalArgumentException();
      }

      switch (field) {
      case SUCCESS:
        return isSetSuccess();
      case IRE:
        return isSetIre();
      case ACE:
        return isSetAce();
      case ASE:
        return isSetAse();
      case AE:
        return isSetAe();
      }
      throw new IllegalStateException();
    }

    @Override
    public boolean equals(Object that) {
      if (that == null)
        return false;
      if (that instanceof registerGatewayResourceProfile_result)
        return this.equals((registerGatewayResourceProfile_result)that);
      return false;
    }

    public boolean equals(registerGatewayResourceProfile_result that) {
      if (that == null)
        return false;

      boolean this_present_success = true && this.isSetSuccess();
      boolean that_present_success = true && that.isSetSuccess();
      if (this_present_success || that_present_success) {
        if (!(this_present_success && that_present_success))
          return false;
        if (!this.success.equals(that.success))
          return false;
      }

      boolean this_present_ire = true && this.isSetIre();
      boolean that_present_ire = true && that.isSetIre();
      if (this_present_ire || that_present_ire) {
        if (!(this_present_ire && that_present_ire))
          return false;
        if (!this.ire.equals(that.ire))
          return false;
      }

      boolean this_present_ace = true && this.isSetAce();
      boolean that_present_ace = true && that.isSetAce();
      if (this_present_ace || that_present_ace) {
        if (!(this_present_ace && that_present_ace))
          return false;
        if (!this.ace.equals(that.ace))
          return false;
      }

      boolean this_present_ase = true && this.isSetAse();
      boolean that_present_ase = true && that.isSetAse();
      if (this_present_ase || that_present_ase) {
        if (!(this_present_ase && that_present_ase))
          return false;
        if (!this.ase.equals(that.ase))
          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() {
      List<Object> list = new ArrayList<Object>();

      boolean present_success = true && (isSetSuccess());
      list.add(present_success);
      if (present_success)
        list.add(success);

      boolean present_ire = true && (isSetIre());
      list.add(present_ire);
      if (present_ire)
        list.add(ire);

      boolean present_ace = true && (isSetAce());
      list.add(present_ace);
      if (present_ace)
        list.add(ace);

      boolean present_ase = true && (isSetAse());
      list.add(present_ase);
      if (present_ase)
        list.add(ase);

      boolean present_ae = true && (isSetAe());
      list.add(present_ae);
      if (present_ae)
        list.add(ae);

      return list.hashCode();
    }

    @Override
    public int compareTo(registerGatewayResourceProfile_result other) {
      if (!getClass().equals(other.getClass())) {
        return getClass().getName().compareTo(other.getClass().getName());
      }

      int lastComparison = 0;

      lastComparison = Boolean.valueOf(isSetSuccess()).compareTo(other.isSetSuccess());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetSuccess()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.success, other.success);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = Boolean.valueOf(isSetIre()).compareTo(other.isSetIre());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetIre()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.ire, other.ire);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = Boolean.valueOf(isSetAce()).compareTo(other.isSetAce());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetAce()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.ace, other.ace);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = Boolean.valueOf(isSetAse()).compareTo(other.isSetAse());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetAse()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.ase, other.ase);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = 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 {
      schemes.get(iprot.getScheme()).getScheme().read(iprot, this);
    }

    public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException {
      schemes.get(oprot.getScheme()).getScheme().write(oprot, this);
      }

    @Override
    public String toString() {
      StringBuilder sb = new StringBuilder("registerGatewayResourceProfile_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("ire:");
      if (this.ire == null) {
        sb.append("null");
      } else {
        sb.append(this.ire);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("ace:");
      if (this.ace == null) {
        sb.append("null");
      } else {
        sb.append(this.ace);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("ase:");
      if (this.ase == null) {
        sb.append("null");
      } else {
        sb.append(this.ase);
      }
      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, 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 registerGatewayResourceProfile_resultStandardSchemeFactory implements SchemeFactory {
      public registerGatewayResourceProfile_resultStandardScheme getScheme() {
        return new registerGatewayResourceProfile_resultStandardScheme();
      }
    }

    private static class registerGatewayResourceProfile_resultStandardScheme extends StandardScheme<registerGatewayResourceProfile_result> {

      public void read(org.apache.thrift.protocol.TProtocol iprot, registerGatewayResourceProfile_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: // IRE
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.ire = new org.apache.airavata.model.error.InvalidRequestException();
                struct.ire.read(iprot);
                struct.setIreIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 2: // ACE
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.ace = new org.apache.airavata.model.error.AiravataClientException();
                struct.ace.read(iprot);
                struct.setAceIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 3: // ASE
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.ase = new org.apache.airavata.model.error.AiravataSystemException();
                struct.ase.read(iprot);
                struct.setAseIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 4: // 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, registerGatewayResourceProfile_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.ire != null) {
          oprot.writeFieldBegin(IRE_FIELD_DESC);
          struct.ire.write(oprot);
          oprot.writeFieldEnd();
        }
        if (struct.ace != null) {
          oprot.writeFieldBegin(ACE_FIELD_DESC);
          struct.ace.write(oprot);
          oprot.writeFieldEnd();
        }
        if (struct.ase != null) {
          oprot.writeFieldBegin(ASE_FIELD_DESC);
          struct.ase.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 registerGatewayResourceProfile_resultTupleSchemeFactory implements SchemeFactory {
      public registerGatewayResourceProfile_resultTupleScheme getScheme() {
        return new registerGatewayResourceProfile_resultTupleScheme();
      }
    }

    private static class registerGatewayResourceProfile_resultTupleScheme extends TupleScheme<registerGatewayResourceProfile_result> {

      @Override
      public void write(org.apache.thrift.protocol.TProtocol prot, registerGatewayResourceProfile_result struct) throws org.apache.thrift.TException {
        TTupleProtocol oprot = (TTupleProtocol) prot;
        BitSet optionals = new BitSet();
        if (struct.isSetSuccess()) {
          optionals.set(0);
        }
        if (struct.isSetIre()) {
          optionals.set(1);
        }
        if (struct.isSetAce()) {
          optionals.set(2);
        }
        if (struct.isSetAse()) {
          optionals.set(3);
        }
        if (struct.isSetAe()) {
          optionals.set(4);
        }
        oprot.writeBitSet(optionals, 5);
        if (struct.isSetSuccess()) {
          oprot.writeString(struct.success);
        }
        if (struct.isSetIre()) {
          struct.ire.write(oprot);
        }
        if (struct.isSetAce()) {
          struct.ace.write(oprot);
        }
        if (struct.isSetAse()) {
          struct.ase.write(oprot);
        }
        if (struct.isSetAe()) {
          struct.ae.write(oprot);
        }
      }

      @Override
      public void read(org.apache.thrift.protocol.TProtocol prot, registerGatewayResourceProfile_result struct) throws org.apache.thrift.TException {
        TTupleProtocol iprot = (TTupleProtocol) prot;
        BitSet incoming = iprot.readBitSet(5);
        if (incoming.get(0)) {
          struct.success = iprot.readString();
          struct.setSuccessIsSet(true);
        }
        if (incoming.get(1)) {
          struct.ire = new org.apache.airavata.model.error.InvalidRequestException();
          struct.ire.read(iprot);
          struct.setIreIsSet(true);
        }
        if (incoming.get(2)) {
          struct.ace = new org.apache.airavata.model.error.AiravataClientException();
          struct.ace.read(iprot);
          struct.setAceIsSet(true);
        }
        if (incoming.get(3)) {
          struct.ase = new org.apache.airavata.model.error.AiravataSystemException();
          struct.ase.read(iprot);
          struct.setAseIsSet(true);
        }
        if (incoming.get(4)) {
          struct.ae = new org.apache.airavata.model.error.AuthorizationException();
          struct.ae.read(iprot);
          struct.setAeIsSet(true);
        }
      }
    }

  }

  public static class getGatewayResourceProfile_args implements org.apache.thrift.TBase<getGatewayResourceProfile_args, getGatewayResourceProfile_args._Fields>, java.io.Serializable, Cloneable, Comparable<getGatewayResourceProfile_args>   {
    private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("getGatewayResourceProfile_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 Map<Class<? extends IScheme>, SchemeFactory> schemes = new HashMap<Class<? extends IScheme>, SchemeFactory>();
    static {
      schemes.put(StandardScheme.class, new getGatewayResourceProfile_argsStandardSchemeFactory());
      schemes.put(TupleScheme.class, new getGatewayResourceProfile_argsTupleSchemeFactory());
    }

    public org.apache.airavata.model.security.AuthzToken authzToken; // required
    public 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 Map<String, _Fields> byName = new HashMap<String, _Fields>();

      static {
        for (_Fields field : EnumSet.allOf(_Fields.class)) {
          byName.put(field.getFieldName(), field);
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, or null if its not found.
       */
      public static _Fields findByThriftId(int fieldId) {
        switch(fieldId) {
          case 1: // 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 IllegalArgumentException("Field " + fieldId + " doesn't exist!");
        return fields;
      }

      /**
       * Find the _Fields constant that matches name, or null if its not found.
       */
      public static _Fields findByName(String name) {
        return byName.get(name);
      }

      private final short _thriftId;
      private final String _fieldName;

      _Fields(short thriftId, String fieldName) {
        _thriftId = thriftId;
        _fieldName = fieldName;
      }

      public short getThriftFieldId() {
        return _thriftId;
      }

      public String getFieldName() {
        return _fieldName;
      }
    }

    // isset id assignments
    public static final Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
    static {
      Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new EnumMap<_Fields, org.apache.thrift.meta_data.FieldMetaData>(_Fields.class);
      tmpMap.put(_Fields.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 = Collections.unmodifiableMap(tmpMap);
      org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(getGatewayResourceProfile_args.class, metaDataMap);
    }

    public getGatewayResourceProfile_args() {
    }

    public getGatewayResourceProfile_args(
      org.apache.airavata.model.security.AuthzToken authzToken,
      String gatewayID)
    {
      this();
      this.authzToken = authzToken;
      this.gatewayID = gatewayID;
    }

    /**
     * Performs a deep copy on <i>other</i>.
     */
    public getGatewayResourceProfile_args(getGatewayResourceProfile_args other) {
      if (other.isSetAuthzToken()) {
        this.authzToken = new org.apache.airavata.model.security.AuthzToken(other.authzToken);
      }
      if (other.isSetGatewayID()) {
        this.gatewayID = other.gatewayID;
      }
    }

    public getGatewayResourceProfile_args deepCopy() {
      return new getGatewayResourceProfile_args(this);
    }

    @Override
    public void clear() {
      this.authzToken = null;
      this.gatewayID = null;
    }

    public org.apache.airavata.model.security.AuthzToken getAuthzToken() {
      return this.authzToken;
    }

    public getGatewayResourceProfile_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 String getGatewayID() {
      return this.gatewayID;
    }

    public getGatewayResourceProfile_args setGatewayID(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, 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((String)value);
        }
        break;

      }
    }

    public Object getFieldValue(_Fields field) {
      switch (field) {
      case AUTHZ_TOKEN:
        return getAuthzToken();

      case GATEWAY_ID:
        return getGatewayID();

      }
      throw new IllegalStateException();
    }

    /** Returns true if field corresponding to fieldID is set (has been assigned a value) and false otherwise */
    public boolean isSet(_Fields field) {
      if (field == null) {
        throw new IllegalArgumentException();
      }

      switch (field) {
      case AUTHZ_TOKEN:
        return isSetAuthzToken();
      case GATEWAY_ID:
        return isSetGatewayID();
      }
      throw new IllegalStateException();
    }

    @Override
    public boolean equals(Object that) {
      if (that == null)
        return false;
      if (that instanceof getGatewayResourceProfile_args)
        return this.equals((getGatewayResourceProfile_args)that);
      return false;
    }

    public boolean equals(getGatewayResourceProfile_args that) {
      if (that == null)
        return false;

      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() {
      List<Object> list = new ArrayList<Object>();

      boolean present_authzToken = true && (isSetAuthzToken());
      list.add(present_authzToken);
      if (present_authzToken)
        list.add(authzToken);

      boolean present_gatewayID = true && (isSetGatewayID());
      list.add(present_gatewayID);
      if (present_gatewayID)
        list.add(gatewayID);

      return list.hashCode();
    }

    @Override
    public int compareTo(getGatewayResourceProfile_args other) {
      if (!getClass().equals(other.getClass())) {
        return getClass().getName().compareTo(other.getClass().getName());
      }

      int lastComparison = 0;

      lastComparison = 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 = 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 {
      schemes.get(iprot.getScheme()).getScheme().read(iprot, this);
    }

    public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException {
      schemes.get(oprot.getScheme()).getScheme().write(oprot, this);
    }

    @Override
    public String toString() {
      StringBuilder sb = new StringBuilder("getGatewayResourceProfile_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, 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 getGatewayResourceProfile_argsStandardSchemeFactory implements SchemeFactory {
      public getGatewayResourceProfile_argsStandardScheme getScheme() {
        return new getGatewayResourceProfile_argsStandardScheme();
      }
    }

    private static class getGatewayResourceProfile_argsStandardScheme extends StandardScheme<getGatewayResourceProfile_args> {

      public void read(org.apache.thrift.protocol.TProtocol iprot, getGatewayResourceProfile_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, getGatewayResourceProfile_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 getGatewayResourceProfile_argsTupleSchemeFactory implements SchemeFactory {
      public getGatewayResourceProfile_argsTupleScheme getScheme() {
        return new getGatewayResourceProfile_argsTupleScheme();
      }
    }

    private static class getGatewayResourceProfile_argsTupleScheme extends TupleScheme<getGatewayResourceProfile_args> {

      @Override
      public void write(org.apache.thrift.protocol.TProtocol prot, getGatewayResourceProfile_args struct) throws org.apache.thrift.TException {
        TTupleProtocol oprot = (TTupleProtocol) prot;
        struct.authzToken.write(oprot);
        oprot.writeString(struct.gatewayID);
      }

      @Override
      public void read(org.apache.thrift.protocol.TProtocol prot, getGatewayResourceProfile_args struct) throws org.apache.thrift.TException {
        TTupleProtocol iprot = (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);
      }
    }

  }

  public static class getGatewayResourceProfile_result implements org.apache.thrift.TBase<getGatewayResourceProfile_result, getGatewayResourceProfile_result._Fields>, java.io.Serializable, Cloneable, Comparable<getGatewayResourceProfile_result>   {
    private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("getGatewayResourceProfile_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 IRE_FIELD_DESC = new org.apache.thrift.protocol.TField("ire", org.apache.thrift.protocol.TType.STRUCT, (short)1);
    private static final org.apache.thrift.protocol.TField ACE_FIELD_DESC = new org.apache.thrift.protocol.TField("ace", org.apache.thrift.protocol.TType.STRUCT, (short)2);
    private static final org.apache.thrift.protocol.TField ASE_FIELD_DESC = new org.apache.thrift.protocol.TField("ase", org.apache.thrift.protocol.TType.STRUCT, (short)3);
    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)4);

    private static final Map<Class<? extends IScheme>, SchemeFactory> schemes = new HashMap<Class<? extends IScheme>, SchemeFactory>();
    static {
      schemes.put(StandardScheme.class, new getGatewayResourceProfile_resultStandardSchemeFactory());
      schemes.put(TupleScheme.class, new getGatewayResourceProfile_resultTupleSchemeFactory());
    }

    public org.apache.airavata.model.appcatalog.gatewayprofile.GatewayResourceProfile success; // required
    public org.apache.airavata.model.error.InvalidRequestException ire; // required
    public org.apache.airavata.model.error.AiravataClientException ace; // required
    public org.apache.airavata.model.error.AiravataSystemException ase; // 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"),
      IRE((short)1, "ire"),
      ACE((short)2, "ace"),
      ASE((short)3, "ase"),
      AE((short)4, "ae");

      private static final Map<String, _Fields> byName = new HashMap<String, _Fields>();

      static {
        for (_Fields field : EnumSet.allOf(_Fields.class)) {
          byName.put(field.getFieldName(), field);
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, or null if its not found.
       */
      public static _Fields findByThriftId(int fieldId) {
        switch(fieldId) {
          case 0: // SUCCESS
            return SUCCESS;
          case 1: // IRE
            return IRE;
          case 2: // ACE
            return ACE;
          case 3: // ASE
            return ASE;
          case 4: // 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 IllegalArgumentException("Field " + fieldId + " doesn't exist!");
        return fields;
      }

      /**
       * Find the _Fields constant that matches name, or null if its not found.
       */
      public static _Fields findByName(String name) {
        return byName.get(name);
      }

      private final short _thriftId;
      private final String _fieldName;

      _Fields(short thriftId, String fieldName) {
        _thriftId = thriftId;
        _fieldName = fieldName;
      }

      public short getThriftFieldId() {
        return _thriftId;
      }

      public String getFieldName() {
        return _fieldName;
      }
    }

    // isset id assignments
    public static final Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
    static {
      Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new EnumMap<_Fields, org.apache.thrift.meta_data.FieldMetaData>(_Fields.class);
      tmpMap.put(_Fields.SUCCESS, new org.apache.thrift.meta_data.FieldMetaData("success", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.StructMetaData(org.apache.thrift.protocol.TType.STRUCT, org.apache.airavata.model.appcatalog.gatewayprofile.GatewayResourceProfile.class)));
      tmpMap.put(_Fields.IRE, new org.apache.thrift.meta_data.FieldMetaData("ire", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRUCT)));
      tmpMap.put(_Fields.ACE, new org.apache.thrift.meta_data.FieldMetaData("ace", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRUCT)));
      tmpMap.put(_Fields.ASE, new org.apache.thrift.meta_data.FieldMetaData("ase", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRUCT)));
      tmpMap.put(_Fields.AE, new org.apache.thrift.meta_data.FieldMetaData("ae", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRUCT)));
      metaDataMap = Collections.unmodifiableMap(tmpMap);
      org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(getGatewayResourceProfile_result.class, metaDataMap);
    }

    public getGatewayResourceProfile_result() {
    }

    public getGatewayResourceProfile_result(
      org.apache.airavata.model.appcatalog.gatewayprofile.GatewayResourceProfile success,
      org.apache.airavata.model.error.InvalidRequestException ire,
      org.apache.airavata.model.error.AiravataClientException ace,
      org.apache.airavata.model.error.AiravataSystemException ase,
      org.apache.airavata.model.error.AuthorizationException ae)
    {
      this();
      this.success = success;
      this.ire = ire;
      this.ace = ace;
      this.ase = ase;
      this.ae = ae;
    }

    /**
     * Performs a deep copy on <i>other</i>.
     */
    public getGatewayResourceProfile_result(getGatewayResourceProfile_result other) {
      if (other.isSetSuccess()) {
        this.success = new org.apache.airavata.model.appcatalog.gatewayprofile.GatewayResourceProfile(other.success);
      }
      if (other.isSetIre()) {
        this.ire = new org.apache.airavata.model.error.InvalidRequestException(other.ire);
      }
      if (other.isSetAce()) {
        this.ace = new org.apache.airavata.model.error.AiravataClientException(other.ace);
      }
      if (other.isSetAse()) {
        this.ase = new org.apache.airavata.model.error.AiravataSystemException(other.ase);
      }
      if (other.isSetAe()) {
        this.ae = new org.apache.airavata.model.error.AuthorizationException(other.ae);
      }
    }

    public getGatewayResourceProfile_result deepCopy() {
      return new getGatewayResourceProfile_result(this);
    }

    @Override
    public void clear() {
      this.success = null;
      this.ire = null;
      this.ace = null;
      this.ase = null;
      this.ae = null;
    }

    public org.apache.airavata.model.appcatalog.gatewayprofile.GatewayResourceProfile getSuccess() {
      return this.success;
    }

    public getGatewayResourceProfile_result setSuccess(org.apache.airavata.model.appcatalog.gatewayprofile.GatewayResourceProfile 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.model.error.InvalidRequestException getIre() {
      return this.ire;
    }

    public getGatewayResourceProfile_result setIre(org.apache.airavata.model.error.InvalidRequestException ire) {
      this.ire = ire;
      return this;
    }

    public void unsetIre() {
      this.ire = null;
    }

    /** Returns true if field ire is set (has been assigned a value) and false otherwise */
    public boolean isSetIre() {
      return this.ire != null;
    }

    public void setIreIsSet(boolean value) {
      if (!value) {
        this.ire = null;
      }
    }

    public org.apache.airavata.model.error.AiravataClientException getAce() {
      return this.ace;
    }

    public getGatewayResourceProfile_result setAce(org.apache.airavata.model.error.AiravataClientException ace) {
      this.ace = ace;
      return this;
    }

    public void unsetAce() {
      this.ace = null;
    }

    /** Returns true if field ace is set (has been assigned a value) and false otherwise */
    public boolean isSetAce() {
      return this.ace != null;
    }

    public void setAceIsSet(boolean value) {
      if (!value) {
        this.ace = null;
      }
    }

    public org.apache.airavata.model.error.AiravataSystemException getAse() {
      return this.ase;
    }

    public getGatewayResourceProfile_result setAse(org.apache.airavata.model.error.AiravataSystemException ase) {
      this.ase = ase;
      return this;
    }

    public void unsetAse() {
      this.ase = null;
    }

    /** Returns true if field ase is set (has been assigned a value) and false otherwise */
    public boolean isSetAse() {
      return this.ase != null;
    }

    public void setAseIsSet(boolean value) {
      if (!value) {
        this.ase = null;
      }
    }

    public org.apache.airavata.model.error.AuthorizationException getAe() {
      return this.ae;
    }

    public getGatewayResourceProfile_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, Object value) {
      switch (field) {
      case SUCCESS:
        if (value == null) {
          unsetSuccess();
        } else {
          setSuccess((org.apache.airavata.model.appcatalog.gatewayprofile.GatewayResourceProfile)value);
        }
        break;

      case IRE:
        if (value == null) {
          unsetIre();
        } else {
          setIre((org.apache.airavata.model.error.InvalidRequestException)value);
        }
        break;

      case ACE:
        if (value == null) {
          unsetAce();
        } else {
          setAce((org.apache.airavata.model.error.AiravataClientException)value);
        }
        break;

      case ASE:
        if (value == null) {
          unsetAse();
        } else {
          setAse((org.apache.airavata.model.error.AiravataSystemException)value);
        }
        break;

      case AE:
        if (value == null) {
          unsetAe();
        } else {
          setAe((org.apache.airavata.model.error.AuthorizationException)value);
        }
        break;

      }
    }

    public Object getFieldValue(_Fields field) {
      switch (field) {
      case SUCCESS:
        return getSuccess();

      case IRE:
        return getIre();

      case ACE:
        return getAce();

      case ASE:
        return getAse();

      case AE:
        return getAe();

      }
      throw new IllegalStateException();
    }

    /** Returns true if field corresponding to fieldID is set (has been assigned a value) and false otherwise */
    public boolean isSet(_Fields field) {
      if (field == null) {
        throw new IllegalArgumentException();
      }

      switch (field) {
      case SUCCESS:
        return isSetSuccess();
      case IRE:
        return isSetIre();
      case ACE:
        return isSetAce();
      case ASE:
        return isSetAse();
      case AE:
        return isSetAe();
      }
      throw new IllegalStateException();
    }

    @Override
    public boolean equals(Object that) {
      if (that == null)
        return false;
      if (that instanceof getGatewayResourceProfile_result)
        return this.equals((getGatewayResourceProfile_result)that);
      return false;
    }

    public boolean equals(getGatewayResourceProfile_result that) {
      if (that == null)
        return false;

      boolean this_present_success = true && this.isSetSuccess();
      boolean that_present_success = true && that.isSetSuccess();
      if (this_present_success || that_present_success) {
        if (!(this_present_success && that_present_success))
          return false;
        if (!this.success.equals(that.success))
          return false;
      }

      boolean this_present_ire = true && this.isSetIre();
      boolean that_present_ire = true && that.isSetIre();
      if (this_present_ire || that_present_ire) {
        if (!(this_present_ire && that_present_ire))
          return false;
        if (!this.ire.equals(that.ire))
          return false;
      }

      boolean this_present_ace = true && this.isSetAce();
      boolean that_present_ace = true && that.isSetAce();
      if (this_present_ace || that_present_ace) {
        if (!(this_present_ace && that_present_ace))
          return false;
        if (!this.ace.equals(that.ace))
          return false;
      }

      boolean this_present_ase = true && this.isSetAse();
      boolean that_present_ase = true && that.isSetAse();
      if (this_present_ase || that_present_ase) {
        if (!(this_present_ase && that_present_ase))
          return false;
        if (!this.ase.equals(that.ase))
          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() {
      List<Object> list = new ArrayList<Object>();

      boolean present_success = true && (isSetSuccess());
      list.add(present_success);
      if (present_success)
        list.add(success);

      boolean present_ire = true && (isSetIre());
      list.add(present_ire);
      if (present_ire)
        list.add(ire);

      boolean present_ace = true && (isSetAce());
      list.add(present_ace);
      if (present_ace)
        list.add(ace);

      boolean present_ase = true && (isSetAse());
      list.add(present_ase);
      if (present_ase)
        list.add(ase);

      boolean present_ae = true && (isSetAe());
      list.add(present_ae);
      if (present_ae)
        list.add(ae);

      return list.hashCode();
    }

    @Override
    public int compareTo(getGatewayResourceProfile_result other) {
      if (!getClass().equals(other.getClass())) {
        return getClass().getName().compareTo(other.getClass().getName());
      }

      int lastComparison = 0;

      lastComparison = Boolean.valueOf(isSetSuccess()).compareTo(other.isSetSuccess());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetSuccess()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.success, other.success);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = Boolean.valueOf(isSetIre()).compareTo(other.isSetIre());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetIre()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.ire, other.ire);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = Boolean.valueOf(isSetAce()).compareTo(other.isSetAce());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetAce()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.ace, other.ace);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = Boolean.valueOf(isSetAse()).compareTo(other.isSetAse());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetAse()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.ase, other.ase);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = 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 {
      schemes.get(iprot.getScheme()).getScheme().read(iprot, this);
    }

    public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException {
      schemes.get(oprot.getScheme()).getScheme().write(oprot, this);
      }

    @Override
    public String toString() {
      StringBuilder sb = new StringBuilder("getGatewayResourceProfile_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("ire:");
      if (this.ire == null) {
        sb.append("null");
      } else {
        sb.append(this.ire);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("ace:");
      if (this.ace == null) {
        sb.append("null");
      } else {
        sb.append(this.ace);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("ase:");
      if (this.ase == null) {
        sb.append("null");
      } else {
        sb.append(this.ase);
      }
      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, 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 getGatewayResourceProfile_resultStandardSchemeFactory implements SchemeFactory {
      public getGatewayResourceProfile_resultStandardScheme getScheme() {
        return new getGatewayResourceProfile_resultStandardScheme();
      }
    }

    private static class getGatewayResourceProfile_resultStandardScheme extends StandardScheme<getGatewayResourceProfile_result> {

      public void read(org.apache.thrift.protocol.TProtocol iprot, getGatewayResourceProfile_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.appcatalog.gatewayprofile.GatewayResourceProfile();
                struct.success.read(iprot);
                struct.setSuccessIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 1: // IRE
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.ire = new org.apache.airavata.model.error.InvalidRequestException();
                struct.ire.read(iprot);
                struct.setIreIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 2: // ACE
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.ace = new org.apache.airavata.model.error.AiravataClientException();
                struct.ace.read(iprot);
                struct.setAceIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 3: // ASE
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.ase = new org.apache.airavata.model.error.AiravataSystemException();
                struct.ase.read(iprot);
                struct.setAseIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 4: // 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, getGatewayResourceProfile_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.ire != null) {
          oprot.writeFieldBegin(IRE_FIELD_DESC);
          struct.ire.write(oprot);
          oprot.writeFieldEnd();
        }
        if (struct.ace != null) {
          oprot.writeFieldBegin(ACE_FIELD_DESC);
          struct.ace.write(oprot);
          oprot.writeFieldEnd();
        }
        if (struct.ase != null) {
          oprot.writeFieldBegin(ASE_FIELD_DESC);
          struct.ase.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 getGatewayResourceProfile_resultTupleSchemeFactory implements SchemeFactory {
      public getGatewayResourceProfile_resultTupleScheme getScheme() {
        return new getGatewayResourceProfile_resultTupleScheme();
      }
    }

    private static class getGatewayResourceProfile_resultTupleScheme extends TupleScheme<getGatewayResourceProfile_result> {

      @Override
      public void write(org.apache.thrift.protocol.TProtocol prot, getGatewayResourceProfile_result struct) throws org.apache.thrift.TException {
        TTupleProtocol oprot = (TTupleProtocol) prot;
        BitSet optionals = new BitSet();
        if (struct.isSetSuccess()) {
          optionals.set(0);
        }
        if (struct.isSetIre()) {
          optionals.set(1);
        }
        if (struct.isSetAce()) {
          optionals.set(2);
        }
        if (struct.isSetAse()) {
          optionals.set(3);
        }
        if (struct.isSetAe()) {
          optionals.set(4);
        }
        oprot.writeBitSet(optionals, 5);
        if (struct.isSetSuccess()) {
          struct.success.write(oprot);
        }
        if (struct.isSetIre()) {
          struct.ire.write(oprot);
        }
        if (struct.isSetAce()) {
          struct.ace.write(oprot);
        }
        if (struct.isSetAse()) {
          struct.ase.write(oprot);
        }
        if (struct.isSetAe()) {
          struct.ae.write(oprot);
        }
      }

      @Override
      public void read(org.apache.thrift.protocol.TProtocol prot, getGatewayResourceProfile_result struct) throws org.apache.thrift.TException {
        TTupleProtocol iprot = (TTupleProtocol) prot;
        BitSet incoming = iprot.readBitSet(5);
        if (incoming.get(0)) {
          struct.success = new org.apache.airavata.model.appcatalog.gatewayprofile.GatewayResourceProfile();
          struct.success.read(iprot);
          struct.setSuccessIsSet(true);
        }
        if (incoming.get(1)) {
          struct.ire = new org.apache.airavata.model.error.InvalidRequestException();
          struct.ire.read(iprot);
          struct.setIreIsSet(true);
        }
        if (incoming.get(2)) {
          struct.ace = new org.apache.airavata.model.error.AiravataClientException();
          struct.ace.read(iprot);
          struct.setAceIsSet(true);
        }
        if (incoming.get(3)) {
          struct.ase = new org.apache.airavata.model.error.AiravataSystemException();
          struct.ase.read(iprot);
          struct.setAseIsSet(true);
        }
        if (incoming.get(4)) {
          struct.ae = new org.apache.airavata.model.error.AuthorizationException();
          struct.ae.read(iprot);
          struct.setAeIsSet(true);
        }
      }
    }

  }

  public static class updateGatewayResourceProfile_args implements org.apache.thrift.TBase<updateGatewayResourceProfile_args, updateGatewayResourceProfile_args._Fields>, java.io.Serializable, Cloneable, Comparable<updateGatewayResourceProfile_args>   {
    private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("updateGatewayResourceProfile_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.protocol.TField GATEWAY_RESOURCE_PROFILE_FIELD_DESC = new org.apache.thrift.protocol.TField("gatewayResourceProfile", org.apache.thrift.protocol.TType.STRUCT, (short)3);

    private static final Map<Class<? extends IScheme>, SchemeFactory> schemes = new HashMap<Class<? extends IScheme>, SchemeFactory>();
    static {
      schemes.put(StandardScheme.class, new updateGatewayResourceProfile_argsStandardSchemeFactory());
      schemes.put(TupleScheme.class, new updateGatewayResourceProfile_argsTupleSchemeFactory());
    }

    public org.apache.airavata.model.security.AuthzToken authzToken; // required
    public String gatewayID; // required
    public org.apache.airavata.model.appcatalog.gatewayprofile.GatewayResourceProfile gatewayResourceProfile; // required

    /** 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"),
      GATEWAY_RESOURCE_PROFILE((short)3, "gatewayResourceProfile");

      private static final Map<String, _Fields> byName = new HashMap<String, _Fields>();

      static {
        for (_Fields field : EnumSet.allOf(_Fields.class)) {
          byName.put(field.getFieldName(), field);
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, or null if its not found.
       */
      public static _Fields findByThriftId(int fieldId) {
        switch(fieldId) {
          case 1: // AUTHZ_TOKEN
            return AUTHZ_TOKEN;
          case 2: // GATEWAY_ID
            return GATEWAY_ID;
          case 3: // GATEWAY_RESOURCE_PROFILE
            return GATEWAY_RESOURCE_PROFILE;
          default:
            return null;
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, throwing an exception
       * if it is not found.
       */
      public static _Fields findByThriftIdOrThrow(int fieldId) {
        _Fields fields = findByThriftId(fieldId);
        if (fields == null) throw new IllegalArgumentException("Field " + fieldId + " doesn't exist!");
        return fields;
      }

      /**
       * Find the _Fields constant that matches name, or null if its not found.
       */
      public static _Fields findByName(String name) {
        return byName.get(name);
      }

      private final short _thriftId;
      private final String _fieldName;

      _Fields(short thriftId, String fieldName) {
        _thriftId = thriftId;
        _fieldName = fieldName;
      }

      public short getThriftFieldId() {
        return _thriftId;
      }

      public String getFieldName() {
        return _fieldName;
      }
    }

    // isset id assignments
    public static final Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
    static {
      Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new EnumMap<_Fields, org.apache.thrift.meta_data.FieldMetaData>(_Fields.class);
      tmpMap.put(_Fields.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)));
      tmpMap.put(_Fields.GATEWAY_RESOURCE_PROFILE, new org.apache.thrift.meta_data.FieldMetaData("gatewayResourceProfile", org.apache.thrift.TFieldRequirementType.REQUIRED, 
          new org.apache.thrift.meta_data.StructMetaData(org.apache.thrift.protocol.TType.STRUCT, org.apache.airavata.model.appcatalog.gatewayprofile.GatewayResourceProfile.class)));
      metaDataMap = Collections.unmodifiableMap(tmpMap);
      org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(updateGatewayResourceProfile_args.class, metaDataMap);
    }

    public updateGatewayResourceProfile_args() {
    }

    public updateGatewayResourceProfile_args(
      org.apache.airavata.model.security.AuthzToken authzToken,
      String gatewayID,
      org.apache.airavata.model.appcatalog.gatewayprofile.GatewayResourceProfile gatewayResourceProfile)
    {
      this();
      this.authzToken = authzToken;
      this.gatewayID = gatewayID;
      this.gatewayResourceProfile = gatewayResourceProfile;
    }

    /**
     * Performs a deep copy on <i>other</i>.
     */
    public updateGatewayResourceProfile_args(updateGatewayResourceProfile_args other) {
      if (other.isSetAuthzToken()) {
        this.authzToken = new org.apache.airavata.model.security.AuthzToken(other.authzToken);
      }
      if (other.isSetGatewayID()) {
        this.gatewayID = other.gatewayID;
      }
      if (other.isSetGatewayResourceProfile()) {
        this.gatewayResourceProfile = new org.apache.airavata.model.appcatalog.gatewayprofile.GatewayResourceProfile(other.gatewayResourceProfile);
      }
    }

    public updateGatewayResourceProfile_args deepCopy() {
      return new updateGatewayResourceProfile_args(this);
    }

    @Override
    public void clear() {
      this.authzToken = null;
      this.gatewayID = null;
      this.gatewayResourceProfile = null;
    }

    public org.apache.airavata.model.security.AuthzToken getAuthzToken() {
      return this.authzToken;
    }

    public updateGatewayResourceProfile_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 String getGatewayID() {
      return this.gatewayID;
    }

    public updateGatewayResourceProfile_args setGatewayID(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 org.apache.airavata.model.appcatalog.gatewayprofile.GatewayResourceProfile getGatewayResourceProfile() {
      return this.gatewayResourceProfile;
    }

    public updateGatewayResourceProfile_args setGatewayResourceProfile(org.apache.airavata.model.appcatalog.gatewayprofile.GatewayResourceProfile gatewayResourceProfile) {
      this.gatewayResourceProfile = gatewayResourceProfile;
      return this;
    }

    public void unsetGatewayResourceProfile() {
      this.gatewayResourceProfile = null;
    }

    /** Returns true if field gatewayResourceProfile is set (has been assigned a value) and false otherwise */
    public boolean isSetGatewayResourceProfile() {
      return this.gatewayResourceProfile != null;
    }

    public void setGatewayResourceProfileIsSet(boolean value) {
      if (!value) {
        this.gatewayResourceProfile = null;
      }
    }

    public void setFieldValue(_Fields field, 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((String)value);
        }
        break;

      case GATEWAY_RESOURCE_PROFILE:
        if (value == null) {
          unsetGatewayResourceProfile();
        } else {
          setGatewayResourceProfile((org.apache.airavata.model.appcatalog.gatewayprofile.GatewayResourceProfile)value);
        }
        break;

      }
    }

    public Object getFieldValue(_Fields field) {
      switch (field) {
      case AUTHZ_TOKEN:
        return getAuthzToken();

      case GATEWAY_ID:
        return getGatewayID();

      case GATEWAY_RESOURCE_PROFILE:
        return getGatewayResourceProfile();

      }
      throw new IllegalStateException();
    }

    /** Returns true if field corresponding to fieldID is set (has been assigned a value) and false otherwise */
    public boolean isSet(_Fields field) {
      if (field == null) {
        throw new IllegalArgumentException();
      }

      switch (field) {
      case AUTHZ_TOKEN:
        return isSetAuthzToken();
      case GATEWAY_ID:
        return isSetGatewayID();
      case GATEWAY_RESOURCE_PROFILE:
        return isSetGatewayResourceProfile();
      }
      throw new IllegalStateException();
    }

    @Override
    public boolean equals(Object that) {
      if (that == null)
        return false;
      if (that instanceof updateGatewayResourceProfile_args)
        return this.equals((updateGatewayResourceProfile_args)that);
      return false;
    }

    public boolean equals(updateGatewayResourceProfile_args that) {
      if (that == null)
        return false;

      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;
      }

      boolean this_present_gatewayResourceProfile = true && this.isSetGatewayResourceProfile();
      boolean that_present_gatewayResourceProfile = true && that.isSetGatewayResourceProfile();
      if (this_present_gatewayResourceProfile || that_present_gatewayResourceProfile) {
        if (!(this_present_gatewayResourceProfile && that_present_gatewayResourceProfile))
          return false;
        if (!this.gatewayResourceProfile.equals(that.gatewayResourceProfile))
          return false;
      }

      return true;
    }

    @Override
    public int hashCode() {
      List<Object> list = new ArrayList<Object>();

      boolean present_authzToken = true && (isSetAuthzToken());
      list.add(present_authzToken);
      if (present_authzToken)
        list.add(authzToken);

      boolean present_gatewayID = true && (isSetGatewayID());
      list.add(present_gatewayID);
      if (present_gatewayID)
        list.add(gatewayID);

      boolean present_gatewayResourceProfile = true && (isSetGatewayResourceProfile());
      list.add(present_gatewayResourceProfile);
      if (present_gatewayResourceProfile)
        list.add(gatewayResourceProfile);

      return list.hashCode();
    }

    @Override
    public int compareTo(updateGatewayResourceProfile_args other) {
      if (!getClass().equals(other.getClass())) {
        return getClass().getName().compareTo(other.getClass().getName());
      }

      int lastComparison = 0;

      lastComparison = 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 = 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;
        }
      }
      lastComparison = Boolean.valueOf(isSetGatewayResourceProfile()).compareTo(other.isSetGatewayResourceProfile());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetGatewayResourceProfile()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.gatewayResourceProfile, other.gatewayResourceProfile);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      return 0;
    }

    public _Fields fieldForId(int fieldId) {
      return _Fields.findByThriftId(fieldId);
    }

    public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
      schemes.get(iprot.getScheme()).getScheme().read(iprot, this);
    }

    public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException {
      schemes.get(oprot.getScheme()).getScheme().write(oprot, this);
    }

    @Override
    public String toString() {
      StringBuilder sb = new StringBuilder("updateGatewayResourceProfile_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;
      if (!first) sb.append(", ");
      sb.append("gatewayResourceProfile:");
      if (this.gatewayResourceProfile == null) {
        sb.append("null");
      } else {
        sb.append(this.gatewayResourceProfile);
      }
      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());
      }
      if (gatewayResourceProfile == null) {
        throw new org.apache.thrift.protocol.TProtocolException("Required field 'gatewayResourceProfile' was not present! Struct: " + toString());
      }
      // check for sub-struct validity
      if (authzToken != null) {
        authzToken.validate();
      }
      if (gatewayResourceProfile != null) {
        gatewayResourceProfile.validate();
      }
    }

    private void writeObject(java.io.ObjectOutputStream out) throws java.io.IOException {
      try {
        write(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(out)));
      } catch (org.apache.thrift.TException te) {
        throw new java.io.IOException(te);
      }
    }

    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, ClassNotFoundException {
      try {
        read(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(in)));
      } catch (org.apache.thrift.TException te) {
        throw new java.io.IOException(te);
      }
    }

    private static class updateGatewayResourceProfile_argsStandardSchemeFactory implements SchemeFactory {
      public updateGatewayResourceProfile_argsStandardScheme getScheme() {
        return new updateGatewayResourceProfile_argsStandardScheme();
      }
    }

    private static class updateGatewayResourceProfile_argsStandardScheme extends StandardScheme<updateGatewayResourceProfile_args> {

      public void read(org.apache.thrift.protocol.TProtocol iprot, updateGatewayResourceProfile_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;
            case 3: // GATEWAY_RESOURCE_PROFILE
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.gatewayResourceProfile = new org.apache.airavata.model.appcatalog.gatewayprofile.GatewayResourceProfile();
                struct.gatewayResourceProfile.read(iprot);
                struct.setGatewayResourceProfileIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            default:
              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
          }
          iprot.readFieldEnd();
        }
        iprot.readStructEnd();

        // check for required fields of primitive type, which can't be checked in the validate method
        struct.validate();
      }

      public void write(org.apache.thrift.protocol.TProtocol oprot, updateGatewayResourceProfile_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();
        }
        if (struct.gatewayResourceProfile != null) {
          oprot.writeFieldBegin(GATEWAY_RESOURCE_PROFILE_FIELD_DESC);
          struct.gatewayResourceProfile.write(oprot);
          oprot.writeFieldEnd();
        }
        oprot.writeFieldStop();
        oprot.writeStructEnd();
      }

    }

    private static class updateGatewayResourceProfile_argsTupleSchemeFactory implements SchemeFactory {
      public updateGatewayResourceProfile_argsTupleScheme getScheme() {
        return new updateGatewayResourceProfile_argsTupleScheme();
      }
    }

    private static class updateGatewayResourceProfile_argsTupleScheme extends TupleScheme<updateGatewayResourceProfile_args> {

      @Override
      public void write(org.apache.thrift.protocol.TProtocol prot, updateGatewayResourceProfile_args struct) throws org.apache.thrift.TException {
        TTupleProtocol oprot = (TTupleProtocol) prot;
        struct.authzToken.write(oprot);
        oprot.writeString(struct.gatewayID);
        struct.gatewayResourceProfile.write(oprot);
      }

      @Override
      public void read(org.apache.thrift.protocol.TProtocol prot, updateGatewayResourceProfile_args struct) throws org.apache.thrift.TException {
        TTupleProtocol iprot = (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);
        struct.gatewayResourceProfile = new org.apache.airavata.model.appcatalog.gatewayprofile.GatewayResourceProfile();
        struct.gatewayResourceProfile.read(iprot);
        struct.setGatewayResourceProfileIsSet(true);
      }
    }

  }

  public static class updateGatewayResourceProfile_result implements org.apache.thrift.TBase<updateGatewayResourceProfile_result, updateGatewayResourceProfile_result._Fields>, java.io.Serializable, Cloneable, Comparable<updateGatewayResourceProfile_result>   {
    private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("updateGatewayResourceProfile_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 IRE_FIELD_DESC = new org.apache.thrift.protocol.TField("ire", org.apache.thrift.protocol.TType.STRUCT, (short)1);
    private static final org.apache.thrift.protocol.TField ACE_FIELD_DESC = new org.apache.thrift.protocol.TField("ace", org.apache.thrift.protocol.TType.STRUCT, (short)2);
    private static final org.apache.thrift.protocol.TField ASE_FIELD_DESC = new org.apache.thrift.protocol.TField("ase", org.apache.thrift.protocol.TType.STRUCT, (short)3);
    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)4);

    private static final Map<Class<? extends IScheme>, SchemeFactory> schemes = new HashMap<Class<? extends IScheme>, SchemeFactory>();
    static {
      schemes.put(StandardScheme.class, new updateGatewayResourceProfile_resultStandardSchemeFactory());
      schemes.put(TupleScheme.class, new updateGatewayResourceProfile_resultTupleSchemeFactory());
    }

    public boolean success; // required
    public org.apache.airavata.model.error.InvalidRequestException ire; // required
    public org.apache.airavata.model.error.AiravataClientException ace; // required
    public org.apache.airavata.model.error.AiravataSystemException ase; // 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"),
      IRE((short)1, "ire"),
      ACE((short)2, "ace"),
      ASE((short)3, "ase"),
      AE((short)4, "ae");

      private static final Map<String, _Fields> byName = new HashMap<String, _Fields>();

      static {
        for (_Fields field : EnumSet.allOf(_Fields.class)) {
          byName.put(field.getFieldName(), field);
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, or null if its not found.
       */
      public static _Fields findByThriftId(int fieldId) {
        switch(fieldId) {
          case 0: // SUCCESS
            return SUCCESS;
          case 1: // IRE
            return IRE;
          case 2: // ACE
            return ACE;
          case 3: // ASE
            return ASE;
          case 4: // 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 IllegalArgumentException("Field " + fieldId + " doesn't exist!");
        return fields;
      }

      /**
       * Find the _Fields constant that matches name, or null if its not found.
       */
      public static _Fields findByName(String name) {
        return byName.get(name);
      }

      private final short _thriftId;
      private final String _fieldName;

      _Fields(short thriftId, String fieldName) {
        _thriftId = thriftId;
        _fieldName = fieldName;
      }

      public short getThriftFieldId() {
        return _thriftId;
      }

      public String getFieldName() {
        return _fieldName;
      }
    }

    // isset id assignments
    private static final int __SUCCESS_ISSET_ID = 0;
    private byte __isset_bitfield = 0;
    public static final Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
    static {
      Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new EnumMap<_Fields, org.apache.thrift.meta_data.FieldMetaData>(_Fields.class);
      tmpMap.put(_Fields.SUCCESS, new org.apache.thrift.meta_data.FieldMetaData("success", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.BOOL)));
      tmpMap.put(_Fields.IRE, new org.apache.thrift.meta_data.FieldMetaData("ire", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRUCT)));
      tmpMap.put(_Fields.ACE, new org.apache.thrift.meta_data.FieldMetaData("ace", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRUCT)));
      tmpMap.put(_Fields.ASE, new org.apache.thrift.meta_data.FieldMetaData("ase", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRUCT)));
      tmpMap.put(_Fields.AE, new org.apache.thrift.meta_data.FieldMetaData("ae", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRUCT)));
      metaDataMap = Collections.unmodifiableMap(tmpMap);
      org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(updateGatewayResourceProfile_result.class, metaDataMap);
    }

    public updateGatewayResourceProfile_result() {
    }

    public updateGatewayResourceProfile_result(
      boolean success,
      org.apache.airavata.model.error.InvalidRequestException ire,
      org.apache.airavata.model.error.AiravataClientException ace,
      org.apache.airavata.model.error.AiravataSystemException ase,
      org.apache.airavata.model.error.AuthorizationException ae)
    {
      this();
      this.success = success;
      setSuccessIsSet(true);
      this.ire = ire;
      this.ace = ace;
      this.ase = ase;
      this.ae = ae;
    }

    /**
     * Performs a deep copy on <i>other</i>.
     */
    public updateGatewayResourceProfile_result(updateGatewayResourceProfile_result other) {
      __isset_bitfield = other.__isset_bitfield;
      this.success = other.success;
      if (other.isSetIre()) {
        this.ire = new org.apache.airavata.model.error.InvalidRequestException(other.ire);
      }
      if (other.isSetAce()) {
        this.ace = new org.apache.airavata.model.error.AiravataClientException(other.ace);
      }
      if (other.isSetAse()) {
        this.ase = new org.apache.airavata.model.error.AiravataSystemException(other.ase);
      }
      if (other.isSetAe()) {
        this.ae = new org.apache.airavata.model.error.AuthorizationException(other.ae);
      }
    }

    public updateGatewayResourceProfile_result deepCopy() {
      return new updateGatewayResourceProfile_result(this);
    }

    @Override
    public void clear() {
      setSuccessIsSet(false);
      this.success = false;
      this.ire = null;
      this.ace = null;
      this.ase = null;
      this.ae = null;
    }

    public boolean isSuccess() {
      return this.success;
    }

    public updateGatewayResourceProfile_result setSuccess(boolean success) {
      this.success = success;
      setSuccessIsSet(true);
      return this;
    }

    public void unsetSuccess() {
      __isset_bitfield = EncodingUtils.clearBit(__isset_bitfield, __SUCCESS_ISSET_ID);
    }

    /** Returns true if field success is set (has been assigned a value) and false otherwise */
    public boolean isSetSuccess() {
      return EncodingUtils.testBit(__isset_bitfield, __SUCCESS_ISSET_ID);
    }

    public void setSuccessIsSet(boolean value) {
      __isset_bitfield = EncodingUtils.setBit(__isset_bitfield, __SUCCESS_ISSET_ID, value);
    }

    public org.apache.airavata.model.error.InvalidRequestException getIre() {
      return this.ire;
    }

    public updateGatewayResourceProfile_result setIre(org.apache.airavata.model.error.InvalidRequestException ire) {
      this.ire = ire;
      return this;
    }

    public void unsetIre() {
      this.ire = null;
    }

    /** Returns true if field ire is set (has been assigned a value) and false otherwise */
    public boolean isSetIre() {
      return this.ire != null;
    }

    public void setIreIsSet(boolean value) {
      if (!value) {
        this.ire = null;
      }
    }

    public org.apache.airavata.model.error.AiravataClientException getAce() {
      return this.ace;
    }

    public updateGatewayResourceProfile_result setAce(org.apache.airavata.model.error.AiravataClientException ace) {
      this.ace = ace;
      return this;
    }

    public void unsetAce() {
      this.ace = null;
    }

    /** Returns true if field ace is set (has been assigned a value) and false otherwise */
    public boolean isSetAce() {
      return this.ace != null;
    }

    public void setAceIsSet(boolean value) {
      if (!value) {
        this.ace = null;
      }
    }

    public org.apache.airavata.model.error.AiravataSystemException getAse() {
      return this.ase;
    }

    public updateGatewayResourceProfile_result setAse(org.apache.airavata.model.error.AiravataSystemException ase) {
      this.ase = ase;
      return this;
    }

    public void unsetAse() {
      this.ase = null;
    }

    /** Returns true if field ase is set (has been assigned a value) and false otherwise */
    public boolean isSetAse() {
      return this.ase != null;
    }

    public void setAseIsSet(boolean value) {
      if (!value) {
        this.ase = null;
      }
    }

    public org.apache.airavata.model.error.AuthorizationException getAe() {
      return this.ae;
    }

    public updateGatewayResourceProfile_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, Object value) {
      switch (field) {
      case SUCCESS:
        if (value == null) {
          unsetSuccess();
        } else {
          setSuccess((Boolean)value);
        }
        break;

      case IRE:
        if (value == null) {
          unsetIre();
        } else {
          setIre((org.apache.airavata.model.error.InvalidRequestException)value);
        }
        break;

      case ACE:
        if (value == null) {
          unsetAce();
        } else {
          setAce((org.apache.airavata.model.error.AiravataClientException)value);
        }
        break;

      case ASE:
        if (value == null) {
          unsetAse();
        } else {
          setAse((org.apache.airavata.model.error.AiravataSystemException)value);
        }
        break;

      case AE:
        if (value == null) {
          unsetAe();
        } else {
          setAe((org.apache.airavata.model.error.AuthorizationException)value);
        }
        break;

      }
    }

    public Object getFieldValue(_Fields field) {
      switch (field) {
      case SUCCESS:
        return Boolean.valueOf(isSuccess());

      case IRE:
        return getIre();

      case ACE:
        return getAce();

      case ASE:
        return getAse();

      case AE:
        return getAe();

      }
      throw new IllegalStateException();
    }

    /** Returns true if field corresponding to fieldID is set (has been assigned a value) and false otherwise */
    public boolean isSet(_Fields field) {
      if (field == null) {
        throw new IllegalArgumentException();
      }

      switch (field) {
      case SUCCESS:
        return isSetSuccess();
      case IRE:
        return isSetIre();
      case ACE:
        return isSetAce();
      case ASE:
        return isSetAse();
      case AE:
        return isSetAe();
      }
      throw new IllegalStateException();
    }

    @Override
    public boolean equals(Object that) {
      if (that == null)
        return false;
      if (that instanceof updateGatewayResourceProfile_result)
        return this.equals((updateGatewayResourceProfile_result)that);
      return false;
    }

    public boolean equals(updateGatewayResourceProfile_result that) {
      if (that == null)
        return false;

      boolean this_present_success = true;
      boolean that_present_success = true;
      if (this_present_success || that_present_success) {
        if (!(this_present_success && that_present_success))
          return false;
        if (this.success != that.success)
          return false;
      }

      boolean this_present_ire = true && this.isSetIre();
      boolean that_present_ire = true && that.isSetIre();
      if (this_present_ire || that_present_ire) {
        if (!(this_present_ire && that_present_ire))
          return false;
        if (!this.ire.equals(that.ire))
          return false;
      }

      boolean this_present_ace = true && this.isSetAce();
      boolean that_present_ace = true && that.isSetAce();
      if (this_present_ace || that_present_ace) {
        if (!(this_present_ace && that_present_ace))
          return false;
        if (!this.ace.equals(that.ace))
          return false;
      }

      boolean this_present_ase = true && this.isSetAse();
      boolean that_present_ase = true && that.isSetAse();
      if (this_present_ase || that_present_ase) {
        if (!(this_present_ase && that_present_ase))
          return false;
        if (!this.ase.equals(that.ase))
          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() {
      List<Object> list = new ArrayList<Object>();

      boolean present_success = true;
      list.add(present_success);
      if (present_success)
        list.add(success);

      boolean present_ire = true && (isSetIre());
      list.add(present_ire);
      if (present_ire)
        list.add(ire);

      boolean present_ace = true && (isSetAce());
      list.add(present_ace);
      if (present_ace)
        list.add(ace);

      boolean present_ase = true && (isSetAse());
      list.add(present_ase);
      if (present_ase)
        list.add(ase);

      boolean present_ae = true && (isSetAe());
      list.add(present_ae);
      if (present_ae)
        list.add(ae);

      return list.hashCode();
    }

    @Override
    public int compareTo(updateGatewayResourceProfile_result other) {
      if (!getClass().equals(other.getClass())) {
        return getClass().getName().compareTo(other.getClass().getName());
      }

      int lastComparison = 0;

      lastComparison = Boolean.valueOf(isSetSuccess()).compareTo(other.isSetSuccess());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetSuccess()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.success, other.success);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = Boolean.valueOf(isSetIre()).compareTo(other.isSetIre());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetIre()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.ire, other.ire);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = Boolean.valueOf(isSetAce()).compareTo(other.isSetAce());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetAce()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.ace, other.ace);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = Boolean.valueOf(isSetAse()).compareTo(other.isSetAse());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetAse()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.ase, other.ase);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = 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 {
      schemes.get(iprot.getScheme()).getScheme().read(iprot, this);
    }

    public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException {
      schemes.get(oprot.getScheme()).getScheme().write(oprot, this);
      }

    @Override
    public String toString() {
      StringBuilder sb = new StringBuilder("updateGatewayResourceProfile_result(");
      boolean first = true;

      sb.append("success:");
      sb.append(this.success);
      first = false;
      if (!first) sb.append(", ");
      sb.append("ire:");
      if (this.ire == null) {
        sb.append("null");
      } else {
        sb.append(this.ire);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("ace:");
      if (this.ace == null) {
        sb.append("null");
      } else {
        sb.append(this.ace);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("ase:");
      if (this.ase == null) {
        sb.append("null");
      } else {
        sb.append(this.ase);
      }
      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, 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 updateGatewayResourceProfile_resultStandardSchemeFactory implements SchemeFactory {
      public updateGatewayResourceProfile_resultStandardScheme getScheme() {
        return new updateGatewayResourceProfile_resultStandardScheme();
      }
    }

    private static class updateGatewayResourceProfile_resultStandardScheme extends StandardScheme<updateGatewayResourceProfile_result> {

      public void read(org.apache.thrift.protocol.TProtocol iprot, updateGatewayResourceProfile_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: // IRE
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.ire = new org.apache.airavata.model.error.InvalidRequestException();
                struct.ire.read(iprot);
                struct.setIreIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 2: // ACE
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.ace = new org.apache.airavata.model.error.AiravataClientException();
                struct.ace.read(iprot);
                struct.setAceIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 3: // ASE
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.ase = new org.apache.airavata.model.error.AiravataSystemException();
                struct.ase.read(iprot);
                struct.setAseIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 4: // 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, updateGatewayResourceProfile_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.ire != null) {
          oprot.writeFieldBegin(IRE_FIELD_DESC);
          struct.ire.write(oprot);
          oprot.writeFieldEnd();
        }
        if (struct.ace != null) {
          oprot.writeFieldBegin(ACE_FIELD_DESC);
          struct.ace.write(oprot);
          oprot.writeFieldEnd();
        }
        if (struct.ase != null) {
          oprot.writeFieldBegin(ASE_FIELD_DESC);
          struct.ase.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 updateGatewayResourceProfile_resultTupleSchemeFactory implements SchemeFactory {
      public updateGatewayResourceProfile_resultTupleScheme getScheme() {
        return new updateGatewayResourceProfile_resultTupleScheme();
      }
    }

    private static class updateGatewayResourceProfile_resultTupleScheme extends TupleScheme<updateGatewayResourceProfile_result> {

      @Override
      public void write(org.apache.thrift.protocol.TProtocol prot, updateGatewayResourceProfile_result struct) throws org.apache.thrift.TException {
        TTupleProtocol oprot = (TTupleProtocol) prot;
        BitSet optionals = new BitSet();
        if (struct.isSetSuccess()) {
          optionals.set(0);
        }
        if (struct.isSetIre()) {
          optionals.set(1);
        }
        if (struct.isSetAce()) {
          optionals.set(2);
        }
        if (struct.isSetAse()) {
          optionals.set(3);
        }
        if (struct.isSetAe()) {
          optionals.set(4);
        }
        oprot.writeBitSet(optionals, 5);
        if (struct.isSetSuccess()) {
          oprot.writeBool(struct.success);
        }
        if (struct.isSetIre()) {
          struct.ire.write(oprot);
        }
        if (struct.isSetAce()) {
          struct.ace.write(oprot);
        }
        if (struct.isSetAse()) {
          struct.ase.write(oprot);
        }
        if (struct.isSetAe()) {
          struct.ae.write(oprot);
        }
      }

      @Override
      public void read(org.apache.thrift.protocol.TProtocol prot, updateGatewayResourceProfile_result struct) throws org.apache.thrift.TException {
        TTupleProtocol iprot = (TTupleProtocol) prot;
        BitSet incoming = iprot.readBitSet(5);
        if (incoming.get(0)) {
          struct.success = iprot.readBool();
          struct.setSuccessIsSet(true);
        }
        if (incoming.get(1)) {
          struct.ire = new org.apache.airavata.model.error.InvalidRequestException();
          struct.ire.read(iprot);
          struct.setIreIsSet(true);
        }
        if (incoming.get(2)) {
          struct.ace = new org.apache.airavata.model.error.AiravataClientException();
          struct.ace.read(iprot);
          struct.setAceIsSet(true);
        }
        if (incoming.get(3)) {
          struct.ase = new org.apache.airavata.model.error.AiravataSystemException();
          struct.ase.read(iprot);
          struct.setAseIsSet(true);
        }
        if (incoming.get(4)) {
          struct.ae = new org.apache.airavata.model.error.AuthorizationException();
          struct.ae.read(iprot);
          struct.setAeIsSet(true);
        }
      }
    }

  }

  public static class deleteGatewayResourceProfile_args implements org.apache.thrift.TBase<deleteGatewayResourceProfile_args, deleteGatewayResourceProfile_args._Fields>, java.io.Serializable, Cloneable, Comparable<deleteGatewayResourceProfile_args>   {
    private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("deleteGatewayResourceProfile_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 Map<Class<? extends IScheme>, SchemeFactory> schemes = new HashMap<Class<? extends IScheme>, SchemeFactory>();
    static {
      schemes.put(StandardScheme.class, new deleteGatewayResourceProfile_argsStandardSchemeFactory());
      schemes.put(TupleScheme.class, new deleteGatewayResourceProfile_argsTupleSchemeFactory());
    }

    public org.apache.airavata.model.security.AuthzToken authzToken; // required
    public 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 Map<String, _Fields> byName = new HashMap<String, _Fields>();

      static {
        for (_Fields field : EnumSet.allOf(_Fields.class)) {
          byName.put(field.getFieldName(), field);
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, or null if its not found.
       */
      public static _Fields findByThriftId(int fieldId) {
        switch(fieldId) {
          case 1: // 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 IllegalArgumentException("Field " + fieldId + " doesn't exist!");
        return fields;
      }

      /**
       * Find the _Fields constant that matches name, or null if its not found.
       */
      public static _Fields findByName(String name) {
        return byName.get(name);
      }

      private final short _thriftId;
      private final String _fieldName;

      _Fields(short thriftId, String fieldName) {
        _thriftId = thriftId;
        _fieldName = fieldName;
      }

      public short getThriftFieldId() {
        return _thriftId;
      }

      public String getFieldName() {
        return _fieldName;
      }
    }

    // isset id assignments
    public static final Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
    static {
      Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new EnumMap<_Fields, org.apache.thrift.meta_data.FieldMetaData>(_Fields.class);
      tmpMap.put(_Fields.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 = Collections.unmodifiableMap(tmpMap);
      org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(deleteGatewayResourceProfile_args.class, metaDataMap);
    }

    public deleteGatewayResourceProfile_args() {
    }

    public deleteGatewayResourceProfile_args(
      org.apache.airavata.model.security.AuthzToken authzToken,
      String gatewayID)
    {
      this();
      this.authzToken = authzToken;
      this.gatewayID = gatewayID;
    }

    /**
     * Performs a deep copy on <i>other</i>.
     */
    public deleteGatewayResourceProfile_args(deleteGatewayResourceProfile_args other) {
      if (other.isSetAuthzToken()) {
        this.authzToken = new org.apache.airavata.model.security.AuthzToken(other.authzToken);
      }
      if (other.isSetGatewayID()) {
        this.gatewayID = other.gatewayID;
      }
    }

    public deleteGatewayResourceProfile_args deepCopy() {
      return new deleteGatewayResourceProfile_args(this);
    }

    @Override
    public void clear() {
      this.authzToken = null;
      this.gatewayID = null;
    }

    public org.apache.airavata.model.security.AuthzToken getAuthzToken() {
      return this.authzToken;
    }

    public deleteGatewayResourceProfile_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 String getGatewayID() {
      return this.gatewayID;
    }

    public deleteGatewayResourceProfile_args setGatewayID(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, 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((String)value);
        }
        break;

      }
    }

    public Object getFieldValue(_Fields field) {
      switch (field) {
      case AUTHZ_TOKEN:
        return getAuthzToken();

      case GATEWAY_ID:
        return getGatewayID();

      }
      throw new IllegalStateException();
    }

    /** Returns true if field corresponding to fieldID is set (has been assigned a value) and false otherwise */
    public boolean isSet(_Fields field) {
      if (field == null) {
        throw new IllegalArgumentException();
      }

      switch (field) {
      case AUTHZ_TOKEN:
        return isSetAuthzToken();
      case GATEWAY_ID:
        return isSetGatewayID();
      }
      throw new IllegalStateException();
    }

    @Override
    public boolean equals(Object that) {
      if (that == null)
        return false;
      if (that instanceof deleteGatewayResourceProfile_args)
        return this.equals((deleteGatewayResourceProfile_args)that);
      return false;
    }

    public boolean equals(deleteGatewayResourceProfile_args that) {
      if (that == null)
        return false;

      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() {
      List<Object> list = new ArrayList<Object>();

      boolean present_authzToken = true && (isSetAuthzToken());
      list.add(present_authzToken);
      if (present_authzToken)
        list.add(authzToken);

      boolean present_gatewayID = true && (isSetGatewayID());
      list.add(present_gatewayID);
      if (present_gatewayID)
        list.add(gatewayID);

      return list.hashCode();
    }

    @Override
    public int compareTo(deleteGatewayResourceProfile_args other) {
      if (!getClass().equals(other.getClass())) {
        return getClass().getName().compareTo(other.getClass().getName());
      }

      int lastComparison = 0;

      lastComparison = 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 = 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 {
      schemes.get(iprot.getScheme()).getScheme().read(iprot, this);
    }

    public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException {
      schemes.get(oprot.getScheme()).getScheme().write(oprot, this);
    }

    @Override
    public String toString() {
      StringBuilder sb = new StringBuilder("deleteGatewayResourceProfile_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, 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 deleteGatewayResourceProfile_argsStandardSchemeFactory implements SchemeFactory {
      public deleteGatewayResourceProfile_argsStandardScheme getScheme() {
        return new deleteGatewayResourceProfile_argsStandardScheme();
      }
    }

    private static class deleteGatewayResourceProfile_argsStandardScheme extends StandardScheme<deleteGatewayResourceProfile_args> {

      public void read(org.apache.thrift.protocol.TProtocol iprot, deleteGatewayResourceProfile_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, deleteGatewayResourceProfile_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 deleteGatewayResourceProfile_argsTupleSchemeFactory implements SchemeFactory {
      public deleteGatewayResourceProfile_argsTupleScheme getScheme() {
        return new deleteGatewayResourceProfile_argsTupleScheme();
      }
    }

    private static class deleteGatewayResourceProfile_argsTupleScheme extends TupleScheme<deleteGatewayResourceProfile_args> {

      @Override
      public void write(org.apache.thrift.protocol.TProtocol prot, deleteGatewayResourceProfile_args struct) throws org.apache.thrift.TException {
        TTupleProtocol oprot = (TTupleProtocol) prot;
        struct.authzToken.write(oprot);
        oprot.writeString(struct.gatewayID);
      }

      @Override
      public void read(org.apache.thrift.protocol.TProtocol prot, deleteGatewayResourceProfile_args struct) throws org.apache.thrift.TException {
        TTupleProtocol iprot = (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);
      }
    }

  }

  public static class deleteGatewayResourceProfile_result implements org.apache.thrift.TBase<deleteGatewayResourceProfile_result, deleteGatewayResourceProfile_result._Fields>, java.io.Serializable, Cloneable, Comparable<deleteGatewayResourceProfile_result>   {
    private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("deleteGatewayResourceProfile_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 IRE_FIELD_DESC = new org.apache.thrift.protocol.TField("ire", org.apache.thrift.protocol.TType.STRUCT, (short)1);
    private static final org.apache.thrift.protocol.TField ACE_FIELD_DESC = new org.apache.thrift.protocol.TField("ace", org.apache.thrift.protocol.TType.STRUCT, (short)2);
    private static final org.apache.thrift.protocol.TField ASE_FIELD_DESC = new org.apache.thrift.protocol.TField("ase", org.apache.thrift.protocol.TType.STRUCT, (short)3);
    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)4);

    private static final Map<Class<? extends IScheme>, SchemeFactory> schemes = new HashMap<Class<? extends IScheme>, SchemeFactory>();
    static {
      schemes.put(StandardScheme.class, new deleteGatewayResourceProfile_resultStandardSchemeFactory());
      schemes.put(TupleScheme.class, new deleteGatewayResourceProfile_resultTupleSchemeFactory());
    }

    public boolean success; // required
    public org.apache.airavata.model.error.InvalidRequestException ire; // required
    public org.apache.airavata.model.error.AiravataClientException ace; // required
    public org.apache.airavata.model.error.AiravataSystemException ase; // 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"),
      IRE((short)1, "ire"),
      ACE((short)2, "ace"),
      ASE((short)3, "ase"),
      AE((short)4, "ae");

      private static final Map<String, _Fields> byName = new HashMap<String, _Fields>();

      static {
        for (_Fields field : EnumSet.allOf(_Fields.class)) {
          byName.put(field.getFieldName(), field);
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, or null if its not found.
       */
      public static _Fields findByThriftId(int fieldId) {
        switch(fieldId) {
          case 0: // SUCCESS
            return SUCCESS;
          case 1: // IRE
            return IRE;
          case 2: // ACE
            return ACE;
          case 3: // ASE
            return ASE;
          case 4: // 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 IllegalArgumentException("Field " + fieldId + " doesn't exist!");
        return fields;
      }

      /**
       * Find the _Fields constant that matches name, or null if its not found.
       */
      public static _Fields findByName(String name) {
        return byName.get(name);
      }

      private final short _thriftId;
      private final String _fieldName;

      _Fields(short thriftId, String fieldName) {
        _thriftId = thriftId;
        _fieldName = fieldName;
      }

      public short getThriftFieldId() {
        return _thriftId;
      }

      public String getFieldName() {
        return _fieldName;
      }
    }

    // isset id assignments
    private static final int __SUCCESS_ISSET_ID = 0;
    private byte __isset_bitfield = 0;
    public static final Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
    static {
      Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new EnumMap<_Fields, org.apache.thrift.meta_data.FieldMetaData>(_Fields.class);
      tmpMap.put(_Fields.SUCCESS, new org.apache.thrift.meta_data.FieldMetaData("success", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.BOOL)));
      tmpMap.put(_Fields.IRE, new org.apache.thrift.meta_data.FieldMetaData("ire", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRUCT)));
      tmpMap.put(_Fields.ACE, new org.apache.thrift.meta_data.FieldMetaData("ace", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRUCT)));
      tmpMap.put(_Fields.ASE, new org.apache.thrift.meta_data.FieldMetaData("ase", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRUCT)));
      tmpMap.put(_Fields.AE, new org.apache.thrift.meta_data.FieldMetaData("ae", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRUCT)));
      metaDataMap = Collections.unmodifiableMap(tmpMap);
      org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(deleteGatewayResourceProfile_result.class, metaDataMap);
    }

    public deleteGatewayResourceProfile_result() {
    }

    public deleteGatewayResourceProfile_result(
      boolean success,
      org.apache.airavata.model.error.InvalidRequestException ire,
      org.apache.airavata.model.error.AiravataClientException ace,
      org.apache.airavata.model.error.AiravataSystemException ase,
      org.apache.airavata.model.error.AuthorizationException ae)
    {
      this();
      this.success = success;
      setSuccessIsSet(true);
      this.ire = ire;
      this.ace = ace;
      this.ase = ase;
      this.ae = ae;
    }

    /**
     * Performs a deep copy on <i>other</i>.
     */
    public deleteGatewayResourceProfile_result(deleteGatewayResourceProfile_result other) {
      __isset_bitfield = other.__isset_bitfield;
      this.success = other.success;
      if (other.isSetIre()) {
        this.ire = new org.apache.airavata.model.error.InvalidRequestException(other.ire);
      }
      if (other.isSetAce()) {
        this.ace = new org.apache.airavata.model.error.AiravataClientException(other.ace);
      }
      if (other.isSetAse()) {
        this.ase = new org.apache.airavata.model.error.AiravataSystemException(other.ase);
      }
      if (other.isSetAe()) {
        this.ae = new org.apache.airavata.model.error.AuthorizationException(other.ae);
      }
    }

    public deleteGatewayResourceProfile_result deepCopy() {
      return new deleteGatewayResourceProfile_result(this);
    }

    @Override
    public void clear() {
      setSuccessIsSet(false);
      this.success = false;
      this.ire = null;
      this.ace = null;
      this.ase = null;
      this.ae = null;
    }

    public boolean isSuccess() {
      return this.success;
    }

    public deleteGatewayResourceProfile_result setSuccess(boolean success) {
      this.success = success;
      setSuccessIsSet(true);
      return this;
    }

    public void unsetSuccess() {
      __isset_bitfield = EncodingUtils.clearBit(__isset_bitfield, __SUCCESS_ISSET_ID);
    }

    /** Returns true if field success is set (has been assigned a value) and false otherwise */
    public boolean isSetSuccess() {
      return EncodingUtils.testBit(__isset_bitfield, __SUCCESS_ISSET_ID);
    }

    public void setSuccessIsSet(boolean value) {
      __isset_bitfield = EncodingUtils.setBit(__isset_bitfield, __SUCCESS_ISSET_ID, value);
    }

    public org.apache.airavata.model.error.InvalidRequestException getIre() {
      return this.ire;
    }

    public deleteGatewayResourceProfile_result setIre(org.apache.airavata.model.error.InvalidRequestException ire) {
      this.ire = ire;
      return this;
    }

    public void unsetIre() {
      this.ire = null;
    }

    /** Returns true if field ire is set (has been assigned a value) and false otherwise */
    public boolean isSetIre() {
      return this.ire != null;
    }

    public void setIreIsSet(boolean value) {
      if (!value) {
        this.ire = null;
      }
    }

    public org.apache.airavata.model.error.AiravataClientException getAce() {
      return this.ace;
    }

    public deleteGatewayResourceProfile_result setAce(org.apache.airavata.model.error.AiravataClientException ace) {
      this.ace = ace;
      return this;
    }

    public void unsetAce() {
      this.ace = null;
    }

    /** Returns true if field ace is set (has been assigned a value) and false otherwise */
    public boolean isSetAce() {
      return this.ace != null;
    }

    public void setAceIsSet(boolean value) {
      if (!value) {
        this.ace = null;
      }
    }

    public org.apache.airavata.model.error.AiravataSystemException getAse() {
      return this.ase;
    }

    public deleteGatewayResourceProfile_result setAse(org.apache.airavata.model.error.AiravataSystemException ase) {
      this.ase = ase;
      return this;
    }

    public void unsetAse() {
      this.ase = null;
    }

    /** Returns true if field ase is set (has been assigned a value) and false otherwise */
    public boolean isSetAse() {
      return this.ase != null;
    }

    public void setAseIsSet(boolean value) {
      if (!value) {
        this.ase = null;
      }
    }

    public org.apache.airavata.model.error.AuthorizationException getAe() {
      return this.ae;
    }

    public deleteGatewayResourceProfile_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, Object value) {
      switch (field) {
      case SUCCESS:
        if (value == null) {
          unsetSuccess();
        } else {
          setSuccess((Boolean)value);
        }
        break;

      case IRE:
        if (value == null) {
          unsetIre();
        } else {
          setIre((org.apache.airavata.model.error.InvalidRequestException)value);
        }
        break;

      case ACE:
        if (value == null) {
          unsetAce();
        } else {
          setAce((org.apache.airavata.model.error.AiravataClientException)value);
        }
        break;

      case ASE:
        if (value == null) {
          unsetAse();
        } else {
          setAse((org.apache.airavata.model.error.AiravataSystemException)value);
        }
        break;

      case AE:
        if (value == null) {
          unsetAe();
        } else {
          setAe((org.apache.airavata.model.error.AuthorizationException)value);
        }
        break;

      }
    }

    public Object getFieldValue(_Fields field) {
      switch (field) {
      case SUCCESS:
        return Boolean.valueOf(isSuccess());

      case IRE:
        return getIre();

      case ACE:
        return getAce();

      case ASE:
        return getAse();

      case AE:
        return getAe();

      }
      throw new IllegalStateException();
    }

    /** Returns true if field corresponding to fieldID is set (has been assigned a value) and false otherwise */
    public boolean isSet(_Fields field) {
      if (field == null) {
        throw new IllegalArgumentException();
      }

      switch (field) {
      case SUCCESS:
        return isSetSuccess();
      case IRE:
        return isSetIre();
      case ACE:
        return isSetAce();
      case ASE:
        return isSetAse();
      case AE:
        return isSetAe();
      }
      throw new IllegalStateException();
    }

    @Override
    public boolean equals(Object that) {
      if (that == null)
        return false;
      if (that instanceof deleteGatewayResourceProfile_result)
        return this.equals((deleteGatewayResourceProfile_result)that);
      return false;
    }

    public boolean equals(deleteGatewayResourceProfile_result that) {
      if (that == null)
        return false;

      boolean this_present_success = true;
      boolean that_present_success = true;
      if (this_present_success || that_present_success) {
        if (!(this_present_success && that_present_success))
          return false;
        if (this.success != that.success)
          return false;
      }

      boolean this_present_ire = true && this.isSetIre();
      boolean that_present_ire = true && that.isSetIre();
      if (this_present_ire || that_present_ire) {
        if (!(this_present_ire && that_present_ire))
          return false;
        if (!this.ire.equals(that.ire))
          return false;
      }

      boolean this_present_ace = true && this.isSetAce();
      boolean that_present_ace = true && that.isSetAce();
      if (this_present_ace || that_present_ace) {
        if (!(this_present_ace && that_present_ace))
          return false;
        if (!this.ace.equals(that.ace))
          return false;
      }

      boolean this_present_ase = true && this.isSetAse();
      boolean that_present_ase = true && that.isSetAse();
      if (this_present_ase || that_present_ase) {
        if (!(this_present_ase && that_present_ase))
          return false;
        if (!this.ase.equals(that.ase))
          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() {
      List<Object> list = new ArrayList<Object>();

      boolean present_success = true;
      list.add(present_success);
      if (present_success)
        list.add(success);

      boolean present_ire = true && (isSetIre());
      list.add(present_ire);
      if (present_ire)
        list.add(ire);

      boolean present_ace = true && (isSetAce());
      list.add(present_ace);
      if (present_ace)
        list.add(ace);

      boolean present_ase = true && (isSetAse());
      list.add(present_ase);
      if (present_ase)
        list.add(ase);

      boolean present_ae = true && (isSetAe());
      list.add(present_ae);
      if (present_ae)
        list.add(ae);

      return list.hashCode();
    }

    @Override
    public int compareTo(deleteGatewayResourceProfile_result other) {
      if (!getClass().equals(other.getClass())) {
        return getClass().getName().compareTo(other.getClass().getName());
      }

      int lastComparison = 0;

      lastComparison = Boolean.valueOf(isSetSuccess()).compareTo(other.isSetSuccess());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetSuccess()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.success, other.success);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = Boolean.valueOf(isSetIre()).compareTo(other.isSetIre());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetIre()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.ire, other.ire);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = Boolean.valueOf(isSetAce()).compareTo(other.isSetAce());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetAce()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.ace, other.ace);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = Boolean.valueOf(isSetAse()).compareTo(other.isSetAse());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetAse()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.ase, other.ase);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = 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 {
      schemes.get(iprot.getScheme()).getScheme().read(iprot, this);
    }

    public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException {
      schemes.get(oprot.getScheme()).getScheme().write(oprot, this);
      }

    @Override
    public String toString() {
      StringBuilder sb = new StringBuilder("deleteGatewayResourceProfile_result(");
      boolean first = true;

      sb.append("success:");
      sb.append(this.success);
      first = false;
      if (!first) sb.append(", ");
      sb.append("ire:");
      if (this.ire == null) {
        sb.append("null");
      } else {
        sb.append(this.ire);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("ace:");
      if (this.ace == null) {
        sb.append("null");
      } else {
        sb.append(this.ace);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("ase:");
      if (this.ase == null) {
        sb.append("null");
      } else {
        sb.append(this.ase);
      }
      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, 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 deleteGatewayResourceProfile_resultStandardSchemeFactory implements SchemeFactory {
      public deleteGatewayResourceProfile_resultStandardScheme getScheme() {
        return new deleteGatewayResourceProfile_resultStandardScheme();
      }
    }

    private static class deleteGatewayResourceProfile_resultStandardScheme extends StandardScheme<deleteGatewayResourceProfile_result> {

      public void read(org.apache.thrift.protocol.TProtocol iprot, deleteGatewayResourceProfile_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: // IRE
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.ire = new org.apache.airavata.model.error.InvalidRequestException();
                struct.ire.read(iprot);
                struct.setIreIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 2: // ACE
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.ace = new org.apache.airavata.model.error.AiravataClientException();
                struct.ace.read(iprot);
                struct.setAceIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 3: // ASE
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.ase = new org.apache.airavata.model.error.AiravataSystemException();
                struct.ase.read(iprot);
                struct.setAseIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 4: // 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, deleteGatewayResourceProfile_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.ire != null) {
          oprot.writeFieldBegin(IRE_FIELD_DESC);
          struct.ire.write(oprot);
          oprot.writeFieldEnd();
        }
        if (struct.ace != null) {
          oprot.writeFieldBegin(ACE_FIELD_DESC);
          struct.ace.write(oprot);
          oprot.writeFieldEnd();
        }
        if (struct.ase != null) {
          oprot.writeFieldBegin(ASE_FIELD_DESC);
          struct.ase.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 deleteGatewayResourceProfile_resultTupleSchemeFactory implements SchemeFactory {
      public deleteGatewayResourceProfile_resultTupleScheme getScheme() {
        return new deleteGatewayResourceProfile_resultTupleScheme();
      }
    }

    private static class deleteGatewayResourceProfile_resultTupleScheme extends TupleScheme<deleteGatewayResourceProfile_result> {

      @Override
      public void write(org.apache.thrift.protocol.TProtocol prot, deleteGatewayResourceProfile_result struct) throws org.apache.thrift.TException {
        TTupleProtocol oprot = (TTupleProtocol) prot;
        BitSet optionals = new BitSet();
        if (struct.isSetSuccess()) {
          optionals.set(0);
        }
        if (struct.isSetIre()) {
          optionals.set(1);
        }
        if (struct.isSetAce()) {
          optionals.set(2);
        }
        if (struct.isSetAse()) {
          optionals.set(3);
        }
        if (struct.isSetAe()) {
          optionals.set(4);
        }
        oprot.writeBitSet(optionals, 5);
        if (struct.isSetSuccess()) {
          oprot.writeBool(struct.success);
        }
        if (struct.isSetIre()) {
          struct.ire.write(oprot);
        }
        if (struct.isSetAce()) {
          struct.ace.write(oprot);
        }
        if (struct.isSetAse()) {
          struct.ase.write(oprot);
        }
        if (struct.isSetAe()) {
          struct.ae.write(oprot);
        }
      }

      @Override
      public void read(org.apache.thrift.protocol.TProtocol prot, deleteGatewayResourceProfile_result struct) throws org.apache.thrift.TException {
        TTupleProtocol iprot = (TTupleProtocol) prot;
        BitSet incoming = iprot.readBitSet(5);
        if (incoming.get(0)) {
          struct.success = iprot.readBool();
          struct.setSuccessIsSet(true);
        }
        if (incoming.get(1)) {
          struct.ire = new org.apache.airavata.model.error.InvalidRequestException();
          struct.ire.read(iprot);
          struct.setIreIsSet(true);
        }
        if (incoming.get(2)) {
          struct.ace = new org.apache.airavata.model.error.AiravataClientException();
          struct.ace.read(iprot);
          struct.setAceIsSet(true);
        }
        if (incoming.get(3)) {
          struct.ase = new org.apache.airavata.model.error.AiravataSystemException();
          struct.ase.read(iprot);
          struct.setAseIsSet(true);
        }
        if (incoming.get(4)) {
          struct.ae = new org.apache.airavata.model.error.AuthorizationException();
          struct.ae.read(iprot);
          struct.setAeIsSet(true);
        }
      }
    }

  }

  public static class addGatewayComputeResourcePreference_args implements org.apache.thrift.TBase<addGatewayComputeResourcePreference_args, addGatewayComputeResourcePreference_args._Fields>, java.io.Serializable, Cloneable, Comparable<addGatewayComputeResourcePreference_args>   {
    private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("addGatewayComputeResourcePreference_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.protocol.TField COMPUTE_RESOURCE_ID_FIELD_DESC = new org.apache.thrift.protocol.TField("computeResourceId", org.apache.thrift.protocol.TType.STRING, (short)3);
    private static final org.apache.thrift.protocol.TField COMPUTE_RESOURCE_PREFERENCE_FIELD_DESC = new org.apache.thrift.protocol.TField("computeResourcePreference", org.apache.thrift.protocol.TType.STRUCT, (short)4);

    private static final Map<Class<? extends IScheme>, SchemeFactory> schemes = new HashMap<Class<? extends IScheme>, SchemeFactory>();
    static {
      schemes.put(StandardScheme.class, new addGatewayComputeResourcePreference_argsStandardSchemeFactory());
      schemes.put(TupleScheme.class, new addGatewayComputeResourcePreference_argsTupleSchemeFactory());
    }

    public org.apache.airavata.model.security.AuthzToken authzToken; // required
    public String gatewayID; // required
    public String computeResourceId; // required
    public org.apache.airavata.model.appcatalog.gatewayprofile.ComputeResourcePreference computeResourcePreference; // required

    /** 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"),
      COMPUTE_RESOURCE_ID((short)3, "computeResourceId"),
      COMPUTE_RESOURCE_PREFERENCE((short)4, "computeResourcePreference");

      private static final Map<String, _Fields> byName = new HashMap<String, _Fields>();

      static {
        for (_Fields field : EnumSet.allOf(_Fields.class)) {
          byName.put(field.getFieldName(), field);
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, or null if its not found.
       */
      public static _Fields findByThriftId(int fieldId) {
        switch(fieldId) {
          case 1: // AUTHZ_TOKEN
            return AUTHZ_TOKEN;
          case 2: // GATEWAY_ID
            return GATEWAY_ID;
          case 3: // COMPUTE_RESOURCE_ID
            return COMPUTE_RESOURCE_ID;
          case 4: // COMPUTE_RESOURCE_PREFERENCE
            return COMPUTE_RESOURCE_PREFERENCE;
          default:
            return null;
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, throwing an exception
       * if it is not found.
       */
      public static _Fields findByThriftIdOrThrow(int fieldId) {
        _Fields fields = findByThriftId(fieldId);
        if (fields == null) throw new IllegalArgumentException("Field " + fieldId + " doesn't exist!");
        return fields;
      }

      /**
       * Find the _Fields constant that matches name, or null if its not found.
       */
      public static _Fields findByName(String name) {
        return byName.get(name);
      }

      private final short _thriftId;
      private final String _fieldName;

      _Fields(short thriftId, String fieldName) {
        _thriftId = thriftId;
        _fieldName = fieldName;
      }

      public short getThriftFieldId() {
        return _thriftId;
      }

      public String getFieldName() {
        return _fieldName;
      }
    }

    // isset id assignments
    public static final Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
    static {
      Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new EnumMap<_Fields, org.apache.thrift.meta_data.FieldMetaData>(_Fields.class);
      tmpMap.put(_Fields.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)));
      tmpMap.put(_Fields.COMPUTE_RESOURCE_ID, new org.apache.thrift.meta_data.FieldMetaData("computeResourceId", org.apache.thrift.TFieldRequirementType.REQUIRED, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING)));
      tmpMap.put(_Fields.COMPUTE_RESOURCE_PREFERENCE, new org.apache.thrift.meta_data.FieldMetaData("computeResourcePreference", org.apache.thrift.TFieldRequirementType.REQUIRED, 
          new org.apache.thrift.meta_data.StructMetaData(org.apache.thrift.protocol.TType.STRUCT, org.apache.airavata.model.appcatalog.gatewayprofile.ComputeResourcePreference.class)));
      metaDataMap = Collections.unmodifiableMap(tmpMap);
      org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(addGatewayComputeResourcePreference_args.class, metaDataMap);
    }

    public addGatewayComputeResourcePreference_args() {
    }

    public addGatewayComputeResourcePreference_args(
      org.apache.airavata.model.security.AuthzToken authzToken,
      String gatewayID,
      String computeResourceId,
      org.apache.airavata.model.appcatalog.gatewayprofile.ComputeResourcePreference computeResourcePreference)
    {
      this();
      this.authzToken = authzToken;
      this.gatewayID = gatewayID;
      this.computeResourceId = computeResourceId;
      this.computeResourcePreference = computeResourcePreference;
    }

    /**
     * Performs a deep copy on <i>other</i>.
     */
    public addGatewayComputeResourcePreference_args(addGatewayComputeResourcePreference_args other) {
      if (other.isSetAuthzToken()) {
        this.authzToken = new org.apache.airavata.model.security.AuthzToken(other.authzToken);
      }
      if (other.isSetGatewayID()) {
        this.gatewayID = other.gatewayID;
      }
      if (other.isSetComputeResourceId()) {
        this.computeResourceId = other.computeResourceId;
      }
      if (other.isSetComputeResourcePreference()) {
        this.computeResourcePreference = new org.apache.airavata.model.appcatalog.gatewayprofile.ComputeResourcePreference(other.computeResourcePreference);
      }
    }

    public addGatewayComputeResourcePreference_args deepCopy() {
      return new addGatewayComputeResourcePreference_args(this);
    }

    @Override
    public void clear() {
      this.authzToken = null;
      this.gatewayID = null;
      this.computeResourceId = null;
      this.computeResourcePreference = null;
    }

    public org.apache.airavata.model.security.AuthzToken getAuthzToken() {
      return this.authzToken;
    }

    public addGatewayComputeResourcePreference_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 String getGatewayID() {
      return this.gatewayID;
    }

    public addGatewayComputeResourcePreference_args setGatewayID(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 String getComputeResourceId() {
      return this.computeResourceId;
    }

    public addGatewayComputeResourcePreference_args setComputeResourceId(String computeResourceId) {
      this.computeResourceId = computeResourceId;
      return this;
    }

    public void unsetComputeResourceId() {
      this.computeResourceId = null;
    }

    /** Returns true if field computeResourceId is set (has been assigned a value) and false otherwise */
    public boolean isSetComputeResourceId() {
      return this.computeResourceId != null;
    }

    public void setComputeResourceIdIsSet(boolean value) {
      if (!value) {
        this.computeResourceId = null;
      }
    }

    public org.apache.airavata.model.appcatalog.gatewayprofile.ComputeResourcePreference getComputeResourcePreference() {
      return this.computeResourcePreference;
    }

    public addGatewayComputeResourcePreference_args setComputeResourcePreference(org.apache.airavata.model.appcatalog.gatewayprofile.ComputeResourcePreference computeResourcePreference) {
      this.computeResourcePreference = computeResourcePreference;
      return this;
    }

    public void unsetComputeResourcePreference() {
      this.computeResourcePreference = null;
    }

    /** Returns true if field computeResourcePreference is set (has been assigned a value) and false otherwise */
    public boolean isSetComputeResourcePreference() {
      return this.computeResourcePreference != null;
    }

    public void setComputeResourcePreferenceIsSet(boolean value) {
      if (!value) {
        this.computeResourcePreference = null;
      }
    }

    public void setFieldValue(_Fields field, 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((String)value);
        }
        break;

      case COMPUTE_RESOURCE_ID:
        if (value == null) {
          unsetComputeResourceId();
        } else {
          setComputeResourceId((String)value);
        }
        break;

      case COMPUTE_RESOURCE_PREFERENCE:
        if (value == null) {
          unsetComputeResourcePreference();
        } else {
          setComputeResourcePreference((org.apache.airavata.model.appcatalog.gatewayprofile.ComputeResourcePreference)value);
        }
        break;

      }
    }

    public Object getFieldValue(_Fields field) {
      switch (field) {
      case AUTHZ_TOKEN:
        return getAuthzToken();

      case GATEWAY_ID:
        return getGatewayID();

      case COMPUTE_RESOURCE_ID:
        return getComputeResourceId();

      case COMPUTE_RESOURCE_PREFERENCE:
        return getComputeResourcePreference();

      }
      throw new IllegalStateException();
    }

    /** Returns true if field corresponding to fieldID is set (has been assigned a value) and false otherwise */
    public boolean isSet(_Fields field) {
      if (field == null) {
        throw new IllegalArgumentException();
      }

      switch (field) {
      case AUTHZ_TOKEN:
        return isSetAuthzToken();
      case GATEWAY_ID:
        return isSetGatewayID();
      case COMPUTE_RESOURCE_ID:
        return isSetComputeResourceId();
      case COMPUTE_RESOURCE_PREFERENCE:
        return isSetComputeResourcePreference();
      }
      throw new IllegalStateException();
    }

    @Override
    public boolean equals(Object that) {
      if (that == null)
        return false;
      if (that instanceof addGatewayComputeResourcePreference_args)
        return this.equals((addGatewayComputeResourcePreference_args)that);
      return false;
    }

    public boolean equals(addGatewayComputeResourcePreference_args that) {
      if (that == null)
        return false;

      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;
      }

      boolean this_present_computeResourceId = true && this.isSetComputeResourceId();
      boolean that_present_computeResourceId = true && that.isSetComputeResourceId();
      if (this_present_computeResourceId || that_present_computeResourceId) {
        if (!(this_present_computeResourceId && that_present_computeResourceId))
          return false;
        if (!this.computeResourceId.equals(that.computeResourceId))
          return false;
      }

      boolean this_present_computeResourcePreference = true && this.isSetComputeResourcePreference();
      boolean that_present_computeResourcePreference = true && that.isSetComputeResourcePreference();
      if (this_present_computeResourcePreference || that_present_computeResourcePreference) {
        if (!(this_present_computeResourcePreference && that_present_computeResourcePreference))
          return false;
        if (!this.computeResourcePreference.equals(that.computeResourcePreference))
          return false;
      }

      return true;
    }

    @Override
    public int hashCode() {
      List<Object> list = new ArrayList<Object>();

      boolean present_authzToken = true && (isSetAuthzToken());
      list.add(present_authzToken);
      if (present_authzToken)
        list.add(authzToken);

      boolean present_gatewayID = true && (isSetGatewayID());
      list.add(present_gatewayID);
      if (present_gatewayID)
        list.add(gatewayID);

      boolean present_computeResourceId = true && (isSetComputeResourceId());
      list.add(present_computeResourceId);
      if (present_computeResourceId)
        list.add(computeResourceId);

      boolean present_computeResourcePreference = true && (isSetComputeResourcePreference());
      list.add(present_computeResourcePreference);
      if (present_computeResourcePreference)
        list.add(computeResourcePreference);

      return list.hashCode();
    }

    @Override
    public int compareTo(addGatewayComputeResourcePreference_args other) {
      if (!getClass().equals(other.getClass())) {
        return getClass().getName().compareTo(other.getClass().getName());
      }

      int lastComparison = 0;

      lastComparison = 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 = 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;
        }
      }
      lastComparison = Boolean.valueOf(isSetComputeResourceId()).compareTo(other.isSetComputeResourceId());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetComputeResourceId()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.computeResourceId, other.computeResourceId);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = Boolean.valueOf(isSetComputeResourcePreference()).compareTo(other.isSetComputeResourcePreference());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetComputeResourcePreference()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.computeResourcePreference, other.computeResourcePreference);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      return 0;
    }

    public _Fields fieldForId(int fieldId) {
      return _Fields.findByThriftId(fieldId);
    }

    public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
      schemes.get(iprot.getScheme()).getScheme().read(iprot, this);
    }

    public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException {
      schemes.get(oprot.getScheme()).getScheme().write(oprot, this);
    }

    @Override
    public String toString() {
      StringBuilder sb = new StringBuilder("addGatewayComputeResourcePreference_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;
      if (!first) sb.append(", ");
      sb.append("computeResourceId:");
      if (this.computeResourceId == null) {
        sb.append("null");
      } else {
        sb.append(this.computeResourceId);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("computeResourcePreference:");
      if (this.computeResourcePreference == null) {
        sb.append("null");
      } else {
        sb.append(this.computeResourcePreference);
      }
      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());
      }
      if (computeResourceId == null) {
        throw new org.apache.thrift.protocol.TProtocolException("Required field 'computeResourceId' was not present! Struct: " + toString());
      }
      if (computeResourcePreference == null) {
        throw new org.apache.thrift.protocol.TProtocolException("Required field 'computeResourcePreference' was not present! Struct: " + toString());
      }
      // check for sub-struct validity
      if (authzToken != null) {
        authzToken.validate();
      }
      if (computeResourcePreference != null) {
        computeResourcePreference.validate();
      }
    }

    private void writeObject(java.io.ObjectOutputStream out) throws java.io.IOException {
      try {
        write(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(out)));
      } catch (org.apache.thrift.TException te) {
        throw new java.io.IOException(te);
      }
    }

    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, ClassNotFoundException {
      try {
        read(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(in)));
      } catch (org.apache.thrift.TException te) {
        throw new java.io.IOException(te);
      }
    }

    private static class addGatewayComputeResourcePreference_argsStandardSchemeFactory implements SchemeFactory {
      public addGatewayComputeResourcePreference_argsStandardScheme getScheme() {
        return new addGatewayComputeResourcePreference_argsStandardScheme();
      }
    }

    private static class addGatewayComputeResourcePreference_argsStandardScheme extends StandardScheme<addGatewayComputeResourcePreference_args> {

      public void read(org.apache.thrift.protocol.TProtocol iprot, addGatewayComputeResourcePreference_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;
            case 3: // COMPUTE_RESOURCE_ID
              if (schemeField.type == org.apache.thrift.protocol.TType.STRING) {
                struct.computeResourceId = iprot.readString();
                struct.setComputeResourceIdIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 4: // COMPUTE_RESOURCE_PREFERENCE
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.computeResourcePreference = new org.apache.airavata.model.appcatalog.gatewayprofile.ComputeResourcePreference();
                struct.computeResourcePreference.read(iprot);
                struct.setComputeResourcePreferenceIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            default:
              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
          }
          iprot.readFieldEnd();
        }
        iprot.readStructEnd();

        // check for required fields of primitive type, which can't be checked in the validate method
        struct.validate();
      }

      public void write(org.apache.thrift.protocol.TProtocol oprot, addGatewayComputeResourcePreference_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();
        }
        if (struct.computeResourceId != null) {
          oprot.writeFieldBegin(COMPUTE_RESOURCE_ID_FIELD_DESC);
          oprot.writeString(struct.computeResourceId);
          oprot.writeFieldEnd();
        }
        if (struct.computeResourcePreference != null) {
          oprot.writeFieldBegin(COMPUTE_RESOURCE_PREFERENCE_FIELD_DESC);
          struct.computeResourcePreference.write(oprot);
          oprot.writeFieldEnd();
        }
        oprot.writeFieldStop();
        oprot.writeStructEnd();
      }

    }

    private static class addGatewayComputeResourcePreference_argsTupleSchemeFactory implements SchemeFactory {
      public addGatewayComputeResourcePreference_argsTupleScheme getScheme() {
        return new addGatewayComputeResourcePreference_argsTupleScheme();
      }
    }

    private static class addGatewayComputeResourcePreference_argsTupleScheme extends TupleScheme<addGatewayComputeResourcePreference_args> {

      @Override
      public void write(org.apache.thrift.protocol.TProtocol prot, addGatewayComputeResourcePreference_args struct) throws org.apache.thrift.TException {
        TTupleProtocol oprot = (TTupleProtocol) prot;
        struct.authzToken.write(oprot);
        oprot.writeString(struct.gatewayID);
        oprot.writeString(struct.computeResourceId);
        struct.computeResourcePreference.write(oprot);
      }

      @Override
      public void read(org.apache.thrift.protocol.TProtocol prot, addGatewayComputeResourcePreference_args struct) throws org.apache.thrift.TException {
        TTupleProtocol iprot = (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);
        struct.computeResourceId = iprot.readString();
        struct.setComputeResourceIdIsSet(true);
        struct.computeResourcePreference = new org.apache.airavata.model.appcatalog.gatewayprofile.ComputeResourcePreference();
        struct.computeResourcePreference.read(iprot);
        struct.setComputeResourcePreferenceIsSet(true);
      }
    }

  }

  public static class addGatewayComputeResourcePreference_result implements org.apache.thrift.TBase<addGatewayComputeResourcePreference_result, addGatewayComputeResourcePreference_result._Fields>, java.io.Serializable, Cloneable, Comparable<addGatewayComputeResourcePreference_result>   {
    private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("addGatewayComputeResourcePreference_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 IRE_FIELD_DESC = new org.apache.thrift.protocol.TField("ire", org.apache.thrift.protocol.TType.STRUCT, (short)1);
    private static final org.apache.thrift.protocol.TField ACE_FIELD_DESC = new org.apache.thrift.protocol.TField("ace", org.apache.thrift.protocol.TType.STRUCT, (short)2);
    private static final org.apache.thrift.protocol.TField ASE_FIELD_DESC = new org.apache.thrift.protocol.TField("ase", org.apache.thrift.protocol.TType.STRUCT, (short)3);
    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)4);

    private static final Map<Class<? extends IScheme>, SchemeFactory> schemes = new HashMap<Class<? extends IScheme>, SchemeFactory>();
    static {
      schemes.put(StandardScheme.class, new addGatewayComputeResourcePreference_resultStandardSchemeFactory());
      schemes.put(TupleScheme.class, new addGatewayComputeResourcePreference_resultTupleSchemeFactory());
    }

    public boolean success; // required
    public org.apache.airavata.model.error.InvalidRequestException ire; // required
    public org.apache.airavata.model.error.AiravataClientException ace; // required
    public org.apache.airavata.model.error.AiravataSystemException ase; // 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"),
      IRE((short)1, "ire"),
      ACE((short)2, "ace"),
      ASE((short)3, "ase"),
      AE((short)4, "ae");

      private static final Map<String, _Fields> byName = new HashMap<String, _Fields>();

      static {
        for (_Fields field : EnumSet.allOf(_Fields.class)) {
          byName.put(field.getFieldName(), field);
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, or null if its not found.
       */
      public static _Fields findByThriftId(int fieldId) {
        switch(fieldId) {
          case 0: // SUCCESS
            return SUCCESS;
          case 1: // IRE
            return IRE;
          case 2: // ACE
            return ACE;
          case 3: // ASE
            return ASE;
          case 4: // 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 IllegalArgumentException("Field " + fieldId + " doesn't exist!");
        return fields;
      }

      /**
       * Find the _Fields constant that matches name, or null if its not found.
       */
      public static _Fields findByName(String name) {
        return byName.get(name);
      }

      private final short _thriftId;
      private final String _fieldName;

      _Fields(short thriftId, String fieldName) {
        _thriftId = thriftId;
        _fieldName = fieldName;
      }

      public short getThriftFieldId() {
        return _thriftId;
      }

      public String getFieldName() {
        return _fieldName;
      }
    }

    // isset id assignments
    private static final int __SUCCESS_ISSET_ID = 0;
    private byte __isset_bitfield = 0;
    public static final Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
    static {
      Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new EnumMap<_Fields, org.apache.thrift.meta_data.FieldMetaData>(_Fields.class);
      tmpMap.put(_Fields.SUCCESS, new org.apache.thrift.meta_data.FieldMetaData("success", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.BOOL)));
      tmpMap.put(_Fields.IRE, new org.apache.thrift.meta_data.FieldMetaData("ire", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRUCT)));
      tmpMap.put(_Fields.ACE, new org.apache.thrift.meta_data.FieldMetaData("ace", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRUCT)));
      tmpMap.put(_Fields.ASE, new org.apache.thrift.meta_data.FieldMetaData("ase", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRUCT)));
      tmpMap.put(_Fields.AE, new org.apache.thrift.meta_data.FieldMetaData("ae", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRUCT)));
      metaDataMap = Collections.unmodifiableMap(tmpMap);
      org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(addGatewayComputeResourcePreference_result.class, metaDataMap);
    }

    public addGatewayComputeResourcePreference_result() {
    }

    public addGatewayComputeResourcePreference_result(
      boolean success,
      org.apache.airavata.model.error.InvalidRequestException ire,
      org.apache.airavata.model.error.AiravataClientException ace,
      org.apache.airavata.model.error.AiravataSystemException ase,
      org.apache.airavata.model.error.AuthorizationException ae)
    {
      this();
      this.success = success;
      setSuccessIsSet(true);
      this.ire = ire;
      this.ace = ace;
      this.ase = ase;
      this.ae = ae;
    }

    /**
     * Performs a deep copy on <i>other</i>.
     */
    public addGatewayComputeResourcePreference_result(addGatewayComputeResourcePreference_result other) {
      __isset_bitfield = other.__isset_bitfield;
      this.success = other.success;
      if (other.isSetIre()) {
        this.ire = new org.apache.airavata.model.error.InvalidRequestException(other.ire);
      }
      if (other.isSetAce()) {
        this.ace = new org.apache.airavata.model.error.AiravataClientException(other.ace);
      }
      if (other.isSetAse()) {
        this.ase = new org.apache.airavata.model.error.AiravataSystemException(other.ase);
      }
      if (other.isSetAe()) {
        this.ae = new org.apache.airavata.model.error.AuthorizationException(other.ae);
      }
    }

    public addGatewayComputeResourcePreference_result deepCopy() {
      return new addGatewayComputeResourcePreference_result(this);
    }

    @Override
    public void clear() {
      setSuccessIsSet(false);
      this.success = false;
      this.ire = null;
      this.ace = null;
      this.ase = null;
      this.ae = null;
    }

    public boolean isSuccess() {
      return this.success;
    }

    public addGatewayComputeResourcePreference_result setSuccess(boolean success) {
      this.success = success;
      setSuccessIsSet(true);
      return this;
    }

    public void unsetSuccess() {
      __isset_bitfield = EncodingUtils.clearBit(__isset_bitfield, __SUCCESS_ISSET_ID);
    }

    /** Returns true if field success is set (has been assigned a value) and false otherwise */
    public boolean isSetSuccess() {
      return EncodingUtils.testBit(__isset_bitfield, __SUCCESS_ISSET_ID);
    }

    public void setSuccessIsSet(boolean value) {
      __isset_bitfield = EncodingUtils.setBit(__isset_bitfield, __SUCCESS_ISSET_ID, value);
    }

    public org.apache.airavata.model.error.InvalidRequestException getIre() {
      return this.ire;
    }

    public addGatewayComputeResourcePreference_result setIre(org.apache.airavata.model.error.InvalidRequestException ire) {
      this.ire = ire;
      return this;
    }

    public void unsetIre() {
      this.ire = null;
    }

    /** Returns true if field ire is set (has been assigned a value) and false otherwise */
    public boolean isSetIre() {
      return this.ire != null;
    }

    public void setIreIsSet(boolean value) {
      if (!value) {
        this.ire = null;
      }
    }

    public org.apache.airavata.model.error.AiravataClientException getAce() {
      return this.ace;
    }

    public addGatewayComputeResourcePreference_result setAce(org.apache.airavata.model.error.AiravataClientException ace) {
      this.ace = ace;
      return this;
    }

    public void unsetAce() {
      this.ace = null;
    }

    /** Returns true if field ace is set (has been assigned a value) and false otherwise */
    public boolean isSetAce() {
      return this.ace != null;
    }

    public void setAceIsSet(boolean value) {
      if (!value) {
        this.ace = null;
      }
    }

    public org.apache.airavata.model.error.AiravataSystemException getAse() {
      return this.ase;
    }

    public addGatewayComputeResourcePreference_result setAse(org.apache.airavata.model.error.AiravataSystemException ase) {
      this.ase = ase;
      return this;
    }

    public void unsetAse() {
      this.ase = null;
    }

    /** Returns true if field ase is set (has been assigned a value) and false otherwise */
    public boolean isSetAse() {
      return this.ase != null;
    }

    public void setAseIsSet(boolean value) {
      if (!value) {
        this.ase = null;
      }
    }

    public org.apache.airavata.model.error.AuthorizationException getAe() {
      return this.ae;
    }

    public addGatewayComputeResourcePreference_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, Object value) {
      switch (field) {
      case SUCCESS:
        if (value == null) {
          unsetSuccess();
        } else {
          setSuccess((Boolean)value);
        }
        break;

      case IRE:
        if (value == null) {
          unsetIre();
        } else {
          setIre((org.apache.airavata.model.error.InvalidRequestException)value);
        }
        break;

      case ACE:
        if (value == null) {
          unsetAce();
        } else {
          setAce((org.apache.airavata.model.error.AiravataClientException)value);
        }
        break;

      case ASE:
        if (value == null) {
          unsetAse();
        } else {
          setAse((org.apache.airavata.model.error.AiravataSystemException)value);
        }
        break;

      case AE:
        if (value == null) {
          unsetAe();
        } else {
          setAe((org.apache.airavata.model.error.AuthorizationException)value);
        }
        break;

      }
    }

    public Object getFieldValue(_Fields field) {
      switch (field) {
      case SUCCESS:
        return Boolean.valueOf(isSuccess());

      case IRE:
        return getIre();

      case ACE:
        return getAce();

      case ASE:
        return getAse();

      case AE:
        return getAe();

      }
      throw new IllegalStateException();
    }

    /** Returns true if field corresponding to fieldID is set (has been assigned a value) and false otherwise */
    public boolean isSet(_Fields field) {
      if (field == null) {
        throw new IllegalArgumentException();
      }

      switch (field) {
      case SUCCESS:
        return isSetSuccess();
      case IRE:
        return isSetIre();
      case ACE:
        return isSetAce();
      case ASE:
        return isSetAse();
      case AE:
        return isSetAe();
      }
      throw new IllegalStateException();
    }

    @Override
    public boolean equals(Object that) {
      if (that == null)
        return false;
      if (that instanceof addGatewayComputeResourcePreference_result)
        return this.equals((addGatewayComputeResourcePreference_result)that);
      return false;
    }

    public boolean equals(addGatewayComputeResourcePreference_result that) {
      if (that == null)
        return false;

      boolean this_present_success = true;
      boolean that_present_success = true;
      if (this_present_success || that_present_success) {
        if (!(this_present_success && that_present_success))
          return false;
        if (this.success != that.success)
          return false;
      }

      boolean this_present_ire = true && this.isSetIre();
      boolean that_present_ire = true && that.isSetIre();
      if (this_present_ire || that_present_ire) {
        if (!(this_present_ire && that_present_ire))
          return false;
        if (!this.ire.equals(that.ire))
          return false;
      }

      boolean this_present_ace = true && this.isSetAce();
      boolean that_present_ace = true && that.isSetAce();
      if (this_present_ace || that_present_ace) {
        if (!(this_present_ace && that_present_ace))
          return false;
        if (!this.ace.equals(that.ace))
          return false;
      }

      boolean this_present_ase = true && this.isSetAse();
      boolean that_present_ase = true && that.isSetAse();
      if (this_present_ase || that_present_ase) {
        if (!(this_present_ase && that_present_ase))
          return false;
        if (!this.ase.equals(that.ase))
          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() {
      List<Object> list = new ArrayList<Object>();

      boolean present_success = true;
      list.add(present_success);
      if (present_success)
        list.add(success);

      boolean present_ire = true && (isSetIre());
      list.add(present_ire);
      if (present_ire)
        list.add(ire);

      boolean present_ace = true && (isSetAce());
      list.add(present_ace);
      if (present_ace)
        list.add(ace);

      boolean present_ase = true && (isSetAse());
      list.add(present_ase);
      if (present_ase)
        list.add(ase);

      boolean present_ae = true && (isSetAe());
      list.add(present_ae);
      if (present_ae)
        list.add(ae);

      return list.hashCode();
    }

    @Override
    public int compareTo(addGatewayComputeResourcePreference_result other) {
      if (!getClass().equals(other.getClass())) {
        return getClass().getName().compareTo(other.getClass().getName());
      }

      int lastComparison = 0;

      lastComparison = Boolean.valueOf(isSetSuccess()).compareTo(other.isSetSuccess());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetSuccess()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.success, other.success);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = Boolean.valueOf(isSetIre()).compareTo(other.isSetIre());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetIre()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.ire, other.ire);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = Boolean.valueOf(isSetAce()).compareTo(other.isSetAce());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetAce()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.ace, other.ace);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = Boolean.valueOf(isSetAse()).compareTo(other.isSetAse());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetAse()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.ase, other.ase);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = 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 {
      schemes.get(iprot.getScheme()).getScheme().read(iprot, this);
    }

    public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException {
      schemes.get(oprot.getScheme()).getScheme().write(oprot, this);
      }

    @Override
    public String toString() {
      StringBuilder sb = new StringBuilder("addGatewayComputeResourcePreference_result(");
      boolean first = true;

      sb.append("success:");
      sb.append(this.success);
      first = false;
      if (!first) sb.append(", ");
      sb.append("ire:");
      if (this.ire == null) {
        sb.append("null");
      } else {
        sb.append(this.ire);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("ace:");
      if (this.ace == null) {
        sb.append("null");
      } else {
        sb.append(this.ace);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("ase:");
      if (this.ase == null) {
        sb.append("null");
      } else {
        sb.append(this.ase);
      }
      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, 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 addGatewayComputeResourcePreference_resultStandardSchemeFactory implements SchemeFactory {
      public addGatewayComputeResourcePreference_resultStandardScheme getScheme() {
        return new addGatewayComputeResourcePreference_resultStandardScheme();
      }
    }

    private static class addGatewayComputeResourcePreference_resultStandardScheme extends StandardScheme<addGatewayComputeResourcePreference_result> {

      public void read(org.apache.thrift.protocol.TProtocol iprot, addGatewayComputeResourcePreference_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: // IRE
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.ire = new org.apache.airavata.model.error.InvalidRequestException();
                struct.ire.read(iprot);
                struct.setIreIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 2: // ACE
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.ace = new org.apache.airavata.model.error.AiravataClientException();
                struct.ace.read(iprot);
                struct.setAceIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 3: // ASE
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.ase = new org.apache.airavata.model.error.AiravataSystemException();
                struct.ase.read(iprot);
                struct.setAseIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 4: // 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, addGatewayComputeResourcePreference_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.ire != null) {
          oprot.writeFieldBegin(IRE_FIELD_DESC);
          struct.ire.write(oprot);
          oprot.writeFieldEnd();
        }
        if (struct.ace != null) {
          oprot.writeFieldBegin(ACE_FIELD_DESC);
          struct.ace.write(oprot);
          oprot.writeFieldEnd();
        }
        if (struct.ase != null) {
          oprot.writeFieldBegin(ASE_FIELD_DESC);
          struct.ase.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 addGatewayComputeResourcePreference_resultTupleSchemeFactory implements SchemeFactory {
      public addGatewayComputeResourcePreference_resultTupleScheme getScheme() {
        return new addGatewayComputeResourcePreference_resultTupleScheme();
      }
    }

    private static class addGatewayComputeResourcePreference_resultTupleScheme extends TupleScheme<addGatewayComputeResourcePreference_result> {

      @Override
      public void write(org.apache.thrift.protocol.TProtocol prot, addGatewayComputeResourcePreference_result struct) throws org.apache.thrift.TException {
        TTupleProtocol oprot = (TTupleProtocol) prot;
        BitSet optionals = new BitSet();
        if (struct.isSetSuccess()) {
          optionals.set(0);
        }
        if (struct.isSetIre()) {
          optionals.set(1);
        }
        if (struct.isSetAce()) {
          optionals.set(2);
        }
        if (struct.isSetAse()) {
          optionals.set(3);
        }
        if (struct.isSetAe()) {
          optionals.set(4);
        }
        oprot.writeBitSet(optionals, 5);
        if (struct.isSetSuccess()) {
          oprot.writeBool(struct.success);
        }
        if (struct.isSetIre()) {
          struct.ire.write(oprot);
        }
        if (struct.isSetAce()) {
          struct.ace.write(oprot);
        }
        if (struct.isSetAse()) {
          struct.ase.write(oprot);
        }
        if (struct.isSetAe()) {
          struct.ae.write(oprot);
        }
      }

      @Override
      public void read(org.apache.thrift.protocol.TProtocol prot, addGatewayComputeResourcePreference_result struct) throws org.apache.thrift.TException {
        TTupleProtocol iprot = (TTupleProtocol) prot;
        BitSet incoming = iprot.readBitSet(5);
        if (incoming.get(0)) {
          struct.success = iprot.readBool();
          struct.setSuccessIsSet(true);
        }
        if (incoming.get(1)) {
          struct.ire = new org.apache.airavata.model.error.InvalidRequestException();
          struct.ire.read(iprot);
          struct.setIreIsSet(true);
        }
        if (incoming.get(2)) {
          struct.ace = new org.apache.airavata.model.error.AiravataClientException();
          struct.ace.read(iprot);
          struct.setAceIsSet(true);
        }
        if (incoming.get(3)) {
          struct.ase = new org.apache.airavata.model.error.AiravataSystemException();
          struct.ase.read(iprot);
          struct.setAseIsSet(true);
        }
        if (incoming.get(4)) {
          struct.ae = new org.apache.airavata.model.error.AuthorizationException();
          struct.ae.read(iprot);
          struct.setAeIsSet(true);
        }
      }
    }

  }

  public static class addGatewayDataStoragePreference_args implements org.apache.thrift.TBase<addGatewayDataStoragePreference_args, addGatewayDataStoragePreference_args._Fields>, java.io.Serializable, Cloneable, Comparable<addGatewayDataStoragePreference_args>   {
    private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("addGatewayDataStoragePreference_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.protocol.TField DATA_MOVE_ID_FIELD_DESC = new org.apache.thrift.protocol.TField("dataMoveId", org.apache.thrift.protocol.TType.STRING, (short)3);
    private static final org.apache.thrift.protocol.TField DATA_STORAGE_PREFERENCE_FIELD_DESC = new org.apache.thrift.protocol.TField("dataStoragePreference", org.apache.thrift.protocol.TType.STRUCT, (short)4);

    private static final Map<Class<? extends IScheme>, SchemeFactory> schemes = new HashMap<Class<? extends IScheme>, SchemeFactory>();
    static {
      schemes.put(StandardScheme.class, new addGatewayDataStoragePreference_argsStandardSchemeFactory());
      schemes.put(TupleScheme.class, new addGatewayDataStoragePreference_argsTupleSchemeFactory());
    }

    public org.apache.airavata.model.security.AuthzToken authzToken; // required
    public String gatewayID; // required
    public String dataMoveId; // required
    public org.apache.airavata.model.appcatalog.gatewayprofile.DataStoragePreference dataStoragePreference; // required

    /** 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"),
      DATA_MOVE_ID((short)3, "dataMoveId"),
      DATA_STORAGE_PREFERENCE((short)4, "dataStoragePreference");

      private static final Map<String, _Fields> byName = new HashMap<String, _Fields>();

      static {
        for (_Fields field : EnumSet.allOf(_Fields.class)) {
          byName.put(field.getFieldName(), field);
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, or null if its not found.
       */
      public static _Fields findByThriftId(int fieldId) {
        switch(fieldId) {
          case 1: // AUTHZ_TOKEN
            return AUTHZ_TOKEN;
          case 2: // GATEWAY_ID
            return GATEWAY_ID;
          case 3: // DATA_MOVE_ID
            return DATA_MOVE_ID;
          case 4: // DATA_STORAGE_PREFERENCE
            return DATA_STORAGE_PREFERENCE;
          default:
            return null;
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, throwing an exception
       * if it is not found.
       */
      public static _Fields findByThriftIdOrThrow(int fieldId) {
        _Fields fields = findByThriftId(fieldId);
        if (fields == null) throw new IllegalArgumentException("Field " + fieldId + " doesn't exist!");
        return fields;
      }

      /**
       * Find the _Fields constant that matches name, or null if its not found.
       */
      public static _Fields findByName(String name) {
        return byName.get(name);
      }

      private final short _thriftId;
      private final String _fieldName;

      _Fields(short thriftId, String fieldName) {
        _thriftId = thriftId;
        _fieldName = fieldName;
      }

      public short getThriftFieldId() {
        return _thriftId;
      }

      public String getFieldName() {
        return _fieldName;
      }
    }

    // isset id assignments
    public static final Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
    static {
      Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new EnumMap<_Fields, org.apache.thrift.meta_data.FieldMetaData>(_Fields.class);
      tmpMap.put(_Fields.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)));
      tmpMap.put(_Fields.DATA_MOVE_ID, new org.apache.thrift.meta_data.FieldMetaData("dataMoveId", org.apache.thrift.TFieldRequirementType.REQUIRED, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING)));
      tmpMap.put(_Fields.DATA_STORAGE_PREFERENCE, new org.apache.thrift.meta_data.FieldMetaData("dataStoragePreference", org.apache.thrift.TFieldRequirementType.REQUIRED, 
          new org.apache.thrift.meta_data.StructMetaData(org.apache.thrift.protocol.TType.STRUCT, org.apache.airavata.model.appcatalog.gatewayprofile.DataStoragePreference.class)));
      metaDataMap = Collections.unmodifiableMap(tmpMap);
      org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(addGatewayDataStoragePreference_args.class, metaDataMap);
    }

    public addGatewayDataStoragePreference_args() {
    }

    public addGatewayDataStoragePreference_args(
      org.apache.airavata.model.security.AuthzToken authzToken,
      String gatewayID,
      String dataMoveId,
      org.apache.airavata.model.appcatalog.gatewayprofile.DataStoragePreference dataStoragePreference)
    {
      this();
      this.authzToken = authzToken;
      this.gatewayID = gatewayID;
      this.dataMoveId = dataMoveId;
      this.dataStoragePreference = dataStoragePreference;
    }

    /**
     * Performs a deep copy on <i>other</i>.
     */
    public addGatewayDataStoragePreference_args(addGatewayDataStoragePreference_args other) {
      if (other.isSetAuthzToken()) {
        this.authzToken = new org.apache.airavata.model.security.AuthzToken(other.authzToken);
      }
      if (other.isSetGatewayID()) {
        this.gatewayID = other.gatewayID;
      }
      if (other.isSetDataMoveId()) {
        this.dataMoveId = other.dataMoveId;
      }
      if (other.isSetDataStoragePreference()) {
        this.dataStoragePreference = new org.apache.airavata.model.appcatalog.gatewayprofile.DataStoragePreference(other.dataStoragePreference);
      }
    }

    public addGatewayDataStoragePreference_args deepCopy() {
      return new addGatewayDataStoragePreference_args(this);
    }

    @Override
    public void clear() {
      this.authzToken = null;
      this.gatewayID = null;
      this.dataMoveId = null;
      this.dataStoragePreference = null;
    }

    public org.apache.airavata.model.security.AuthzToken getAuthzToken() {
      return this.authzToken;
    }

    public addGatewayDataStoragePreference_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 String getGatewayID() {
      return this.gatewayID;
    }

    public addGatewayDataStoragePreference_args setGatewayID(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 String getDataMoveId() {
      return this.dataMoveId;
    }

    public addGatewayDataStoragePreference_args setDataMoveId(String dataMoveId) {
      this.dataMoveId = dataMoveId;
      return this;
    }

    public void unsetDataMoveId() {
      this.dataMoveId = null;
    }

    /** Returns true if field dataMoveId is set (has been assigned a value) and false otherwise */
    public boolean isSetDataMoveId() {
      return this.dataMoveId != null;
    }

    public void setDataMoveIdIsSet(boolean value) {
      if (!value) {
        this.dataMoveId = null;
      }
    }

    public org.apache.airavata.model.appcatalog.gatewayprofile.DataStoragePreference getDataStoragePreference() {
      return this.dataStoragePreference;
    }

    public addGatewayDataStoragePreference_args setDataStoragePreference(org.apache.airavata.model.appcatalog.gatewayprofile.DataStoragePreference dataStoragePreference) {
      this.dataStoragePreference = dataStoragePreference;
      return this;
    }

    public void unsetDataStoragePreference() {
      this.dataStoragePreference = null;
    }

    /** Returns true if field dataStoragePreference is set (has been assigned a value) and false otherwise */
    public boolean isSetDataStoragePreference() {
      return this.dataStoragePreference != null;
    }

    public void setDataStoragePreferenceIsSet(boolean value) {
      if (!value) {
        this.dataStoragePreference = null;
      }
    }

    public void setFieldValue(_Fields field, 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((String)value);
        }
        break;

      case DATA_MOVE_ID:
        if (value == null) {
          unsetDataMoveId();
        } else {
          setDataMoveId((String)value);
        }
        break;

      case DATA_STORAGE_PREFERENCE:
        if (value == null) {
          unsetDataStoragePreference();
        } else {
          setDataStoragePreference((org.apache.airavata.model.appcatalog.gatewayprofile.DataStoragePreference)value);
        }
        break;

      }
    }

    public Object getFieldValue(_Fields field) {
      switch (field) {
      case AUTHZ_TOKEN:
        return getAuthzToken();

      case GATEWAY_ID:
        return getGatewayID();

      case DATA_MOVE_ID:
        return getDataMoveId();

      case DATA_STORAGE_PREFERENCE:
        return getDataStoragePreference();

      }
      throw new IllegalStateException();
    }

    /** Returns true if field corresponding to fieldID is set (has been assigned a value) and false otherwise */
    public boolean isSet(_Fields field) {
      if (field == null) {
        throw new IllegalArgumentException();
      }

      switch (field) {
      case AUTHZ_TOKEN:
        return isSetAuthzToken();
      case GATEWAY_ID:
        return isSetGatewayID();
      case DATA_MOVE_ID:
        return isSetDataMoveId();
      case DATA_STORAGE_PREFERENCE:
        return isSetDataStoragePreference();
      }
      throw new IllegalStateException();
    }

    @Override
    public boolean equals(Object that) {
      if (that == null)
        return false;
      if (that instanceof addGatewayDataStoragePreference_args)
        return this.equals((addGatewayDataStoragePreference_args)that);
      return false;
    }

    public boolean equals(addGatewayDataStoragePreference_args that) {
      if (that == null)
        return false;

      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;
      }

      boolean this_present_dataMoveId = true && this.isSetDataMoveId();
      boolean that_present_dataMoveId = true && that.isSetDataMoveId();
      if (this_present_dataMoveId || that_present_dataMoveId) {
        if (!(this_present_dataMoveId && that_present_dataMoveId))
          return false;
        if (!this.dataMoveId.equals(that.dataMoveId))
          return false;
      }

      boolean this_present_dataStoragePreference = true && this.isSetDataStoragePreference();
      boolean that_present_dataStoragePreference = true && that.isSetDataStoragePreference();
      if (this_present_dataStoragePreference || that_present_dataStoragePreference) {
        if (!(this_present_dataStoragePreference && that_present_dataStoragePreference))
          return false;
        if (!this.dataStoragePreference.equals(that.dataStoragePreference))
          return false;
      }

      return true;
    }

    @Override
    public int hashCode() {
      List<Object> list = new ArrayList<Object>();

      boolean present_authzToken = true && (isSetAuthzToken());
      list.add(present_authzToken);
      if (present_authzToken)
        list.add(authzToken);

      boolean present_gatewayID = true && (isSetGatewayID());
      list.add(present_gatewayID);
      if (present_gatewayID)
        list.add(gatewayID);

      boolean present_dataMoveId = true && (isSetDataMoveId());
      list.add(present_dataMoveId);
      if (present_dataMoveId)
        list.add(dataMoveId);

      boolean present_dataStoragePreference = true && (isSetDataStoragePreference());
      list.add(present_dataStoragePreference);
      if (present_dataStoragePreference)
        list.add(dataStoragePreference);

      return list.hashCode();
    }

    @Override
    public int compareTo(addGatewayDataStoragePreference_args other) {
      if (!getClass().equals(other.getClass())) {
        return getClass().getName().compareTo(other.getClass().getName());
      }

      int lastComparison = 0;

      lastComparison = 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 = 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;
        }
      }
      lastComparison = Boolean.valueOf(isSetDataMoveId()).compareTo(other.isSetDataMoveId());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetDataMoveId()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.dataMoveId, other.dataMoveId);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = Boolean.valueOf(isSetDataStoragePreference()).compareTo(other.isSetDataStoragePreference());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetDataStoragePreference()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.dataStoragePreference, other.dataStoragePreference);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      return 0;
    }

    public _Fields fieldForId(int fieldId) {
      return _Fields.findByThriftId(fieldId);
    }

    public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
      schemes.get(iprot.getScheme()).getScheme().read(iprot, this);
    }

    public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException {
      schemes.get(oprot.getScheme()).getScheme().write(oprot, this);
    }

    @Override
    public String toString() {
      StringBuilder sb = new StringBuilder("addGatewayDataStoragePreference_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;
      if (!first) sb.append(", ");
      sb.append("dataMoveId:");
      if (this.dataMoveId == null) {
        sb.append("null");
      } else {
        sb.append(this.dataMoveId);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("dataStoragePreference:");
      if (this.dataStoragePreference == null) {
        sb.append("null");
      } else {
        sb.append(this.dataStoragePreference);
      }
      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());
      }
      if (dataMoveId == null) {
        throw new org.apache.thrift.protocol.TProtocolException("Required field 'dataMoveId' was not present! Struct: " + toString());
      }
      if (dataStoragePreference == null) {
        throw new org.apache.thrift.protocol.TProtocolException("Required field 'dataStoragePreference' was not present! Struct: " + toString());
      }
      // check for sub-struct validity
      if (authzToken != null) {
        authzToken.validate();
      }
      if (dataStoragePreference != null) {
        dataStoragePreference.validate();
      }
    }

    private void writeObject(java.io.ObjectOutputStream out) throws java.io.IOException {
      try {
        write(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(out)));
      } catch (org.apache.thrift.TException te) {
        throw new java.io.IOException(te);
      }
    }

    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, ClassNotFoundException {
      try {
        read(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(in)));
      } catch (org.apache.thrift.TException te) {
        throw new java.io.IOException(te);
      }
    }

    private static class addGatewayDataStoragePreference_argsStandardSchemeFactory implements SchemeFactory {
      public addGatewayDataStoragePreference_argsStandardScheme getScheme() {
        return new addGatewayDataStoragePreference_argsStandardScheme();
      }
    }

    private static class addGatewayDataStoragePreference_argsStandardScheme extends StandardScheme<addGatewayDataStoragePreference_args> {

      public void read(org.apache.thrift.protocol.TProtocol iprot, addGatewayDataStoragePreference_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;
            case 3: // DATA_MOVE_ID
              if (schemeField.type == org.apache.thrift.protocol.TType.STRING) {
                struct.dataMoveId = iprot.readString();
                struct.setDataMoveIdIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 4: // DATA_STORAGE_PREFERENCE
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.dataStoragePreference = new org.apache.airavata.model.appcatalog.gatewayprofile.DataStoragePreference();
                struct.dataStoragePreference.read(iprot);
                struct.setDataStoragePreferenceIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            default:
              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
          }
          iprot.readFieldEnd();
        }
        iprot.readStructEnd();

        // check for required fields of primitive type, which can't be checked in the validate method
        struct.validate();
      }

      public void write(org.apache.thrift.protocol.TProtocol oprot, addGatewayDataStoragePreference_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();
        }
        if (struct.dataMoveId != null) {
          oprot.writeFieldBegin(DATA_MOVE_ID_FIELD_DESC);
          oprot.writeString(struct.dataMoveId);
          oprot.writeFieldEnd();
        }
        if (struct.dataStoragePreference != null) {
          oprot.writeFieldBegin(DATA_STORAGE_PREFERENCE_FIELD_DESC);
          struct.dataStoragePreference.write(oprot);
          oprot.writeFieldEnd();
        }
        oprot.writeFieldStop();
        oprot.writeStructEnd();
      }

    }

    private static class addGatewayDataStoragePreference_argsTupleSchemeFactory implements SchemeFactory {
      public addGatewayDataStoragePreference_argsTupleScheme getScheme() {
        return new addGatewayDataStoragePreference_argsTupleScheme();
      }
    }

    private static class addGatewayDataStoragePreference_argsTupleScheme extends TupleScheme<addGatewayDataStoragePreference_args> {

      @Override
      public void write(org.apache.thrift.protocol.TProtocol prot, addGatewayDataStoragePreference_args struct) throws org.apache.thrift.TException {
        TTupleProtocol oprot = (TTupleProtocol) prot;
        struct.authzToken.write(oprot);
        oprot.writeString(struct.gatewayID);
        oprot.writeString(struct.dataMoveId);
        struct.dataStoragePreference.write(oprot);
      }

      @Override
      public void read(org.apache.thrift.protocol.TProtocol prot, addGatewayDataStoragePreference_args struct) throws org.apache.thrift.TException {
        TTupleProtocol iprot = (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);
        struct.dataMoveId = iprot.readString();
        struct.setDataMoveIdIsSet(true);
        struct.dataStoragePreference = new org.apache.airavata.model.appcatalog.gatewayprofile.DataStoragePreference();
        struct.dataStoragePreference.read(iprot);
        struct.setDataStoragePreferenceIsSet(true);
      }
    }

  }

  public static class addGatewayDataStoragePreference_result implements org.apache.thrift.TBase<addGatewayDataStoragePreference_result, addGatewayDataStoragePreference_result._Fields>, java.io.Serializable, Cloneable, Comparable<addGatewayDataStoragePreference_result>   {
    private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("addGatewayDataStoragePreference_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 IRE_FIELD_DESC = new org.apache.thrift.protocol.TField("ire", org.apache.thrift.protocol.TType.STRUCT, (short)1);
    private static final org.apache.thrift.protocol.TField ACE_FIELD_DESC = new org.apache.thrift.protocol.TField("ace", org.apache.thrift.protocol.TType.STRUCT, (short)2);
    private static final org.apache.thrift.protocol.TField ASE_FIELD_DESC = new org.apache.thrift.protocol.TField("ase", org.apache.thrift.protocol.TType.STRUCT, (short)3);
    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)4);

    private static final Map<Class<? extends IScheme>, SchemeFactory> schemes = new HashMap<Class<? extends IScheme>, SchemeFactory>();
    static {
      schemes.put(StandardScheme.class, new addGatewayDataStoragePreference_resultStandardSchemeFactory());
      schemes.put(TupleScheme.class, new addGatewayDataStoragePreference_resultTupleSchemeFactory());
    }

    public boolean success; // required
    public org.apache.airavata.model.error.InvalidRequestException ire; // required
    public org.apache.airavata.model.error.AiravataClientException ace; // required
    public org.apache.airavata.model.error.AiravataSystemException ase; // 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"),
      IRE((short)1, "ire"),
      ACE((short)2, "ace"),
      ASE((short)3, "ase"),
      AE((short)4, "ae");

      private static final Map<String, _Fields> byName = new HashMap<String, _Fields>();

      static {
        for (_Fields field : EnumSet.allOf(_Fields.class)) {
          byName.put(field.getFieldName(), field);
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, or null if its not found.
       */
      public static _Fields findByThriftId(int fieldId) {
        switch(fieldId) {
          case 0: // SUCCESS
            return SUCCESS;
          case 1: // IRE
            return IRE;
          case 2: // ACE
            return ACE;
          case 3: // ASE
            return ASE;
          case 4: // 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 IllegalArgumentException("Field " + fieldId + " doesn't exist!");
        return fields;
      }

      /**
       * Find the _Fields constant that matches name, or null if its not found.
       */
      public static _Fields findByName(String name) {
        return byName.get(name);
      }

      private final short _thriftId;
      private final String _fieldName;

      _Fields(short thriftId, String fieldName) {
        _thriftId = thriftId;
        _fieldName = fieldName;
      }

      public short getThriftFieldId() {
        return _thriftId;
      }

      public String getFieldName() {
        return _fieldName;
      }
    }

    // isset id assignments
    private static final int __SUCCESS_ISSET_ID = 0;
    private byte __isset_bitfield = 0;
    public static final Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
    static {
      Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new EnumMap<_Fields, org.apache.thrift.meta_data.FieldMetaData>(_Fields.class);
      tmpMap.put(_Fields.SUCCESS, new org.apache.thrift.meta_data.FieldMetaData("success", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.BOOL)));
      tmpMap.put(_Fields.IRE, new org.apache.thrift.meta_data.FieldMetaData("ire", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRUCT)));
      tmpMap.put(_Fields.ACE, new org.apache.thrift.meta_data.FieldMetaData("ace", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRUCT)));
      tmpMap.put(_Fields.ASE, new org.apache.thrift.meta_data.FieldMetaData("ase", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRUCT)));
      tmpMap.put(_Fields.AE, new org.apache.thrift.meta_data.FieldMetaData("ae", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRUCT)));
      metaDataMap = Collections.unmodifiableMap(tmpMap);
      org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(addGatewayDataStoragePreference_result.class, metaDataMap);
    }

    public addGatewayDataStoragePreference_result() {
    }

    public addGatewayDataStoragePreference_result(
      boolean success,
      org.apache.airavata.model.error.InvalidRequestException ire,
      org.apache.airavata.model.error.AiravataClientException ace,
      org.apache.airavata.model.error.AiravataSystemException ase,
      org.apache.airavata.model.error.AuthorizationException ae)
    {
      this();
      this.success = success;
      setSuccessIsSet(true);
      this.ire = ire;
      this.ace = ace;
      this.ase = ase;
      this.ae = ae;
    }

    /**
     * Performs a deep copy on <i>other</i>.
     */
    public addGatewayDataStoragePreference_result(addGatewayDataStoragePreference_result other) {
      __isset_bitfield = other.__isset_bitfield;
      this.success = other.success;
      if (other.isSetIre()) {
        this.ire = new org.apache.airavata.model.error.InvalidRequestException(other.ire);
      }
      if (other.isSetAce()) {
        this.ace = new org.apache.airavata.model.error.AiravataClientException(other.ace);
      }
      if (other.isSetAse()) {
        this.ase = new org.apache.airavata.model.error.AiravataSystemException(other.ase);
      }
      if (other.isSetAe()) {
        this.ae = new org.apache.airavata.model.error.AuthorizationException(other.ae);
      }
    }

    public addGatewayDataStoragePreference_result deepCopy() {
      return new addGatewayDataStoragePreference_result(this);
    }

    @Override
    public void clear() {
      setSuccessIsSet(false);
      this.success = false;
      this.ire = null;
      this.ace = null;
      this.ase = null;
      this.ae = null;
    }

    public boolean isSuccess() {
      return this.success;
    }

    public addGatewayDataStoragePreference_result setSuccess(boolean success) {
      this.success = success;
      setSuccessIsSet(true);
      return this;
    }

    public void unsetSuccess() {
      __isset_bitfield = EncodingUtils.clearBit(__isset_bitfield, __SUCCESS_ISSET_ID);
    }

    /** Returns true if field success is set (has been assigned a value) and false otherwise */
    public boolean isSetSuccess() {
      return EncodingUtils.testBit(__isset_bitfield, __SUCCESS_ISSET_ID);
    }

    public void setSuccessIsSet(boolean value) {
      __isset_bitfield = EncodingUtils.setBit(__isset_bitfield, __SUCCESS_ISSET_ID, value);
    }

    public org.apache.airavata.model.error.InvalidRequestException getIre() {
      return this.ire;
    }

    public addGatewayDataStoragePreference_result setIre(org.apache.airavata.model.error.InvalidRequestException ire) {
      this.ire = ire;
      return this;
    }

    public void unsetIre() {
      this.ire = null;
    }

    /** Returns true if field ire is set (has been assigned a value) and false otherwise */
    public boolean isSetIre() {
      return this.ire != null;
    }

    public void setIreIsSet(boolean value) {
      if (!value) {
        this.ire = null;
      }
    }

    public org.apache.airavata.model.error.AiravataClientException getAce() {
      return this.ace;
    }

    public addGatewayDataStoragePreference_result setAce(org.apache.airavata.model.error.AiravataClientException ace) {
      this.ace = ace;
      return this;
    }

    public void unsetAce() {
      this.ace = null;
    }

    /** Returns true if field ace is set (has been assigned a value) and false otherwise */
    public boolean isSetAce() {
      return this.ace != null;
    }

    public void setAceIsSet(boolean value) {
      if (!value) {
        this.ace = null;
      }
    }

    public org.apache.airavata.model.error.AiravataSystemException getAse() {
      return this.ase;
    }

    public addGatewayDataStoragePreference_result setAse(org.apache.airavata.model.error.AiravataSystemException ase) {
      this.ase = ase;
      return this;
    }

    public void unsetAse() {
      this.ase = null;
    }

    /** Returns true if field ase is set (has been assigned a value) and false otherwise */
    public boolean isSetAse() {
      return this.ase != null;
    }

    public void setAseIsSet(boolean value) {
      if (!value) {
        this.ase = null;
      }
    }

    public org.apache.airavata.model.error.AuthorizationException getAe() {
      return this.ae;
    }

    public addGatewayDataStoragePreference_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, Object value) {
      switch (field) {
      case SUCCESS:
        if (value == null) {
          unsetSuccess();
        } else {
          setSuccess((Boolean)value);
        }
        break;

      case IRE:
        if (value == null) {
          unsetIre();
        } else {
          setIre((org.apache.airavata.model.error.InvalidRequestException)value);
        }
        break;

      case ACE:
        if (value == null) {
          unsetAce();
        } else {
          setAce((org.apache.airavata.model.error.AiravataClientException)value);
        }
        break;

      case ASE:
        if (value == null) {
          unsetAse();
        } else {
          setAse((org.apache.airavata.model.error.AiravataSystemException)value);
        }
        break;

      case AE:
        if (value == null) {
          unsetAe();
        } else {
          setAe((org.apache.airavata.model.error.AuthorizationException)value);
        }
        break;

      }
    }

    public Object getFieldValue(_Fields field) {
      switch (field) {
      case SUCCESS:
        return Boolean.valueOf(isSuccess());

      case IRE:
        return getIre();

      case ACE:
        return getAce();

      case ASE:
        return getAse();

      case AE:
        return getAe();

      }
      throw new IllegalStateException();
    }

    /** Returns true if field corresponding to fieldID is set (has been assigned a value) and false otherwise */
    public boolean isSet(_Fields field) {
      if (field == null) {
        throw new IllegalArgumentException();
      }

      switch (field) {
      case SUCCESS:
        return isSetSuccess();
      case IRE:
        return isSetIre();
      case ACE:
        return isSetAce();
      case ASE:
        return isSetAse();
      case AE:
        return isSetAe();
      }
      throw new IllegalStateException();
    }

    @Override
    public boolean equals(Object that) {
      if (that == null)
        return false;
      if (that instanceof addGatewayDataStoragePreference_result)
        return this.equals((addGatewayDataStoragePreference_result)that);
      return false;
    }

    public boolean equals(addGatewayDataStoragePreference_result that) {
      if (that == null)
        return false;

      boolean this_present_success = true;
      boolean that_present_success = true;
      if (this_present_success || that_present_success) {
        if (!(this_present_success && that_present_success))
          return false;
        if (this.success != that.success)
          return false;
      }

      boolean this_present_ire = true && this.isSetIre();
      boolean that_present_ire = true && that.isSetIre();
      if (this_present_ire || that_present_ire) {
        if (!(this_present_ire && that_present_ire))
          return false;
        if (!this.ire.equals(that.ire))
          return false;
      }

      boolean this_present_ace = true && this.isSetAce();
      boolean that_present_ace = true && that.isSetAce();
      if (this_present_ace || that_present_ace) {
        if (!(this_present_ace && that_present_ace))
          return false;
        if (!this.ace.equals(that.ace))
          return false;
      }

      boolean this_present_ase = true && this.isSetAse();
      boolean that_present_ase = true && that.isSetAse();
      if (this_present_ase || that_present_ase) {
        if (!(this_present_ase && that_present_ase))
          return false;
        if (!this.ase.equals(that.ase))
          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() {
      List<Object> list = new ArrayList<Object>();

      boolean present_success = true;
      list.add(present_success);
      if (present_success)
        list.add(success);

      boolean present_ire = true && (isSetIre());
      list.add(present_ire);
      if (present_ire)
        list.add(ire);

      boolean present_ace = true && (isSetAce());
      list.add(present_ace);
      if (present_ace)
        list.add(ace);

      boolean present_ase = true && (isSetAse());
      list.add(present_ase);
      if (present_ase)
        list.add(ase);

      boolean present_ae = true && (isSetAe());
      list.add(present_ae);
      if (present_ae)
        list.add(ae);

      return list.hashCode();
    }

    @Override
    public int compareTo(addGatewayDataStoragePreference_result other) {
      if (!getClass().equals(other.getClass())) {
        return getClass().getName().compareTo(other.getClass().getName());
      }

      int lastComparison = 0;

      lastComparison = Boolean.valueOf(isSetSuccess()).compareTo(other.isSetSuccess());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetSuccess()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.success, other.success);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = Boolean.valueOf(isSetIre()).compareTo(other.isSetIre());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetIre()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.ire, other.ire);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = Boolean.valueOf(isSetAce()).compareTo(other.isSetAce());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetAce()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.ace, other.ace);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = Boolean.valueOf(isSetAse()).compareTo(other.isSetAse());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetAse()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.ase, other.ase);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = 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 {
      schemes.get(iprot.getScheme()).getScheme().read(iprot, this);
    }

    public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException {
      schemes.get(oprot.getScheme()).getScheme().write(oprot, this);
      }

    @Override
    public String toString() {
      StringBuilder sb = new StringBuilder("addGatewayDataStoragePreference_result(");
      boolean first = true;

      sb.append("success:");
      sb.append(this.success);
      first = false;
      if (!first) sb.append(", ");
      sb.append("ire:");
      if (this.ire == null) {
        sb.append("null");
      } else {
        sb.append(this.ire);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("ace:");
      if (this.ace == null) {
        sb.append("null");
      } else {
        sb.append(this.ace);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("ase:");
      if (this.ase == null) {
        sb.append("null");
      } else {
        sb.append(this.ase);
      }
      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, 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 addGatewayDataStoragePreference_resultStandardSchemeFactory implements SchemeFactory {
      public addGatewayDataStoragePreference_resultStandardScheme getScheme() {
        return new addGatewayDataStoragePreference_resultStandardScheme();
      }
    }

    private static class addGatewayDataStoragePreference_resultStandardScheme extends StandardScheme<addGatewayDataStoragePreference_result> {

      public void read(org.apache.thrift.protocol.TProtocol iprot, addGatewayDataStoragePreference_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: // IRE
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.ire = new org.apache.airavata.model.error.InvalidRequestException();
                struct.ire.read(iprot);
                struct.setIreIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 2: // ACE
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.ace = new org.apache.airavata.model.error.AiravataClientException();
                struct.ace.read(iprot);
                struct.setAceIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 3: // ASE
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.ase = new org.apache.airavata.model.error.AiravataSystemException();
                struct.ase.read(iprot);
                struct.setAseIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 4: // 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, addGatewayDataStoragePreference_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.ire != null) {
          oprot.writeFieldBegin(IRE_FIELD_DESC);
          struct.ire.write(oprot);
          oprot.writeFieldEnd();
        }
        if (struct.ace != null) {
          oprot.writeFieldBegin(ACE_FIELD_DESC);
          struct.ace.write(oprot);
          oprot.writeFieldEnd();
        }
        if (struct.ase != null) {
          oprot.writeFieldBegin(ASE_FIELD_DESC);
          struct.ase.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 addGatewayDataStoragePreference_resultTupleSchemeFactory implements SchemeFactory {
      public addGatewayDataStoragePreference_resultTupleScheme getScheme() {
        return new addGatewayDataStoragePreference_resultTupleScheme();
      }
    }

    private static class addGatewayDataStoragePreference_resultTupleScheme extends TupleScheme<addGatewayDataStoragePreference_result> {

      @Override
      public void write(org.apache.thrift.protocol.TProtocol prot, addGatewayDataStoragePreference_result struct) throws org.apache.thrift.TException {
        TTupleProtocol oprot = (TTupleProtocol) prot;
        BitSet optionals = new BitSet();
        if (struct.isSetSuccess()) {
          optionals.set(0);
        }
        if (struct.isSetIre()) {
          optionals.set(1);
        }
        if (struct.isSetAce()) {
          optionals.set(2);
        }
        if (struct.isSetAse()) {
          optionals.set(3);
        }
        if (struct.isSetAe()) {
          optionals.set(4);
        }
        oprot.writeBitSet(optionals, 5);
        if (struct.isSetSuccess()) {
          oprot.writeBool(struct.success);
        }
        if (struct.isSetIre()) {
          struct.ire.write(oprot);
        }
        if (struct.isSetAce()) {
          struct.ace.write(oprot);
        }
        if (struct.isSetAse()) {
          struct.ase.write(oprot);
        }
        if (struct.isSetAe()) {
          struct.ae.write(oprot);
        }
      }

      @Override
      public void read(org.apache.thrift.protocol.TProtocol prot, addGatewayDataStoragePreference_result struct) throws org.apache.thrift.TException {
        TTupleProtocol iprot = (TTupleProtocol) prot;
        BitSet incoming = iprot.readBitSet(5);
        if (incoming.get(0)) {
          struct.success = iprot.readBool();
          struct.setSuccessIsSet(true);
        }
        if (incoming.get(1)) {
          struct.ire = new org.apache.airavata.model.error.InvalidRequestException();
          struct.ire.read(iprot);
          struct.setIreIsSet(true);
        }
        if (incoming.get(2)) {
          struct.ace = new org.apache.airavata.model.error.AiravataClientException();
          struct.ace.read(iprot);
          struct.setAceIsSet(true);
        }
        if (incoming.get(3)) {
          struct.ase = new org.apache.airavata.model.error.AiravataSystemException();
          struct.ase.read(iprot);
          struct.setAseIsSet(true);
        }
        if (incoming.get(4)) {
          struct.ae = new org.apache.airavata.model.error.AuthorizationException();
          struct.ae.read(iprot);
          struct.setAeIsSet(true);
        }
      }
    }

  }

  public static class getGatewayComputeResourcePreference_args implements org.apache.thrift.TBase<getGatewayComputeResourcePreference_args, getGatewayComputeResourcePreference_args._Fields>, java.io.Serializable, Cloneable, Comparable<getGatewayComputeResourcePreference_args>   {
    private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("getGatewayComputeResourcePreference_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.protocol.TField COMPUTE_RESOURCE_ID_FIELD_DESC = new org.apache.thrift.protocol.TField("computeResourceId", org.apache.thrift.protocol.TType.STRING, (short)3);

    private static final Map<Class<? extends IScheme>, SchemeFactory> schemes = new HashMap<Class<? extends IScheme>, SchemeFactory>();
    static {
      schemes.put(StandardScheme.class, new getGatewayComputeResourcePreference_argsStandardSchemeFactory());
      schemes.put(TupleScheme.class, new getGatewayComputeResourcePreference_argsTupleSchemeFactory());
    }

    public org.apache.airavata.model.security.AuthzToken authzToken; // required
    public String gatewayID; // required
    public String computeResourceId; // required

    /** 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"),
      COMPUTE_RESOURCE_ID((short)3, "computeResourceId");

      private static final Map<String, _Fields> byName = new HashMap<String, _Fields>();

      static {
        for (_Fields field : EnumSet.allOf(_Fields.class)) {
          byName.put(field.getFieldName(), field);
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, or null if its not found.
       */
      public static _Fields findByThriftId(int fieldId) {
        switch(fieldId) {
          case 1: // AUTHZ_TOKEN
            return AUTHZ_TOKEN;
          case 2: // GATEWAY_ID
            return GATEWAY_ID;
          case 3: // COMPUTE_RESOURCE_ID
            return COMPUTE_RESOURCE_ID;
          default:
            return null;
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, throwing an exception
       * if it is not found.
       */
      public static _Fields findByThriftIdOrThrow(int fieldId) {
        _Fields fields = findByThriftId(fieldId);
        if (fields == null) throw new IllegalArgumentException("Field " + fieldId + " doesn't exist!");
        return fields;
      }

      /**
       * Find the _Fields constant that matches name, or null if its not found.
       */
      public static _Fields findByName(String name) {
        return byName.get(name);
      }

      private final short _thriftId;
      private final String _fieldName;

      _Fields(short thriftId, String fieldName) {
        _thriftId = thriftId;
        _fieldName = fieldName;
      }

      public short getThriftFieldId() {
        return _thriftId;
      }

      public String getFieldName() {
        return _fieldName;
      }
    }

    // isset id assignments
    public static final Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
    static {
      Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new EnumMap<_Fields, org.apache.thrift.meta_data.FieldMetaData>(_Fields.class);
      tmpMap.put(_Fields.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)));
      tmpMap.put(_Fields.COMPUTE_RESOURCE_ID, new org.apache.thrift.meta_data.FieldMetaData("computeResourceId", org.apache.thrift.TFieldRequirementType.REQUIRED, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING)));
      metaDataMap = Collections.unmodifiableMap(tmpMap);
      org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(getGatewayComputeResourcePreference_args.class, metaDataMap);
    }

    public getGatewayComputeResourcePreference_args() {
    }

    public getGatewayComputeResourcePreference_args(
      org.apache.airavata.model.security.AuthzToken authzToken,
      String gatewayID,
      String computeResourceId)
    {
      this();
      this.authzToken = authzToken;
      this.gatewayID = gatewayID;
      this.computeResourceId = computeResourceId;
    }

    /**
     * Performs a deep copy on <i>other</i>.
     */
    public getGatewayComputeResourcePreference_args(getGatewayComputeResourcePreference_args other) {
      if (other.isSetAuthzToken()) {
        this.authzToken = new org.apache.airavata.model.security.AuthzToken(other.authzToken);
      }
      if (other.isSetGatewayID()) {
        this.gatewayID = other.gatewayID;
      }
      if (other.isSetComputeResourceId()) {
        this.computeResourceId = other.computeResourceId;
      }
    }

    public getGatewayComputeResourcePreference_args deepCopy() {
      return new getGatewayComputeResourcePreference_args(this);
    }

    @Override
    public void clear() {
      this.authzToken = null;
      this.gatewayID = null;
      this.computeResourceId = null;
    }

    public org.apache.airavata.model.security.AuthzToken getAuthzToken() {
      return this.authzToken;
    }

    public getGatewayComputeResourcePreference_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 String getGatewayID() {
      return this.gatewayID;
    }

    public getGatewayComputeResourcePreference_args setGatewayID(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 String getComputeResourceId() {
      return this.computeResourceId;
    }

    public getGatewayComputeResourcePreference_args setComputeResourceId(String computeResourceId) {
      this.computeResourceId = computeResourceId;
      return this;
    }

    public void unsetComputeResourceId() {
      this.computeResourceId = null;
    }

    /** Returns true if field computeResourceId is set (has been assigned a value) and false otherwise */
    public boolean isSetComputeResourceId() {
      return this.computeResourceId != null;
    }

    public void setComputeResourceIdIsSet(boolean value) {
      if (!value) {
        this.computeResourceId = null;
      }
    }

    public void setFieldValue(_Fields field, 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((String)value);
        }
        break;

      case COMPUTE_RESOURCE_ID:
        if (value == null) {
          unsetComputeResourceId();
        } else {
          setComputeResourceId((String)value);
        }
        break;

      }
    }

    public Object getFieldValue(_Fields field) {
      switch (field) {
      case AUTHZ_TOKEN:
        return getAuthzToken();

      case GATEWAY_ID:
        return getGatewayID();

      case COMPUTE_RESOURCE_ID:
        return getComputeResourceId();

      }
      throw new IllegalStateException();
    }

    /** Returns true if field corresponding to fieldID is set (has been assigned a value) and false otherwise */
    public boolean isSet(_Fields field) {
      if (field == null) {
        throw new IllegalArgumentException();
      }

      switch (field) {
      case AUTHZ_TOKEN:
        return isSetAuthzToken();
      case GATEWAY_ID:
        return isSetGatewayID();
      case COMPUTE_RESOURCE_ID:
        return isSetComputeResourceId();
      }
      throw new IllegalStateException();
    }

    @Override
    public boolean equals(Object that) {
      if (that == null)
        return false;
      if (that instanceof getGatewayComputeResourcePreference_args)
        return this.equals((getGatewayComputeResourcePreference_args)that);
      return false;
    }

    public boolean equals(getGatewayComputeResourcePreference_args that) {
      if (that == null)
        return false;

      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;
      }

      boolean this_present_computeResourceId = true && this.isSetComputeResourceId();
      boolean that_present_computeResourceId = true && that.isSetComputeResourceId();
      if (this_present_computeResourceId || that_present_computeResourceId) {
        if (!(this_present_computeResourceId && that_present_computeResourceId))
          return false;
        if (!this.computeResourceId.equals(that.computeResourceId))
          return false;
      }

      return true;
    }

    @Override
    public int hashCode() {
      List<Object> list = new ArrayList<Object>();

      boolean present_authzToken = true && (isSetAuthzToken());
      list.add(present_authzToken);
      if (present_authzToken)
        list.add(authzToken);

      boolean present_gatewayID = true && (isSetGatewayID());
      list.add(present_gatewayID);
      if (present_gatewayID)
        list.add(gatewayID);

      boolean present_computeResourceId = true && (isSetComputeResourceId());
      list.add(present_computeResourceId);
      if (present_computeResourceId)
        list.add(computeResourceId);

      return list.hashCode();
    }

    @Override
    public int compareTo(getGatewayComputeResourcePreference_args other) {
      if (!getClass().equals(other.getClass())) {
        return getClass().getName().compareTo(other.getClass().getName());
      }

      int lastComparison = 0;

      lastComparison = 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 = 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;
        }
      }
      lastComparison = Boolean.valueOf(isSetComputeResourceId()).compareTo(other.isSetComputeResourceId());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetComputeResourceId()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.computeResourceId, other.computeResourceId);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      return 0;
    }

    public _Fields fieldForId(int fieldId) {
      return _Fields.findByThriftId(fieldId);
    }

    public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
      schemes.get(iprot.getScheme()).getScheme().read(iprot, this);
    }

    public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException {
      schemes.get(oprot.getScheme()).getScheme().write(oprot, this);
    }

    @Override
    public String toString() {
      StringBuilder sb = new StringBuilder("getGatewayComputeResourcePreference_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;
      if (!first) sb.append(", ");
      sb.append("computeResourceId:");
      if (this.computeResourceId == null) {
        sb.append("null");
      } else {
        sb.append(this.computeResourceId);
      }
      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());
      }
      if (computeResourceId == null) {
        throw new org.apache.thrift.protocol.TProtocolException("Required field 'computeResourceId' 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, 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 getGatewayComputeResourcePreference_argsStandardSchemeFactory implements SchemeFactory {
      public getGatewayComputeResourcePreference_argsStandardScheme getScheme() {
        return new getGatewayComputeResourcePreference_argsStandardScheme();
      }
    }

    private static class getGatewayComputeResourcePreference_argsStandardScheme extends StandardScheme<getGatewayComputeResourcePreference_args> {

      public void read(org.apache.thrift.protocol.TProtocol iprot, getGatewayComputeResourcePreference_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;
            case 3: // COMPUTE_RESOURCE_ID
              if (schemeField.type == org.apache.thrift.protocol.TType.STRING) {
                struct.computeResourceId = iprot.readString();
                struct.setComputeResourceIdIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            default:
              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
          }
          iprot.readFieldEnd();
        }
        iprot.readStructEnd();

        // check for required fields of primitive type, which can't be checked in the validate method
        struct.validate();
      }

      public void write(org.apache.thrift.protocol.TProtocol oprot, getGatewayComputeResourcePreference_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();
        }
        if (struct.computeResourceId != null) {
          oprot.writeFieldBegin(COMPUTE_RESOURCE_ID_FIELD_DESC);
          oprot.writeString(struct.computeResourceId);
          oprot.writeFieldEnd();
        }
        oprot.writeFieldStop();
        oprot.writeStructEnd();
      }

    }

    private static class getGatewayComputeResourcePreference_argsTupleSchemeFactory implements SchemeFactory {
      public getGatewayComputeResourcePreference_argsTupleScheme getScheme() {
        return new getGatewayComputeResourcePreference_argsTupleScheme();
      }
    }

    private static class getGatewayComputeResourcePreference_argsTupleScheme extends TupleScheme<getGatewayComputeResourcePreference_args> {

      @Override
      public void write(org.apache.thrift.protocol.TProtocol prot, getGatewayComputeResourcePreference_args struct) throws org.apache.thrift.TException {
        TTupleProtocol oprot = (TTupleProtocol) prot;
        struct.authzToken.write(oprot);
        oprot.writeString(struct.gatewayID);
        oprot.writeString(struct.computeResourceId);
      }

      @Override
      public void read(org.apache.thrift.protocol.TProtocol prot, getGatewayComputeResourcePreference_args struct) throws org.apache.thrift.TException {
        TTupleProtocol iprot = (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);
        struct.computeResourceId = iprot.readString();
        struct.setComputeResourceIdIsSet(true);
      }
    }

  }

  public static class getGatewayComputeResourcePreference_result implements org.apache.thrift.TBase<getGatewayComputeResourcePreference_result, getGatewayComputeResourcePreference_result._Fields>, java.io.Serializable, Cloneable, Comparable<getGatewayComputeResourcePreference_result>   {
    private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("getGatewayComputeResourcePreference_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 IRE_FIELD_DESC = new org.apache.thrift.protocol.TField("ire", org.apache.thrift.protocol.TType.STRUCT, (short)1);
    private static final org.apache.thrift.protocol.TField ACE_FIELD_DESC = new org.apache.thrift.protocol.TField("ace", org.apache.thrift.protocol.TType.STRUCT, (short)2);
    private static final org.apache.thrift.protocol.TField ASE_FIELD_DESC = new org.apache.thrift.protocol.TField("ase", org.apache.thrift.protocol.TType.STRUCT, (short)3);
    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)4);

    private static final Map<Class<? extends IScheme>, SchemeFactory> schemes = new HashMap<Class<? extends IScheme>, SchemeFactory>();
    static {
      schemes.put(StandardScheme.class, new getGatewayComputeResourcePreference_resultStandardSchemeFactory());
      schemes.put(TupleScheme.class, new getGatewayComputeResourcePreference_resultTupleSchemeFactory());
    }

    public org.apache.airavata.model.appcatalog.gatewayprofile.ComputeResourcePreference success; // required
    public org.apache.airavata.model.error.InvalidRequestException ire; // required
    public org.apache.airavata.model.error.AiravataClientException ace; // required
    public org.apache.airavata.model.error.AiravataSystemException ase; // 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"),
      IRE((short)1, "ire"),
      ACE((short)2, "ace"),
      ASE((short)3, "ase"),
      AE((short)4, "ae");

      private static final Map<String, _Fields> byName = new HashMap<String, _Fields>();

      static {
        for (_Fields field : EnumSet.allOf(_Fields.class)) {
          byName.put(field.getFieldName(), field);
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, or null if its not found.
       */
      public static _Fields findByThriftId(int fieldId) {
        switch(fieldId) {
          case 0: // SUCCESS
            return SUCCESS;
          case 1: // IRE
            return IRE;
          case 2: // ACE
            return ACE;
          case 3: // ASE
            return ASE;
          case 4: // 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 IllegalArgumentException("Field " + fieldId + " doesn't exist!");
        return fields;
      }

      /**
       * Find the _Fields constant that matches name, or null if its not found.
       */
      public static _Fields findByName(String name) {
        return byName.get(name);
      }

      private final short _thriftId;
      private final String _fieldName;

      _Fields(short thriftId, String fieldName) {
        _thriftId = thriftId;
        _fieldName = fieldName;
      }

      public short getThriftFieldId() {
        return _thriftId;
      }

      public String getFieldName() {
        return _fieldName;
      }
    }

    // isset id assignments
    public static final Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
    static {
      Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new EnumMap<_Fields, org.apache.thrift.meta_data.FieldMetaData>(_Fields.class);
      tmpMap.put(_Fields.SUCCESS, new org.apache.thrift.meta_data.FieldMetaData("success", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.StructMetaData(org.apache.thrift.protocol.TType.STRUCT, org.apache.airavata.model.appcatalog.gatewayprofile.ComputeResourcePreference.class)));
      tmpMap.put(_Fields.IRE, new org.apache.thrift.meta_data.FieldMetaData("ire", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRUCT)));
      tmpMap.put(_Fields.ACE, new org.apache.thrift.meta_data.FieldMetaData("ace", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRUCT)));
      tmpMap.put(_Fields.ASE, new org.apache.thrift.meta_data.FieldMetaData("ase", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRUCT)));
      tmpMap.put(_Fields.AE, new org.apache.thrift.meta_data.FieldMetaData("ae", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRUCT)));
      metaDataMap = Collections.unmodifiableMap(tmpMap);
      org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(getGatewayComputeResourcePreference_result.class, metaDataMap);
    }

    public getGatewayComputeResourcePreference_result() {
    }

    public getGatewayComputeResourcePreference_result(
      org.apache.airavata.model.appcatalog.gatewayprofile.ComputeResourcePreference success,
      org.apache.airavata.model.error.InvalidRequestException ire,
      org.apache.airavata.model.error.AiravataClientException ace,
      org.apache.airavata.model.error.AiravataSystemException ase,
      org.apache.airavata.model.error.AuthorizationException ae)
    {
      this();
      this.success = success;
      this.ire = ire;
      this.ace = ace;
      this.ase = ase;
      this.ae = ae;
    }

    /**
     * Performs a deep copy on <i>other</i>.
     */
    public getGatewayComputeResourcePreference_result(getGatewayComputeResourcePreference_result other) {
      if (other.isSetSuccess()) {
        this.success = new org.apache.airavata.model.appcatalog.gatewayprofile.ComputeResourcePreference(other.success);
      }
      if (other.isSetIre()) {
        this.ire = new org.apache.airavata.model.error.InvalidRequestException(other.ire);
      }
      if (other.isSetAce()) {
        this.ace = new org.apache.airavata.model.error.AiravataClientException(other.ace);
      }
      if (other.isSetAse()) {
        this.ase = new org.apache.airavata.model.error.AiravataSystemException(other.ase);
      }
      if (other.isSetAe()) {
        this.ae = new org.apache.airavata.model.error.AuthorizationException(other.ae);
      }
    }

    public getGatewayComputeResourcePreference_result deepCopy() {
      return new getGatewayComputeResourcePreference_result(this);
    }

    @Override
    public void clear() {
      this.success = null;
      this.ire = null;
      this.ace = null;
      this.ase = null;
      this.ae = null;
    }

    public org.apache.airavata.model.appcatalog.gatewayprofile.ComputeResourcePreference getSuccess() {
      return this.success;
    }

    public getGatewayComputeResourcePreference_result setSuccess(org.apache.airavata.model.appcatalog.gatewayprofile.ComputeResourcePreference 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.model.error.InvalidRequestException getIre() {
      return this.ire;
    }

    public getGatewayComputeResourcePreference_result setIre(org.apache.airavata.model.error.InvalidRequestException ire) {
      this.ire = ire;
      return this;
    }

    public void unsetIre() {
      this.ire = null;
    }

    /** Returns true if field ire is set (has been assigned a value) and false otherwise */
    public boolean isSetIre() {
      return this.ire != null;
    }

    public void setIreIsSet(boolean value) {
      if (!value) {
        this.ire = null;
      }
    }

    public org.apache.airavata.model.error.AiravataClientException getAce() {
      return this.ace;
    }

    public getGatewayComputeResourcePreference_result setAce(org.apache.airavata.model.error.AiravataClientException ace) {
      this.ace = ace;
      return this;
    }

    public void unsetAce() {
      this.ace = null;
    }

    /** Returns true if field ace is set (has been assigned a value) and false otherwise */
    public boolean isSetAce() {
      return this.ace != null;
    }

    public void setAceIsSet(boolean value) {
      if (!value) {
        this.ace = null;
      }
    }

    public org.apache.airavata.model.error.AiravataSystemException getAse() {
      return this.ase;
    }

    public getGatewayComputeResourcePreference_result setAse(org.apache.airavata.model.error.AiravataSystemException ase) {
      this.ase = ase;
      return this;
    }

    public void unsetAse() {
      this.ase = null;
    }

    /** Returns true if field ase is set (has been assigned a value) and false otherwise */
    public boolean isSetAse() {
      return this.ase != null;
    }

    public void setAseIsSet(boolean value) {
      if (!value) {
        this.ase = null;
      }
    }

    public org.apache.airavata.model.error.AuthorizationException getAe() {
      return this.ae;
    }

    public getGatewayComputeResourcePreference_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, Object value) {
      switch (field) {
      case SUCCESS:
        if (value == null) {
          unsetSuccess();
        } else {
          setSuccess((org.apache.airavata.model.appcatalog.gatewayprofile.ComputeResourcePreference)value);
        }
        break;

      case IRE:
        if (value == null) {
          unsetIre();
        } else {
          setIre((org.apache.airavata.model.error.InvalidRequestException)value);
        }
        break;

      case ACE:
        if (value == null) {
          unsetAce();
        } else {
          setAce((org.apache.airavata.model.error.AiravataClientException)value);
        }
        break;

      case ASE:
        if (value == null) {
          unsetAse();
        } else {
          setAse((org.apache.airavata.model.error.AiravataSystemException)value);
        }
        break;

      case AE:
        if (value == null) {
          unsetAe();
        } else {
          setAe((org.apache.airavata.model.error.AuthorizationException)value);
        }
        break;

      }
    }

    public Object getFieldValue(_Fields field) {
      switch (field) {
      case SUCCESS:
        return getSuccess();

      case IRE:
        return getIre();

      case ACE:
        return getAce();

      case ASE:
        return getAse();

      case AE:
        return getAe();

      }
      throw new IllegalStateException();
    }

    /** Returns true if field corresponding to fieldID is set (has been assigned a value) and false otherwise */
    public boolean isSet(_Fields field) {
      if (field == null) {
        throw new IllegalArgumentException();
      }

      switch (field) {
      case SUCCESS:
        return isSetSuccess();
      case IRE:
        return isSetIre();
      case ACE:
        return isSetAce();
      case ASE:
        return isSetAse();
      case AE:
        return isSetAe();
      }
      throw new IllegalStateException();
    }

    @Override
    public boolean equals(Object that) {
      if (that == null)
        return false;
      if (that instanceof getGatewayComputeResourcePreference_result)
        return this.equals((getGatewayComputeResourcePreference_result)that);
      return false;
    }

    public boolean equals(getGatewayComputeResourcePreference_result that) {
      if (that == null)
        return false;

      boolean this_present_success = true && this.isSetSuccess();
      boolean that_present_success = true && that.isSetSuccess();
      if (this_present_success || that_present_success) {
        if (!(this_present_success && that_present_success))
          return false;
        if (!this.success.equals(that.success))
          return false;
      }

      boolean this_present_ire = true && this.isSetIre();
      boolean that_present_ire = true && that.isSetIre();
      if (this_present_ire || that_present_ire) {
        if (!(this_present_ire && that_present_ire))
          return false;
        if (!this.ire.equals(that.ire))
          return false;
      }

      boolean this_present_ace = true && this.isSetAce();
      boolean that_present_ace = true && that.isSetAce();
      if (this_present_ace || that_present_ace) {
        if (!(this_present_ace && that_present_ace))
          return false;
        if (!this.ace.equals(that.ace))
          return false;
      }

      boolean this_present_ase = true && this.isSetAse();
      boolean that_present_ase = true && that.isSetAse();
      if (this_present_ase || that_present_ase) {
        if (!(this_present_ase && that_present_ase))
          return false;
        if (!this.ase.equals(that.ase))
          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() {
      List<Object> list = new ArrayList<Object>();

      boolean present_success = true && (isSetSuccess());
      list.add(present_success);
      if (present_success)
        list.add(success);

      boolean present_ire = true && (isSetIre());
      list.add(present_ire);
      if (present_ire)
        list.add(ire);

      boolean present_ace = true && (isSetAce());
      list.add(present_ace);
      if (present_ace)
        list.add(ace);

      boolean present_ase = true && (isSetAse());
      list.add(present_ase);
      if (present_ase)
        list.add(ase);

      boolean present_ae = true && (isSetAe());
      list.add(present_ae);
      if (present_ae)
        list.add(ae);

      return list.hashCode();
    }

    @Override
    public int compareTo(getGatewayComputeResourcePreference_result other) {
      if (!getClass().equals(other.getClass())) {
        return getClass().getName().compareTo(other.getClass().getName());
      }

      int lastComparison = 0;

      lastComparison = Boolean.valueOf(isSetSuccess()).compareTo(other.isSetSuccess());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetSuccess()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.success, other.success);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = Boolean.valueOf(isSetIre()).compareTo(other.isSetIre());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetIre()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.ire, other.ire);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = Boolean.valueOf(isSetAce()).compareTo(other.isSetAce());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetAce()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.ace, other.ace);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = Boolean.valueOf(isSetAse()).compareTo(other.isSetAse());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetAse()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.ase, other.ase);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = 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 {
      schemes.get(iprot.getScheme()).getScheme().read(iprot, this);
    }

    public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException {
      schemes.get(oprot.getScheme()).getScheme().write(oprot, this);
      }

    @Override
    public String toString() {
      StringBuilder sb = new StringBuilder("getGatewayComputeResourcePreference_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("ire:");
      if (this.ire == null) {
        sb.append("null");
      } else {
        sb.append(this.ire);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("ace:");
      if (this.ace == null) {
        sb.append("null");
      } else {
        sb.append(this.ace);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("ase:");
      if (this.ase == null) {
        sb.append("null");
      } else {
        sb.append(this.ase);
      }
      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, 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 getGatewayComputeResourcePreference_resultStandardSchemeFactory implements SchemeFactory {
      public getGatewayComputeResourcePreference_resultStandardScheme getScheme() {
        return new getGatewayComputeResourcePreference_resultStandardScheme();
      }
    }

    private static class getGatewayComputeResourcePreference_resultStandardScheme extends StandardScheme<getGatewayComputeResourcePreference_result> {

      public void read(org.apache.thrift.protocol.TProtocol iprot, getGatewayComputeResourcePreference_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.appcatalog.gatewayprofile.ComputeResourcePreference();
                struct.success.read(iprot);
                struct.setSuccessIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 1: // IRE
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.ire = new org.apache.airavata.model.error.InvalidRequestException();
                struct.ire.read(iprot);
                struct.setIreIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 2: // ACE
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.ace = new org.apache.airavata.model.error.AiravataClientException();
                struct.ace.read(iprot);
                struct.setAceIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 3: // ASE
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.ase = new org.apache.airavata.model.error.AiravataSystemException();
                struct.ase.read(iprot);
                struct.setAseIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 4: // 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, getGatewayComputeResourcePreference_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.ire != null) {
          oprot.writeFieldBegin(IRE_FIELD_DESC);
          struct.ire.write(oprot);
          oprot.writeFieldEnd();
        }
        if (struct.ace != null) {
          oprot.writeFieldBegin(ACE_FIELD_DESC);
          struct.ace.write(oprot);
          oprot.writeFieldEnd();
        }
        if (struct.ase != null) {
          oprot.writeFieldBegin(ASE_FIELD_DESC);
          struct.ase.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 getGatewayComputeResourcePreference_resultTupleSchemeFactory implements SchemeFactory {
      public getGatewayComputeResourcePreference_resultTupleScheme getScheme() {
        return new getGatewayComputeResourcePreference_resultTupleScheme();
      }
    }

    private static class getGatewayComputeResourcePreference_resultTupleScheme extends TupleScheme<getGatewayComputeResourcePreference_result> {

      @Override
      public void write(org.apache.thrift.protocol.TProtocol prot, getGatewayComputeResourcePreference_result struct) throws org.apache.thrift.TException {
        TTupleProtocol oprot = (TTupleProtocol) prot;
        BitSet optionals = new BitSet();
        if (struct.isSetSuccess()) {
          optionals.set(0);
        }
        if (struct.isSetIre()) {
          optionals.set(1);
        }
        if (struct.isSetAce()) {
          optionals.set(2);
        }
        if (struct.isSetAse()) {
          optionals.set(3);
        }
        if (struct.isSetAe()) {
          optionals.set(4);
        }
        oprot.writeBitSet(optionals, 5);
        if (struct.isSetSuccess()) {
          struct.success.write(oprot);
        }
        if (struct.isSetIre()) {
          struct.ire.write(oprot);
        }
        if (struct.isSetAce()) {
          struct.ace.write(oprot);
        }
        if (struct.isSetAse()) {
          struct.ase.write(oprot);
        }
        if (struct.isSetAe()) {
          struct.ae.write(oprot);
        }
      }

      @Override
      public void read(org.apache.thrift.protocol.TProtocol prot, getGatewayComputeResourcePreference_result struct) throws org.apache.thrift.TException {
        TTupleProtocol iprot = (TTupleProtocol) prot;
        BitSet incoming = iprot.readBitSet(5);
        if (incoming.get(0)) {
          struct.success = new org.apache.airavata.model.appcatalog.gatewayprofile.ComputeResourcePreference();
          struct.success.read(iprot);
          struct.setSuccessIsSet(true);
        }
        if (incoming.get(1)) {
          struct.ire = new org.apache.airavata.model.error.InvalidRequestException();
          struct.ire.read(iprot);
          struct.setIreIsSet(true);
        }
        if (incoming.get(2)) {
          struct.ace = new org.apache.airavata.model.error.AiravataClientException();
          struct.ace.read(iprot);
          struct.setAceIsSet(true);
        }
        if (incoming.get(3)) {
          struct.ase = new org.apache.airavata.model.error.AiravataSystemException();
          struct.ase.read(iprot);
          struct.setAseIsSet(true);
        }
        if (incoming.get(4)) {
          struct.ae = new org.apache.airavata.model.error.AuthorizationException();
          struct.ae.read(iprot);
          struct.setAeIsSet(true);
        }
      }
    }

  }

  public static class getGatewayDataStoragePreference_args implements org.apache.thrift.TBase<getGatewayDataStoragePreference_args, getGatewayDataStoragePreference_args._Fields>, java.io.Serializable, Cloneable, Comparable<getGatewayDataStoragePreference_args>   {
    private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("getGatewayDataStoragePreference_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.protocol.TField DATA_MOVE_ID_FIELD_DESC = new org.apache.thrift.protocol.TField("dataMoveId", org.apache.thrift.protocol.TType.STRING, (short)3);

    private static final Map<Class<? extends IScheme>, SchemeFactory> schemes = new HashMap<Class<? extends IScheme>, SchemeFactory>();
    static {
      schemes.put(StandardScheme.class, new getGatewayDataStoragePreference_argsStandardSchemeFactory());
      schemes.put(TupleScheme.class, new getGatewayDataStoragePreference_argsTupleSchemeFactory());
    }

    public org.apache.airavata.model.security.AuthzToken authzToken; // required
    public String gatewayID; // required
    public String dataMoveId; // required

    /** 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"),
      DATA_MOVE_ID((short)3, "dataMoveId");

      private static final Map<String, _Fields> byName = new HashMap<String, _Fields>();

      static {
        for (_Fields field : EnumSet.allOf(_Fields.class)) {
          byName.put(field.getFieldName(), field);
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, or null if its not found.
       */
      public static _Fields findByThriftId(int fieldId) {
        switch(fieldId) {
          case 1: // AUTHZ_TOKEN
            return AUTHZ_TOKEN;
          case 2: // GATEWAY_ID
            return GATEWAY_ID;
          case 3: // DATA_MOVE_ID
            return DATA_MOVE_ID;
          default:
            return null;
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, throwing an exception
       * if it is not found.
       */
      public static _Fields findByThriftIdOrThrow(int fieldId) {
        _Fields fields = findByThriftId(fieldId);
        if (fields == null) throw new IllegalArgumentException("Field " + fieldId + " doesn't exist!");
        return fields;
      }

      /**
       * Find the _Fields constant that matches name, or null if its not found.
       */
      public static _Fields findByName(String name) {
        return byName.get(name);
      }

      private final short _thriftId;
      private final String _fieldName;

      _Fields(short thriftId, String fieldName) {
        _thriftId = thriftId;
        _fieldName = fieldName;
      }

      public short getThriftFieldId() {
        return _thriftId;
      }

      public String getFieldName() {
        return _fieldName;
      }
    }

    // isset id assignments
    public static final Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
    static {
      Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new EnumMap<_Fields, org.apache.thrift.meta_data.FieldMetaData>(_Fields.class);
      tmpMap.put(_Fields.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)));
      tmpMap.put(_Fields.DATA_MOVE_ID, new org.apache.thrift.meta_data.FieldMetaData("dataMoveId", org.apache.thrift.TFieldRequirementType.REQUIRED, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING)));
      metaDataMap = Collections.unmodifiableMap(tmpMap);
      org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(getGatewayDataStoragePreference_args.class, metaDataMap);
    }

    public getGatewayDataStoragePreference_args() {
    }

    public getGatewayDataStoragePreference_args(
      org.apache.airavata.model.security.AuthzToken authzToken,
      String gatewayID,
      String dataMoveId)
    {
      this();
      this.authzToken = authzToken;
      this.gatewayID = gatewayID;
      this.dataMoveId = dataMoveId;
    }

    /**
     * Performs a deep copy on <i>other</i>.
     */
    public getGatewayDataStoragePreference_args(getGatewayDataStoragePreference_args other) {
      if (other.isSetAuthzToken()) {
        this.authzToken = new org.apache.airavata.model.security.AuthzToken(other.authzToken);
      }
      if (other.isSetGatewayID()) {
        this.gatewayID = other.gatewayID;
      }
      if (other.isSetDataMoveId()) {
        this.dataMoveId = other.dataMoveId;
      }
    }

    public getGatewayDataStoragePreference_args deepCopy() {
      return new getGatewayDataStoragePreference_args(this);
    }

    @Override
    public void clear() {
      this.authzToken = null;
      this.gatewayID = null;
      this.dataMoveId = null;
    }

    public org.apache.airavata.model.security.AuthzToken getAuthzToken() {
      return this.authzToken;
    }

    public getGatewayDataStoragePreference_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 String getGatewayID() {
      return this.gatewayID;
    }

    public getGatewayDataStoragePreference_args setGatewayID(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 String getDataMoveId() {
      return this.dataMoveId;
    }

    public getGatewayDataStoragePreference_args setDataMoveId(String dataMoveId) {
      this.dataMoveId = dataMoveId;
      return this;
    }

    public void unsetDataMoveId() {
      this.dataMoveId = null;
    }

    /** Returns true if field dataMoveId is set (has been assigned a value) and false otherwise */
    public boolean isSetDataMoveId() {
      return this.dataMoveId != null;
    }

    public void setDataMoveIdIsSet(boolean value) {
      if (!value) {
        this.dataMoveId = null;
      }
    }

    public void setFieldValue(_Fields field, 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((String)value);
        }
        break;

      case DATA_MOVE_ID:
        if (value == null) {
          unsetDataMoveId();
        } else {
          setDataMoveId((String)value);
        }
        break;

      }
    }

    public Object getFieldValue(_Fields field) {
      switch (field) {
      case AUTHZ_TOKEN:
        return getAuthzToken();

      case GATEWAY_ID:
        return getGatewayID();

      case DATA_MOVE_ID:
        return getDataMoveId();

      }
      throw new IllegalStateException();
    }

    /** Returns true if field corresponding to fieldID is set (has been assigned a value) and false otherwise */
    public boolean isSet(_Fields field) {
      if (field == null) {
        throw new IllegalArgumentException();
      }

      switch (field) {
      case AUTHZ_TOKEN:
        return isSetAuthzToken();
      case GATEWAY_ID:
        return isSetGatewayID();
      case DATA_MOVE_ID:
        return isSetDataMoveId();
      }
      throw new IllegalStateException();
    }

    @Override
    public boolean equals(Object that) {
      if (that == null)
        return false;
      if (that instanceof getGatewayDataStoragePreference_args)
        return this.equals((getGatewayDataStoragePreference_args)that);
      return false;
    }

    public boolean equals(getGatewayDataStoragePreference_args that) {
      if (that == null)
        return false;

      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;
      }

      boolean this_present_dataMoveId = true && this.isSetDataMoveId();
      boolean that_present_dataMoveId = true && that.isSetDataMoveId();
      if (this_present_dataMoveId || that_present_dataMoveId) {
        if (!(this_present_dataMoveId && that_present_dataMoveId))
          return false;
        if (!this.dataMoveId.equals(that.dataMoveId))
          return false;
      }

      return true;
    }

    @Override
    public int hashCode() {
      List<Object> list = new ArrayList<Object>();

      boolean present_authzToken = true && (isSetAuthzToken());
      list.add(present_authzToken);
      if (present_authzToken)
        list.add(authzToken);

      boolean present_gatewayID = true && (isSetGatewayID());
      list.add(present_gatewayID);
      if (present_gatewayID)
        list.add(gatewayID);

      boolean present_dataMoveId = true && (isSetDataMoveId());
      list.add(present_dataMoveId);
      if (present_dataMoveId)
        list.add(dataMoveId);

      return list.hashCode();
    }

    @Override
    public int compareTo(getGatewayDataStoragePreference_args other) {
      if (!getClass().equals(other.getClass())) {
        return getClass().getName().compareTo(other.getClass().getName());
      }

      int lastComparison = 0;

      lastComparison = 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 = 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;
        }
      }
      lastComparison = Boolean.valueOf(isSetDataMoveId()).compareTo(other.isSetDataMoveId());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetDataMoveId()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.dataMoveId, other.dataMoveId);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      return 0;
    }

    public _Fields fieldForId(int fieldId) {
      return _Fields.findByThriftId(fieldId);
    }

    public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
      schemes.get(iprot.getScheme()).getScheme().read(iprot, this);
    }

    public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException {
      schemes.get(oprot.getScheme()).getScheme().write(oprot, this);
    }

    @Override
    public String toString() {
      StringBuilder sb = new StringBuilder("getGatewayDataStoragePreference_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;
      if (!first) sb.append(", ");
      sb.append("dataMoveId:");
      if (this.dataMoveId == null) {
        sb.append("null");
      } else {
        sb.append(this.dataMoveId);
      }
      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());
      }
      if (dataMoveId == null) {
        throw new org.apache.thrift.protocol.TProtocolException("Required field 'dataMoveId' 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, 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 getGatewayDataStoragePreference_argsStandardSchemeFactory implements SchemeFactory {
      public getGatewayDataStoragePreference_argsStandardScheme getScheme() {
        return new getGatewayDataStoragePreference_argsStandardScheme();
      }
    }

    private static class getGatewayDataStoragePreference_argsStandardScheme extends StandardScheme<getGatewayDataStoragePreference_args> {

      public void read(org.apache.thrift.protocol.TProtocol iprot, getGatewayDataStoragePreference_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;
            case 3: // DATA_MOVE_ID
              if (schemeField.type == org.apache.thrift.protocol.TType.STRING) {
                struct.dataMoveId = iprot.readString();
                struct.setDataMoveIdIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            default:
              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
          }
          iprot.readFieldEnd();
        }
        iprot.readStructEnd();

        // check for required fields of primitive type, which can't be checked in the validate method
        struct.validate();
      }

      public void write(org.apache.thrift.protocol.TProtocol oprot, getGatewayDataStoragePreference_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();
        }
        if (struct.dataMoveId != null) {
          oprot.writeFieldBegin(DATA_MOVE_ID_FIELD_DESC);
          oprot.writeString(struct.dataMoveId);
          oprot.writeFieldEnd();
        }
        oprot.writeFieldStop();
        oprot.writeStructEnd();
      }

    }

    private static class getGatewayDataStoragePreference_argsTupleSchemeFactory implements SchemeFactory {
      public getGatewayDataStoragePreference_argsTupleScheme getScheme() {
        return new getGatewayDataStoragePreference_argsTupleScheme();
      }
    }

    private static class getGatewayDataStoragePreference_argsTupleScheme extends TupleScheme<getGatewayDataStoragePreference_args> {

      @Override
      public void write(org.apache.thrift.protocol.TProtocol prot, getGatewayDataStoragePreference_args struct) throws org.apache.thrift.TException {
        TTupleProtocol oprot = (TTupleProtocol) prot;
        struct.authzToken.write(oprot);
        oprot.writeString(struct.gatewayID);
        oprot.writeString(struct.dataMoveId);
      }

      @Override
      public void read(org.apache.thrift.protocol.TProtocol prot, getGatewayDataStoragePreference_args struct) throws org.apache.thrift.TException {
        TTupleProtocol iprot = (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);
        struct.dataMoveId = iprot.readString();
        struct.setDataMoveIdIsSet(true);
      }
    }

  }

  public static class getGatewayDataStoragePreference_result implements org.apache.thrift.TBase<getGatewayDataStoragePreference_result, getGatewayDataStoragePreference_result._Fields>, java.io.Serializable, Cloneable, Comparable<getGatewayDataStoragePreference_result>   {
    private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("getGatewayDataStoragePreference_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 IRE_FIELD_DESC = new org.apache.thrift.protocol.TField("ire", org.apache.thrift.protocol.TType.STRUCT, (short)1);
    private static final org.apache.thrift.protocol.TField ACE_FIELD_DESC = new org.apache.thrift.protocol.TField("ace", org.apache.thrift.protocol.TType.STRUCT, (short)2);
    private static final org.apache.thrift.protocol.TField ASE_FIELD_DESC = new org.apache.thrift.protocol.TField("ase", org.apache.thrift.protocol.TType.STRUCT, (short)3);
    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)4);

    private static final Map<Class<? extends IScheme>, SchemeFactory> schemes = new HashMap<Class<? extends IScheme>, SchemeFactory>();
    static {
      schemes.put(StandardScheme.class, new getGatewayDataStoragePreference_resultStandardSchemeFactory());
      schemes.put(TupleScheme.class, new getGatewayDataStoragePreference_resultTupleSchemeFactory());
    }

    public org.apache.airavata.model.appcatalog.gatewayprofile.DataStoragePreference success; // required
    public org.apache.airavata.model.error.InvalidRequestException ire; // required
    public org.apache.airavata.model.error.AiravataClientException ace; // required
    public org.apache.airavata.model.error.AiravataSystemException ase; // 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"),
      IRE((short)1, "ire"),
      ACE((short)2, "ace"),
      ASE((short)3, "ase"),
      AE((short)4, "ae");

      private static final Map<String, _Fields> byName = new HashMap<String, _Fields>();

      static {
        for (_Fields field : EnumSet.allOf(_Fields.class)) {
          byName.put(field.getFieldName(), field);
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, or null if its not found.
       */
      public static _Fields findByThriftId(int fieldId) {
        switch(fieldId) {
          case 0: // SUCCESS
            return SUCCESS;
          case 1: // IRE
            return IRE;
          case 2: // ACE
            return ACE;
          case 3: // ASE
            return ASE;
          case 4: // 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 IllegalArgumentException("Field " + fieldId + " doesn't exist!");
        return fields;
      }

      /**
       * Find the _Fields constant that matches name, or null if its not found.
       */
      public static _Fields findByName(String name) {
        return byName.get(name);
      }

      private final short _thriftId;
      private final String _fieldName;

      _Fields(short thriftId, String fieldName) {
        _thriftId = thriftId;
        _fieldName = fieldName;
      }

      public short getThriftFieldId() {
        return _thriftId;
      }

      public String getFieldName() {
        return _fieldName;
      }
    }

    // isset id assignments
    public static final Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
    static {
      Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new EnumMap<_Fields, org.apache.thrift.meta_data.FieldMetaData>(_Fields.class);
      tmpMap.put(_Fields.SUCCESS, new org.apache.thrift.meta_data.FieldMetaData("success", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.StructMetaData(org.apache.thrift.protocol.TType.STRUCT, org.apache.airavata.model.appcatalog.gatewayprofile.DataStoragePreference.class)));
      tmpMap.put(_Fields.IRE, new org.apache.thrift.meta_data.FieldMetaData("ire", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRUCT)));
      tmpMap.put(_Fields.ACE, new org.apache.thrift.meta_data.FieldMetaData("ace", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRUCT)));
      tmpMap.put(_Fields.ASE, new org.apache.thrift.meta_data.FieldMetaData("ase", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRUCT)));
      tmpMap.put(_Fields.AE, new org.apache.thrift.meta_data.FieldMetaData("ae", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRUCT)));
      metaDataMap = Collections.unmodifiableMap(tmpMap);
      org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(getGatewayDataStoragePreference_result.class, metaDataMap);
    }

    public getGatewayDataStoragePreference_result() {
    }

    public getGatewayDataStoragePreference_result(
      org.apache.airavata.model.appcatalog.gatewayprofile.DataStoragePreference success,
      org.apache.airavata.model.error.InvalidRequestException ire,
      org.apache.airavata.model.error.AiravataClientException ace,
      org.apache.airavata.model.error.AiravataSystemException ase,
      org.apache.airavata.model.error.AuthorizationException ae)
    {
      this();
      this.success = success;
      this.ire = ire;
      this.ace = ace;
      this.ase = ase;
      this.ae = ae;
    }

    /**
     * Performs a deep copy on <i>other</i>.
     */
    public getGatewayDataStoragePreference_result(getGatewayDataStoragePreference_result other) {
      if (other.isSetSuccess()) {
        this.success = new org.apache.airavata.model.appcatalog.gatewayprofile.DataStoragePreference(other.success);
      }
      if (other.isSetIre()) {
        this.ire = new org.apache.airavata.model.error.InvalidRequestException(other.ire);
      }
      if (other.isSetAce()) {
        this.ace = new org.apache.airavata.model.error.AiravataClientException(other.ace);
      }
      if (other.isSetAse()) {
        this.ase = new org.apache.airavata.model.error.AiravataSystemException(other.ase);
      }
      if (other.isSetAe()) {
        this.ae = new org.apache.airavata.model.error.AuthorizationException(other.ae);
      }
    }

    public getGatewayDataStoragePreference_result deepCopy() {
      return new getGatewayDataStoragePreference_result(this);
    }

    @Override
    public void clear() {
      this.success = null;
      this.ire = null;
      this.ace = null;
      this.ase = null;
      this.ae = null;
    }

    public org.apache.airavata.model.appcatalog.gatewayprofile.DataStoragePreference getSuccess() {
      return this.success;
    }

    public getGatewayDataStoragePreference_result setSuccess(org.apache.airavata.model.appcatalog.gatewayprofile.DataStoragePreference 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.model.error.InvalidRequestException getIre() {
      return this.ire;
    }

    public getGatewayDataStoragePreference_result setIre(org.apache.airavata.model.error.InvalidRequestException ire) {
      this.ire = ire;
      return this;
    }

    public void unsetIre() {
      this.ire = null;
    }

    /** Returns true if field ire is set (has been assigned a value) and false otherwise */
    public boolean isSetIre() {
      return this.ire != null;
    }

    public void setIreIsSet(boolean value) {
      if (!value) {
        this.ire = null;
      }
    }

    public org.apache.airavata.model.error.AiravataClientException getAce() {
      return this.ace;
    }

    public getGatewayDataStoragePreference_result setAce(org.apache.airavata.model.error.AiravataClientException ace) {
      this.ace = ace;
      return this;
    }

    public void unsetAce() {
      this.ace = null;
    }

    /** Returns true if field ace is set (has been assigned a value) and false otherwise */
    public boolean isSetAce() {
      return this.ace != null;
    }

    public void setAceIsSet(boolean value) {
      if (!value) {
        this.ace = null;
      }
    }

    public org.apache.airavata.model.error.AiravataSystemException getAse() {
      return this.ase;
    }

    public getGatewayDataStoragePreference_result setAse(org.apache.airavata.model.error.AiravataSystemException ase) {
      this.ase = ase;
      return this;
    }

    public void unsetAse() {
      this.ase = null;
    }

    /** Returns true if field ase is set (has been assigned a value) and false otherwise */
    public boolean isSetAse() {
      return this.ase != null;
    }

    public void setAseIsSet(boolean value) {
      if (!value) {
        this.ase = null;
      }
    }

    public org.apache.airavata.model.error.AuthorizationException getAe() {
      return this.ae;
    }

    public getGatewayDataStoragePreference_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, Object value) {
      switch (field) {
      case SUCCESS:
        if (value == null) {
          unsetSuccess();
        } else {
          setSuccess((org.apache.airavata.model.appcatalog.gatewayprofile.DataStoragePreference)value);
        }
        break;

      case IRE:
        if (value == null) {
          unsetIre();
        } else {
          setIre((org.apache.airavata.model.error.InvalidRequestException)value);
        }
        break;

      case ACE:
        if (value == null) {
          unsetAce();
        } else {
          setAce((org.apache.airavata.model.error.AiravataClientException)value);
        }
        break;

      case ASE:
        if (value == null) {
          unsetAse();
        } else {
          setAse((org.apache.airavata.model.error.AiravataSystemException)value);
        }
        break;

      case AE:
        if (value == null) {
          unsetAe();
        } else {
          setAe((org.apache.airavata.model.error.AuthorizationException)value);
        }
        break;

      }
    }

    public Object getFieldValue(_Fields field) {
      switch (field) {
      case SUCCESS:
        return getSuccess();

      case IRE:
        return getIre();

      case ACE:
        return getAce();

      case ASE:
        return getAse();

      case AE:
        return getAe();

      }
      throw new IllegalStateException();
    }

    /** Returns true if field corresponding to fieldID is set (has been assigned a value) and false otherwise */
    public boolean isSet(_Fields field) {
      if (field == null) {
        throw new IllegalArgumentException();
      }

      switch (field) {
      case SUCCESS:
        return isSetSuccess();
      case IRE:
        return isSetIre();
      case ACE:
        return isSetAce();
      case ASE:
        return isSetAse();
      case AE:
        return isSetAe();
      }
      throw new IllegalStateException();
    }

    @Override
    public boolean equals(Object that) {
      if (that == null)
        return false;
      if (that instanceof getGatewayDataStoragePreference_result)
        return this.equals((getGatewayDataStoragePreference_result)that);
      return false;
    }

    public boolean equals(getGatewayDataStoragePreference_result that) {
      if (that == null)
        return false;

      boolean this_present_success = true && this.isSetSuccess();
      boolean that_present_success = true && that.isSetSuccess();
      if (this_present_success || that_present_success) {
        if (!(this_present_success && that_present_success))
          return false;
        if (!this.success.equals(that.success))
          return false;
      }

      boolean this_present_ire = true && this.isSetIre();
      boolean that_present_ire = true && that.isSetIre();
      if (this_present_ire || that_present_ire) {
        if (!(this_present_ire && that_present_ire))
          return false;
        if (!this.ire.equals(that.ire))
          return false;
      }

      boolean this_present_ace = true && this.isSetAce();
      boolean that_present_ace = true && that.isSetAce();
      if (this_present_ace || that_present_ace) {
        if (!(this_present_ace && that_present_ace))
          return false;
        if (!this.ace.equals(that.ace))
          return false;
      }

      boolean this_present_ase = true && this.isSetAse();
      boolean that_present_ase = true && that.isSetAse();
      if (this_present_ase || that_present_ase) {
        if (!(this_present_ase && that_present_ase))
          return false;
        if (!this.ase.equals(that.ase))
          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() {
      List<Object> list = new ArrayList<Object>();

      boolean present_success = true && (isSetSuccess());
      list.add(present_success);
      if (present_success)
        list.add(success);

      boolean present_ire = true && (isSetIre());
      list.add(present_ire);
      if (present_ire)
        list.add(ire);

      boolean present_ace = true && (isSetAce());
      list.add(present_ace);
      if (present_ace)
        list.add(ace);

      boolean present_ase = true && (isSetAse());
      list.add(present_ase);
      if (present_ase)
        list.add(ase);

      boolean present_ae = true && (isSetAe());
      list.add(present_ae);
      if (present_ae)
        list.add(ae);

      return list.hashCode();
    }

    @Override
    public int compareTo(getGatewayDataStoragePreference_result other) {
      if (!getClass().equals(other.getClass())) {
        return getClass().getName().compareTo(other.getClass().getName());
      }

      int lastComparison = 0;

      lastComparison = Boolean.valueOf(isSetSuccess()).compareTo(other.isSetSuccess());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetSuccess()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.success, other.success);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = Boolean.valueOf(isSetIre()).compareTo(other.isSetIre());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetIre()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.ire, other.ire);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = Boolean.valueOf(isSetAce()).compareTo(other.isSetAce());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetAce()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.ace, other.ace);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = Boolean.valueOf(isSetAse()).compareTo(other.isSetAse());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetAse()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.ase, other.ase);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = 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 {
      schemes.get(iprot.getScheme()).getScheme().read(iprot, this);
    }

    public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException {
      schemes.get(oprot.getScheme()).getScheme().write(oprot, this);
      }

    @Override
    public String toString() {
      StringBuilder sb = new StringBuilder("getGatewayDataStoragePreference_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("ire:");
      if (this.ire == null) {
        sb.append("null");
      } else {
        sb.append(this.ire);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("ace:");
      if (this.ace == null) {
        sb.append("null");
      } else {
        sb.append(this.ace);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("ase:");
      if (this.ase == null) {
        sb.append("null");
      } else {
        sb.append(this.ase);
      }
      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, 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 getGatewayDataStoragePreference_resultStandardSchemeFactory implements SchemeFactory {
      public getGatewayDataStoragePreference_resultStandardScheme getScheme() {
        return new getGatewayDataStoragePreference_resultStandardScheme();
      }
    }

    private static class getGatewayDataStoragePreference_resultStandardScheme extends StandardScheme<getGatewayDataStoragePreference_result> {

      public void read(org.apache.thrift.protocol.TProtocol iprot, getGatewayDataStoragePreference_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.appcatalog.gatewayprofile.DataStoragePreference();
                struct.success.read(iprot);
                struct.setSuccessIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 1: // IRE
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.ire = new org.apache.airavata.model.error.InvalidRequestException();
                struct.ire.read(iprot);
                struct.setIreIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 2: // ACE
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.ace = new org.apache.airavata.model.error.AiravataClientException();
                struct.ace.read(iprot);
                struct.setAceIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 3: // ASE
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.ase = new org.apache.airavata.model.error.AiravataSystemException();
                struct.ase.read(iprot);
                struct.setAseIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 4: // 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, getGatewayDataStoragePreference_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.ire != null) {
          oprot.writeFieldBegin(IRE_FIELD_DESC);
          struct.ire.write(oprot);
          oprot.writeFieldEnd();
        }
        if (struct.ace != null) {
          oprot.writeFieldBegin(ACE_FIELD_DESC);
          struct.ace.write(oprot);
          oprot.writeFieldEnd();
        }
        if (struct.ase != null) {
          oprot.writeFieldBegin(ASE_FIELD_DESC);
          struct.ase.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 getGatewayDataStoragePreference_resultTupleSchemeFactory implements SchemeFactory {
      public getGatewayDataStoragePreference_resultTupleScheme getScheme() {
        return new getGatewayDataStoragePreference_resultTupleScheme();
      }
    }

    private static class getGatewayDataStoragePreference_resultTupleScheme extends TupleScheme<getGatewayDataStoragePreference_result> {

      @Override
      public void write(org.apache.thrift.protocol.TProtocol prot, getGatewayDataStoragePreference_result struct) throws org.apache.thrift.TException {
        TTupleProtocol oprot = (TTupleProtocol) prot;
        BitSet optionals = new BitSet();
        if (struct.isSetSuccess()) {
          optionals.set(0);
        }
        if (struct.isSetIre()) {
          optionals.set(1);
        }
        if (struct.isSetAce()) {
          optionals.set(2);
        }
        if (struct.isSetAse()) {
          optionals.set(3);
        }
        if (struct.isSetAe()) {
          optionals.set(4);
        }
        oprot.writeBitSet(optionals, 5);
        if (struct.isSetSuccess()) {
          struct.success.write(oprot);
        }
        if (struct.isSetIre()) {
          struct.ire.write(oprot);
        }
        if (struct.isSetAce()) {
          struct.ace.write(oprot);
        }
        if (struct.isSetAse()) {
          struct.ase.write(oprot);
        }
        if (struct.isSetAe()) {
          struct.ae.write(oprot);
        }
      }

      @Override
      public void read(org.apache.thrift.protocol.TProtocol prot, getGatewayDataStoragePreference_result struct) throws org.apache.thrift.TException {
        TTupleProtocol iprot = (TTupleProtocol) prot;
        BitSet incoming = iprot.readBitSet(5);
        if (incoming.get(0)) {
          struct.success = new org.apache.airavata.model.appcatalog.gatewayprofile.DataStoragePreference();
          struct.success.read(iprot);
          struct.setSuccessIsSet(true);
        }
        if (incoming.get(1)) {
          struct.ire = new org.apache.airavata.model.error.InvalidRequestException();
          struct.ire.read(iprot);
          struct.setIreIsSet(true);
        }
        if (incoming.get(2)) {
          struct.ace = new org.apache.airavata.model.error.AiravataClientException();
          struct.ace.read(iprot);
          struct.setAceIsSet(true);
        }
        if (incoming.get(3)) {
          struct.ase = new org.apache.airavata.model.error.AiravataSystemException();
          struct.ase.read(iprot);
          struct.setAseIsSet(true);
        }
        if (incoming.get(4)) {
          struct.ae = new org.apache.airavata.model.error.AuthorizationException();
          struct.ae.read(iprot);
          struct.setAeIsSet(true);
        }
      }
    }

  }

  public static class getAllGatewayComputeResourcePreferences_args implements org.apache.thrift.TBase<getAllGatewayComputeResourcePreferences_args, getAllGatewayComputeResourcePreferences_args._Fields>, java.io.Serializable, Cloneable, Comparable<getAllGatewayComputeResourcePreferences_args>   {
    private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("getAllGatewayComputeResourcePreferences_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 Map<Class<? extends IScheme>, SchemeFactory> schemes = new HashMap<Class<? extends IScheme>, SchemeFactory>();
    static {
      schemes.put(StandardScheme.class, new getAllGatewayComputeResourcePreferences_argsStandardSchemeFactory());
      schemes.put(TupleScheme.class, new getAllGatewayComputeResourcePreferences_argsTupleSchemeFactory());
    }

    public org.apache.airavata.model.security.AuthzToken authzToken; // required
    public 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 Map<String, _Fields> byName = new HashMap<String, _Fields>();

      static {
        for (_Fields field : EnumSet.allOf(_Fields.class)) {
          byName.put(field.getFieldName(), field);
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, or null if its not found.
       */
      public static _Fields findByThriftId(int fieldId) {
        switch(fieldId) {
          case 1: // 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 IllegalArgumentException("Field " + fieldId + " doesn't exist!");
        return fields;
      }

      /**
       * Find the _Fields constant that matches name, or null if its not found.
       */
      public static _Fields findByName(String name) {
        return byName.get(name);
      }

      private final short _thriftId;
      private final String _fieldName;

      _Fields(short thriftId, String fieldName) {
        _thriftId = thriftId;
        _fieldName = fieldName;
      }

      public short getThriftFieldId() {
        return _thriftId;
      }

      public String getFieldName() {
        return _fieldName;
      }
    }

    // isset id assignments
    public static final Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
    static {
      Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new EnumMap<_Fields, org.apache.thrift.meta_data.FieldMetaData>(_Fields.class);
      tmpMap.put(_Fields.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 = Collections.unmodifiableMap(tmpMap);
      org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(getAllGatewayComputeResourcePreferences_args.class, metaDataMap);
    }

    public getAllGatewayComputeResourcePreferences_args() {
    }

    public getAllGatewayComputeResourcePreferences_args(
      org.apache.airavata.model.security.AuthzToken authzToken,
      String gatewayID)
    {
      this();
      this.authzToken = authzToken;
      this.gatewayID = gatewayID;
    }

    /**
     * Performs a deep copy on <i>other</i>.
     */
    public getAllGatewayComputeResourcePreferences_args(getAllGatewayComputeResourcePreferences_args other) {
      if (other.isSetAuthzToken()) {
        this.authzToken = new org.apache.airavata.model.security.AuthzToken(other.authzToken);
      }
      if (other.isSetGatewayID()) {
        this.gatewayID = other.gatewayID;
      }
    }

    public getAllGatewayComputeResourcePreferences_args deepCopy() {
      return new getAllGatewayComputeResourcePreferences_args(this);
    }

    @Override
    public void clear() {
      this.authzToken = null;
      this.gatewayID = null;
    }

    public org.apache.airavata.model.security.AuthzToken getAuthzToken() {
      return this.authzToken;
    }

    public getAllGatewayComputeResourcePreferences_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 String getGatewayID() {
      return this.gatewayID;
    }

    public getAllGatewayComputeResourcePreferences_args setGatewayID(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, 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((String)value);
        }
        break;

      }
    }

    public Object getFieldValue(_Fields field) {
      switch (field) {
      case AUTHZ_TOKEN:
        return getAuthzToken();

      case GATEWAY_ID:
        return getGatewayID();

      }
      throw new IllegalStateException();
    }

    /** Returns true if field corresponding to fieldID is set (has been assigned a value) and false otherwise */
    public boolean isSet(_Fields field) {
      if (field == null) {
        throw new IllegalArgumentException();
      }

      switch (field) {
      case AUTHZ_TOKEN:
        return isSetAuthzToken();
      case GATEWAY_ID:
        return isSetGatewayID();
      }
      throw new IllegalStateException();
    }

    @Override
    public boolean equals(Object that) {
      if (that == null)
        return false;
      if (that instanceof getAllGatewayComputeResourcePreferences_args)
        return this.equals((getAllGatewayComputeResourcePreferences_args)that);
      return false;
    }

    public boolean equals(getAllGatewayComputeResourcePreferences_args that) {
      if (that == null)
        return false;

      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() {
      List<Object> list = new ArrayList<Object>();

      boolean present_authzToken = true && (isSetAuthzToken());
      list.add(present_authzToken);
      if (present_authzToken)
        list.add(authzToken);

      boolean present_gatewayID = true && (isSetGatewayID());
      list.add(present_gatewayID);
      if (present_gatewayID)
        list.add(gatewayID);

      return list.hashCode();
    }

    @Override
    public int compareTo(getAllGatewayComputeResourcePreferences_args other) {
      if (!getClass().equals(other.getClass())) {
        return getClass().getName().compareTo(other.getClass().getName());
      }

      int lastComparison = 0;

      lastComparison = 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 = 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 {
      schemes.get(iprot.getScheme()).getScheme().read(iprot, this);
    }

    public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException {
      schemes.get(oprot.getScheme()).getScheme().write(oprot, this);
    }

    @Override
    public String toString() {
      StringBuilder sb = new StringBuilder("getAllGatewayComputeResourcePreferences_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, 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 getAllGatewayComputeResourcePreferences_argsStandardSchemeFactory implements SchemeFactory {
      public getAllGatewayComputeResourcePreferences_argsStandardScheme getScheme() {
        return new getAllGatewayComputeResourcePreferences_argsStandardScheme();
      }
    }

    private static class getAllGatewayComputeResourcePreferences_argsStandardScheme extends StandardScheme<getAllGatewayComputeResourcePreferences_args> {

      public void read(org.apache.thrift.protocol.TProtocol iprot, getAllGatewayComputeResourcePreferences_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, getAllGatewayComputeResourcePreferences_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 getAllGatewayComputeResourcePreferences_argsTupleSchemeFactory implements SchemeFactory {
      public getAllGatewayComputeResourcePreferences_argsTupleScheme getScheme() {
        return new getAllGatewayComputeResourcePreferences_argsTupleScheme();
      }
    }

    private static class getAllGatewayComputeResourcePreferences_argsTupleScheme extends TupleScheme<getAllGatewayComputeResourcePreferences_args> {

      @Override
      public void write(org.apache.thrift.protocol.TProtocol prot, getAllGatewayComputeResourcePreferences_args struct) throws org.apache.thrift.TException {
        TTupleProtocol oprot = (TTupleProtocol) prot;
        struct.authzToken.write(oprot);
        oprot.writeString(struct.gatewayID);
      }

      @Override
      public void read(org.apache.thrift.protocol.TProtocol prot, getAllGatewayComputeResourcePreferences_args struct) throws org.apache.thrift.TException {
        TTupleProtocol iprot = (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);
      }
    }

  }

  public static class getAllGatewayComputeResourcePreferences_result implements org.apache.thrift.TBase<getAllGatewayComputeResourcePreferences_result, getAllGatewayComputeResourcePreferences_result._Fields>, java.io.Serializable, Cloneable, Comparable<getAllGatewayComputeResourcePreferences_result>   {
    private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("getAllGatewayComputeResourcePreferences_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 IRE_FIELD_DESC = new org.apache.thrift.protocol.TField("ire", org.apache.thrift.protocol.TType.STRUCT, (short)1);
    private static final org.apache.thrift.protocol.TField ACE_FIELD_DESC = new org.apache.thrift.protocol.TField("ace", org.apache.thrift.protocol.TType.STRUCT, (short)2);
    private static final org.apache.thrift.protocol.TField ASE_FIELD_DESC = new org.apache.thrift.protocol.TField("ase", org.apache.thrift.protocol.TType.STRUCT, (short)3);
    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)4);

    private static final Map<Class<? extends IScheme>, SchemeFactory> schemes = new HashMap<Class<? extends IScheme>, SchemeFactory>();
    static {
      schemes.put(StandardScheme.class, new getAllGatewayComputeResourcePreferences_resultStandardSchemeFactory());
      schemes.put(TupleScheme.class, new getAllGatewayComputeResourcePreferences_resultTupleSchemeFactory());
    }

    public List<org.apache.airavata.model.appcatalog.gatewayprofile.ComputeResourcePreference> success; // required
    public org.apache.airavata.model.error.InvalidRequestException ire; // required
    public org.apache.airavata.model.error.AiravataClientException ace; // required
    public org.apache.airavata.model.error.AiravataSystemException ase; // 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"),
      IRE((short)1, "ire"),
      ACE((short)2, "ace"),
      ASE((short)3, "ase"),
      AE((short)4, "ae");

      private static final Map<String, _Fields> byName = new HashMap<String, _Fields>();

      static {
        for (_Fields field : EnumSet.allOf(_Fields.class)) {
          byName.put(field.getFieldName(), field);
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, or null if its not found.
       */
      public static _Fields findByThriftId(int fieldId) {
        switch(fieldId) {
          case 0: // SUCCESS
            return SUCCESS;
          case 1: // IRE
            return IRE;
          case 2: // ACE
            return ACE;
          case 3: // ASE
            return ASE;
          case 4: // 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 IllegalArgumentException("Field " + fieldId + " doesn't exist!");
        return fields;
      }

      /**
       * Find the _Fields constant that matches name, or null if its not found.
       */
      public static _Fields findByName(String name) {
        return byName.get(name);
      }

      private final short _thriftId;
      private final String _fieldName;

      _Fields(short thriftId, String fieldName) {
        _thriftId = thriftId;
        _fieldName = fieldName;
      }

      public short getThriftFieldId() {
        return _thriftId;
      }

      public String getFieldName() {
        return _fieldName;
      }
    }

    // isset id assignments
    public static final Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
    static {
      Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new EnumMap<_Fields, org.apache.thrift.meta_data.FieldMetaData>(_Fields.class);
      tmpMap.put(_Fields.SUCCESS, new org.apache.thrift.meta_data.FieldMetaData("success", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.ListMetaData(org.apache.thrift.protocol.TType.LIST, 
              new org.apache.thrift.meta_data.StructMetaData(org.apache.thrift.protocol.TType.STRUCT, org.apache.airavata.model.appcatalog.gatewayprofile.ComputeResourcePreference.class))));
      tmpMap.put(_Fields.IRE, new org.apache.thrift.meta_data.FieldMetaData("ire", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRUCT)));
      tmpMap.put(_Fields.ACE, new org.apache.thrift.meta_data.FieldMetaData("ace", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRUCT)));
      tmpMap.put(_Fields.ASE, new org.apache.thrift.meta_data.FieldMetaData("ase", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRUCT)));
      tmpMap.put(_Fields.AE, new org.apache.thrift.meta_data.FieldMetaData("ae", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRUCT)));
      metaDataMap = Collections.unmodifiableMap(tmpMap);
      org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(getAllGatewayComputeResourcePreferences_result.class, metaDataMap);
    }

    public getAllGatewayComputeResourcePreferences_result() {
    }

    public getAllGatewayComputeResourcePreferences_result(
      List<org.apache.airavata.model.appcatalog.gatewayprofile.ComputeResourcePreference> success,
      org.apache.airavata.model.error.InvalidRequestException ire,
      org.apache.airavata.model.error.AiravataClientException ace,
      org.apache.airavata.model.error.AiravataSystemException ase,
      org.apache.airavata.model.error.AuthorizationException ae)
    {
      this();
      this.success = success;
      this.ire = ire;
      this.ace = ace;
      this.ase = ase;
      this.ae = ae;
    }

    /**
     * Performs a deep copy on <i>other</i>.
     */
    public getAllGatewayComputeResourcePreferences_result(getAllGatewayComputeResourcePreferences_result other) {
      if (other.isSetSuccess()) {
        List<org.apache.airavata.model.appcatalog.gatewayprofile.ComputeResourcePreference> __this__success = new ArrayList<org.apache.airavata.model.appcatalog.gatewayprofile.ComputeResourcePreference>(other.success.size());
        for (org.apache.airavata.model.appcatalog.gatewayprofile.ComputeResourcePreference other_element : other.success) {
          __this__success.add(new org.apache.airavata.model.appcatalog.gatewayprofile.ComputeResourcePreference(other_element));
        }
        this.success = __this__success;
      }
      if (other.isSetIre()) {
        this.ire = new org.apache.airavata.model.error.InvalidRequestException(other.ire);
      }
      if (other.isSetAce()) {
        this.ace = new org.apache.airavata.model.error.AiravataClientException(other.ace);
      }
      if (other.isSetAse()) {
        this.ase = new org.apache.airavata.model.error.AiravataSystemException(other.ase);
      }
      if (other.isSetAe()) {
        this.ae = new org.apache.airavata.model.error.AuthorizationException(other.ae);
      }
    }

    public getAllGatewayComputeResourcePreferences_result deepCopy() {
      return new getAllGatewayComputeResourcePreferences_result(this);
    }

    @Override
    public void clear() {
      this.success = null;
      this.ire = null;
      this.ace = null;
      this.ase = null;
      this.ae = null;
    }

    public int getSuccessSize() {
      return (this.success == null) ? 0 : this.success.size();
    }

    public java.util.Iterator<org.apache.airavata.model.appcatalog.gatewayprofile.ComputeResourcePreference> getSuccessIterator() {
      return (this.success == null) ? null : this.success.iterator();
    }

    public void addToSuccess(org.apache.airavata.model.appcatalog.gatewayprofile.ComputeResourcePreference elem) {
      if (this.success == null) {
        this.success = new ArrayList<org.apache.airavata.model.appcatalog.gatewayprofile.ComputeResourcePreference>();
      }
      this.success.add(elem);
    }

    public List<org.apache.airavata.model.appcatalog.gatewayprofile.ComputeResourcePreference> getSuccess() {
      return this.success;
    }

    public getAllGatewayComputeResourcePreferences_result setSuccess(List<org.apache.airavata.model.appcatalog.gatewayprofile.ComputeResourcePreference> 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.model.error.InvalidRequestException getIre() {
      return this.ire;
    }

    public getAllGatewayComputeResourcePreferences_result setIre(org.apache.airavata.model.error.InvalidRequestException ire) {
      this.ire = ire;
      return this;
    }

    public void unsetIre() {
      this.ire = null;
    }

    /** Returns true if field ire is set (has been assigned a value) and false otherwise */
    public boolean isSetIre() {
      return this.ire != null;
    }

    public void setIreIsSet(boolean value) {
      if (!value) {
        this.ire = null;
      }
    }

    public org.apache.airavata.model.error.AiravataClientException getAce() {
      return this.ace;
    }

    public getAllGatewayComputeResourcePreferences_result setAce(org.apache.airavata.model.error.AiravataClientException ace) {
      this.ace = ace;
      return this;
    }

    public void unsetAce() {
      this.ace = null;
    }

    /** Returns true if field ace is set (has been assigned a value) and false otherwise */
    public boolean isSetAce() {
      return this.ace != null;
    }

    public void setAceIsSet(boolean value) {
      if (!value) {
        this.ace = null;
      }
    }

    public org.apache.airavata.model.error.AiravataSystemException getAse() {
      return this.ase;
    }

    public getAllGatewayComputeResourcePreferences_result setAse(org.apache.airavata.model.error.AiravataSystemException ase) {
      this.ase = ase;
      return this;
    }

    public void unsetAse() {
      this.ase = null;
    }

    /** Returns true if field ase is set (has been assigned a value) and false otherwise */
    public boolean isSetAse() {
      return this.ase != null;
    }

    public void setAseIsSet(boolean value) {
      if (!value) {
        this.ase = null;
      }
    }

    public org.apache.airavata.model.error.AuthorizationException getAe() {
      return this.ae;
    }

    public getAllGatewayComputeResourcePreferences_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, Object value) {
      switch (field) {
      case SUCCESS:
        if (value == null) {
          unsetSuccess();
        } else {
          setSuccess((List<org.apache.airavata.model.appcatalog.gatewayprofile.ComputeResourcePreference>)value);
        }
        break;

      case IRE:
        if (value == null) {
          unsetIre();
        } else {
          setIre((org.apache.airavata.model.error.InvalidRequestException)value);
        }
        break;

      case ACE:
        if (value == null) {
          unsetAce();
        } else {
          setAce((org.apache.airavata.model.error.AiravataClientException)value);
        }
        break;

      case ASE:
        if (value == null) {
          unsetAse();
        } else {
          setAse((org.apache.airavata.model.error.AiravataSystemException)value);
        }
        break;

      case AE:
        if (value == null) {
          unsetAe();
        } else {
          setAe((org.apache.airavata.model.error.AuthorizationException)value);
        }
        break;

      }
    }

    public Object getFieldValue(_Fields field) {
      switch (field) {
      case SUCCESS:
        return getSuccess();

      case IRE:
        return getIre();

      case ACE:
        return getAce();

      case ASE:
        return getAse();

      case AE:
        return getAe();

      }
      throw new IllegalStateException();
    }

    /** Returns true if field corresponding to fieldID is set (has been assigned a value) and false otherwise */
    public boolean isSet(_Fields field) {
      if (field == null) {
        throw new IllegalArgumentException();
      }

      switch (field) {
      case SUCCESS:
        return isSetSuccess();
      case IRE:
        return isSetIre();
      case ACE:
        return isSetAce();
      case ASE:
        return isSetAse();
      case AE:
        return isSetAe();
      }
      throw new IllegalStateException();
    }

    @Override
    public boolean equals(Object that) {
      if (that == null)
        return false;
      if (that instanceof getAllGatewayComputeResourcePreferences_result)
        return this.equals((getAllGatewayComputeResourcePreferences_result)that);
      return false;
    }

    public boolean equals(getAllGatewayComputeResourcePreferences_result that) {
      if (that == null)
        return false;

      boolean this_present_success = true && this.isSetSuccess();
      boolean that_present_success = true && that.isSetSuccess();
      if (this_present_success || that_present_success) {
        if (!(this_present_success && that_present_success))
          return false;
        if (!this.success.equals(that.success))
          return false;
      }

      boolean this_present_ire = true && this.isSetIre();
      boolean that_present_ire = true && that.isSetIre();
      if (this_present_ire || that_present_ire) {
        if (!(this_present_ire && that_present_ire))
          return false;
        if (!this.ire.equals(that.ire))
          return false;
      }

      boolean this_present_ace = true && this.isSetAce();
      boolean that_present_ace = true && that.isSetAce();
      if (this_present_ace || that_present_ace) {
        if (!(this_present_ace && that_present_ace))
          return false;
        if (!this.ace.equals(that.ace))
          return false;
      }

      boolean this_present_ase = true && this.isSetAse();
      boolean that_present_ase = true && that.isSetAse();
      if (this_present_ase || that_present_ase) {
        if (!(this_present_ase && that_present_ase))
          return false;
        if (!this.ase.equals(that.ase))
          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() {
      List<Object> list = new ArrayList<Object>();

      boolean present_success = true && (isSetSuccess());
      list.add(present_success);
      if (present_success)
        list.add(success);

      boolean present_ire = true && (isSetIre());
      list.add(present_ire);
      if (present_ire)
        list.add(ire);

      boolean present_ace = true && (isSetAce());
      list.add(present_ace);
      if (present_ace)
        list.add(ace);

      boolean present_ase = true && (isSetAse());
      list.add(present_ase);
      if (present_ase)
        list.add(ase);

      boolean present_ae = true && (isSetAe());
      list.add(present_ae);
      if (present_ae)
        list.add(ae);

      return list.hashCode();
    }

    @Override
    public int compareTo(getAllGatewayComputeResourcePreferences_result other) {
      if (!getClass().equals(other.getClass())) {
        return getClass().getName().compareTo(other.getClass().getName());
      }

      int lastComparison = 0;

      lastComparison = Boolean.valueOf(isSetSuccess()).compareTo(other.isSetSuccess());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetSuccess()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.success, other.success);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = Boolean.valueOf(isSetIre()).compareTo(other.isSetIre());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetIre()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.ire, other.ire);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = Boolean.valueOf(isSetAce()).compareTo(other.isSetAce());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetAce()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.ace, other.ace);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = Boolean.valueOf(isSetAse()).compareTo(other.isSetAse());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetAse()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.ase, other.ase);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = 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 {
      schemes.get(iprot.getScheme()).getScheme().read(iprot, this);
    }

    public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException {
      schemes.get(oprot.getScheme()).getScheme().write(oprot, this);
      }

    @Override
    public String toString() {
      StringBuilder sb = new StringBuilder("getAllGatewayComputeResourcePreferences_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("ire:");
      if (this.ire == null) {
        sb.append("null");
      } else {
        sb.append(this.ire);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("ace:");
      if (this.ace == null) {
        sb.append("null");
      } else {
        sb.append(this.ace);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("ase:");
      if (this.ase == null) {
        sb.append("null");
      } else {
        sb.append(this.ase);
      }
      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, 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 getAllGatewayComputeResourcePreferences_resultStandardSchemeFactory implements SchemeFactory {
      public getAllGatewayComputeResourcePreferences_resultStandardScheme getScheme() {
        return new getAllGatewayComputeResourcePreferences_resultStandardScheme();
      }
    }

    private static class getAllGatewayComputeResourcePreferences_resultStandardScheme extends StandardScheme<getAllGatewayComputeResourcePreferences_result> {

      public void read(org.apache.thrift.protocol.TProtocol iprot, getAllGatewayComputeResourcePreferences_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 _list248 = iprot.readListBegin();
                  struct.success = new ArrayList<org.apache.airavata.model.appcatalog.gatewayprofile.ComputeResourcePreference>(_list248.size);
                  org.apache.airavata.model.appcatalog.gatewayprofile.ComputeResourcePreference _elem249;
                  for (int _i250 = 0; _i250 < _list248.size; ++_i250)
                  {
                    _elem249 = new org.apache.airavata.model.appcatalog.gatewayprofile.ComputeResourcePreference();
                    _elem249.read(iprot);
                    struct.success.add(_elem249);
                  }
                  iprot.readListEnd();
                }
                struct.setSuccessIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 1: // IRE
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.ire = new org.apache.airavata.model.error.InvalidRequestException();
                struct.ire.read(iprot);
                struct.setIreIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 2: // ACE
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.ace = new org.apache.airavata.model.error.AiravataClientException();
                struct.ace.read(iprot);
                struct.setAceIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 3: // ASE
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.ase = new org.apache.airavata.model.error.AiravataSystemException();
                struct.ase.read(iprot);
                struct.setAseIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 4: // 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, getAllGatewayComputeResourcePreferences_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.appcatalog.gatewayprofile.ComputeResourcePreference _iter251 : struct.success)
            {
              _iter251.write(oprot);
            }
            oprot.writeListEnd();
          }
          oprot.writeFieldEnd();
        }
        if (struct.ire != null) {
          oprot.writeFieldBegin(IRE_FIELD_DESC);
          struct.ire.write(oprot);
          oprot.writeFieldEnd();
        }
        if (struct.ace != null) {
          oprot.writeFieldBegin(ACE_FIELD_DESC);
          struct.ace.write(oprot);
          oprot.writeFieldEnd();
        }
        if (struct.ase != null) {
          oprot.writeFieldBegin(ASE_FIELD_DESC);
          struct.ase.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 getAllGatewayComputeResourcePreferences_resultTupleSchemeFactory implements SchemeFactory {
      public getAllGatewayComputeResourcePreferences_resultTupleScheme getScheme() {
        return new getAllGatewayComputeResourcePreferences_resultTupleScheme();
      }
    }

    private static class getAllGatewayComputeResourcePreferences_resultTupleScheme extends TupleScheme<getAllGatewayComputeResourcePreferences_result> {

      @Override
      public void write(org.apache.thrift.protocol.TProtocol prot, getAllGatewayComputeResourcePreferences_result struct) throws org.apache.thrift.TException {
        TTupleProtocol oprot = (TTupleProtocol) prot;
        BitSet optionals = new BitSet();
        if (struct.isSetSuccess()) {
          optionals.set(0);
        }
        if (struct.isSetIre()) {
          optionals.set(1);
        }
        if (struct.isSetAce()) {
          optionals.set(2);
        }
        if (struct.isSetAse()) {
          optionals.set(3);
        }
        if (struct.isSetAe()) {
          optionals.set(4);
        }
        oprot.writeBitSet(optionals, 5);
        if (struct.isSetSuccess()) {
          {
            oprot.writeI32(struct.success.size());
            for (org.apache.airavata.model.appcatalog.gatewayprofile.ComputeResourcePreference _iter252 : struct.success)
            {
              _iter252.write(oprot);
            }
          }
        }
        if (struct.isSetIre()) {
          struct.ire.write(oprot);
        }
        if (struct.isSetAce()) {
          struct.ace.write(oprot);
        }
        if (struct.isSetAse()) {
          struct.ase.write(oprot);
        }
        if (struct.isSetAe()) {
          struct.ae.write(oprot);
        }
      }

      @Override
      public void read(org.apache.thrift.protocol.TProtocol prot, getAllGatewayComputeResourcePreferences_result struct) throws org.apache.thrift.TException {
        TTupleProtocol iprot = (TTupleProtocol) prot;
        BitSet incoming = iprot.readBitSet(5);
        if (incoming.get(0)) {
          {
            org.apache.thrift.protocol.TList _list253 = new org.apache.thrift.protocol.TList(org.apache.thrift.protocol.TType.STRUCT, iprot.readI32());
            struct.success = new ArrayList<org.apache.airavata.model.appcatalog.gatewayprofile.ComputeResourcePreference>(_list253.size);
            org.apache.airavata.model.appcatalog.gatewayprofile.ComputeResourcePreference _elem254;
            for (int _i255 = 0; _i255 < _list253.size; ++_i255)
            {
              _elem254 = new org.apache.airavata.model.appcatalog.gatewayprofile.ComputeResourcePreference();
              _elem254.read(iprot);
              struct.success.add(_elem254);
            }
          }
          struct.setSuccessIsSet(true);
        }
        if (incoming.get(1)) {
          struct.ire = new org.apache.airavata.model.error.InvalidRequestException();
          struct.ire.read(iprot);
          struct.setIreIsSet(true);
        }
        if (incoming.get(2)) {
          struct.ace = new org.apache.airavata.model.error.AiravataClientException();
          struct.ace.read(iprot);
          struct.setAceIsSet(true);
        }
        if (incoming.get(3)) {
          struct.ase = new org.apache.airavata.model.error.AiravataSystemException();
          struct.ase.read(iprot);
          struct.setAseIsSet(true);
        }
        if (incoming.get(4)) {
          struct.ae = new org.apache.airavata.model.error.AuthorizationException();
          struct.ae.read(iprot);
          struct.setAeIsSet(true);
        }
      }
    }

  }

  public static class getAllGatewayDataStoragePreferences_args implements org.apache.thrift.TBase<getAllGatewayDataStoragePreferences_args, getAllGatewayDataStoragePreferences_args._Fields>, java.io.Serializable, Cloneable, Comparable<getAllGatewayDataStoragePreferences_args>   {
    private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("getAllGatewayDataStoragePreferences_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 Map<Class<? extends IScheme>, SchemeFactory> schemes = new HashMap<Class<? extends IScheme>, SchemeFactory>();
    static {
      schemes.put(StandardScheme.class, new getAllGatewayDataStoragePreferences_argsStandardSchemeFactory());
      schemes.put(TupleScheme.class, new getAllGatewayDataStoragePreferences_argsTupleSchemeFactory());
    }

    public org.apache.airavata.model.security.AuthzToken authzToken; // required
    public 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 Map<String, _Fields> byName = new HashMap<String, _Fields>();

      static {
        for (_Fields field : EnumSet.allOf(_Fields.class)) {
          byName.put(field.getFieldName(), field);
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, or null if its not found.
       */
      public static _Fields findByThriftId(int fieldId) {
        switch(fieldId) {
          case 1: // 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 IllegalArgumentException("Field " + fieldId + " doesn't exist!");
        return fields;
      }

      /**
       * Find the _Fields constant that matches name, or null if its not found.
       */
      public static _Fields findByName(String name) {
        return byName.get(name);
      }

      private final short _thriftId;
      private final String _fieldName;

      _Fields(short thriftId, String fieldName) {
        _thriftId = thriftId;
        _fieldName = fieldName;
      }

      public short getThriftFieldId() {
        return _thriftId;
      }

      public String getFieldName() {
        return _fieldName;
      }
    }

    // isset id assignments
    public static final Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
    static {
      Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new EnumMap<_Fields, org.apache.thrift.meta_data.FieldMetaData>(_Fields.class);
      tmpMap.put(_Fields.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 = Collections.unmodifiableMap(tmpMap);
      org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(getAllGatewayDataStoragePreferences_args.class, metaDataMap);
    }

    public getAllGatewayDataStoragePreferences_args() {
    }

    public getAllGatewayDataStoragePreferences_args(
      org.apache.airavata.model.security.AuthzToken authzToken,
      String gatewayID)
    {
      this();
      this.authzToken = authzToken;
      this.gatewayID = gatewayID;
    }

    /**
     * Performs a deep copy on <i>other</i>.
     */
    public getAllGatewayDataStoragePreferences_args(getAllGatewayDataStoragePreferences_args other) {
      if (other.isSetAuthzToken()) {
        this.authzToken = new org.apache.airavata.model.security.AuthzToken(other.authzToken);
      }
      if (other.isSetGatewayID()) {
        this.gatewayID = other.gatewayID;
      }
    }

    public getAllGatewayDataStoragePreferences_args deepCopy() {
      return new getAllGatewayDataStoragePreferences_args(this);
    }

    @Override
    public void clear() {
      this.authzToken = null;
      this.gatewayID = null;
    }

    public org.apache.airavata.model.security.AuthzToken getAuthzToken() {
      return this.authzToken;
    }

    public getAllGatewayDataStoragePreferences_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 String getGatewayID() {
      return this.gatewayID;
    }

    public getAllGatewayDataStoragePreferences_args setGatewayID(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, 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((String)value);
        }
        break;

      }
    }

    public Object getFieldValue(_Fields field) {
      switch (field) {
      case AUTHZ_TOKEN:
        return getAuthzToken();

      case GATEWAY_ID:
        return getGatewayID();

      }
      throw new IllegalStateException();
    }

    /** Returns true if field corresponding to fieldID is set (has been assigned a value) and false otherwise */
    public boolean isSet(_Fields field) {
      if (field == null) {
        throw new IllegalArgumentException();
      }

      switch (field) {
      case AUTHZ_TOKEN:
        return isSetAuthzToken();
      case GATEWAY_ID:
        return isSetGatewayID();
      }
      throw new IllegalStateException();
    }

    @Override
    public boolean equals(Object that) {
      if (that == null)
        return false;
      if (that instanceof getAllGatewayDataStoragePreferences_args)
        return this.equals((getAllGatewayDataStoragePreferences_args)that);
      return false;
    }

    public boolean equals(getAllGatewayDataStoragePreferences_args that) {
      if (that == null)
        return false;

      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() {
      List<Object> list = new ArrayList<Object>();

      boolean present_authzToken = true && (isSetAuthzToken());
      list.add(present_authzToken);
      if (present_authzToken)
        list.add(authzToken);

      boolean present_gatewayID = true && (isSetGatewayID());
      list.add(present_gatewayID);
      if (present_gatewayID)
        list.add(gatewayID);

      return list.hashCode();
    }

    @Override
    public int compareTo(getAllGatewayDataStoragePreferences_args other) {
      if (!getClass().equals(other.getClass())) {
        return getClass().getName().compareTo(other.getClass().getName());
      }

      int lastComparison = 0;

      lastComparison = 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 = 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 {
      schemes.get(iprot.getScheme()).getScheme().read(iprot, this);
    }

    public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException {
      schemes.get(oprot.getScheme()).getScheme().write(oprot, this);
    }

    @Override
    public String toString() {
      StringBuilder sb = new StringBuilder("getAllGatewayDataStoragePreferences_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, 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 getAllGatewayDataStoragePreferences_argsStandardSchemeFactory implements SchemeFactory {
      public getAllGatewayDataStoragePreferences_argsStandardScheme getScheme() {
        return new getAllGatewayDataStoragePreferences_argsStandardScheme();
      }
    }

    private static class getAllGatewayDataStoragePreferences_argsStandardScheme extends StandardScheme<getAllGatewayDataStoragePreferences_args> {

      public void read(org.apache.thrift.protocol.TProtocol iprot, getAllGatewayDataStoragePreferences_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, getAllGatewayDataStoragePreferences_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 getAllGatewayDataStoragePreferences_argsTupleSchemeFactory implements SchemeFactory {
      public getAllGatewayDataStoragePreferences_argsTupleScheme getScheme() {
        return new getAllGatewayDataStoragePreferences_argsTupleScheme();
      }
    }

    private static class getAllGatewayDataStoragePreferences_argsTupleScheme extends TupleScheme<getAllGatewayDataStoragePreferences_args> {

      @Override
      public void write(org.apache.thrift.protocol.TProtocol prot, getAllGatewayDataStoragePreferences_args struct) throws org.apache.thrift.TException {
        TTupleProtocol oprot = (TTupleProtocol) prot;
        struct.authzToken.write(oprot);
        oprot.writeString(struct.gatewayID);
      }

      @Override
      public void read(org.apache.thrift.protocol.TProtocol prot, getAllGatewayDataStoragePreferences_args struct) throws org.apache.thrift.TException {
        TTupleProtocol iprot = (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);
      }
    }

  }

  public static class getAllGatewayDataStoragePreferences_result implements org.apache.thrift.TBase<getAllGatewayDataStoragePreferences_result, getAllGatewayDataStoragePreferences_result._Fields>, java.io.Serializable, Cloneable, Comparable<getAllGatewayDataStoragePreferences_result>   {
    private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("getAllGatewayDataStoragePreferences_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 IRE_FIELD_DESC = new org.apache.thrift.protocol.TField("ire", org.apache.thrift.protocol.TType.STRUCT, (short)1);
    private static final org.apache.thrift.protocol.TField ACE_FIELD_DESC = new org.apache.thrift.protocol.TField("ace", org.apache.thrift.protocol.TType.STRUCT, (short)2);
    private static final org.apache.thrift.protocol.TField ASE_FIELD_DESC = new org.apache.thrift.protocol.TField("ase", org.apache.thrift.protocol.TType.STRUCT, (short)3);
    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)4);

    private static final Map<Class<? extends IScheme>, SchemeFactory> schemes = new HashMap<Class<? extends IScheme>, SchemeFactory>();
    static {
      schemes.put(StandardScheme.class, new getAllGatewayDataStoragePreferences_resultStandardSchemeFactory());
      schemes.put(TupleScheme.class, new getAllGatewayDataStoragePreferences_resultTupleSchemeFactory());
    }

    public List<org.apache.airavata.model.appcatalog.gatewayprofile.DataStoragePreference> success; // required
    public org.apache.airavata.model.error.InvalidRequestException ire; // required
    public org.apache.airavata.model.error.AiravataClientException ace; // required
    public org.apache.airavata.model.error.AiravataSystemException ase; // 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"),
      IRE((short)1, "ire"),
      ACE((short)2, "ace"),
      ASE((short)3, "ase"),
      AE((short)4, "ae");

      private static final Map<String, _Fields> byName = new HashMap<String, _Fields>();

      static {
        for (_Fields field : EnumSet.allOf(_Fields.class)) {
          byName.put(field.getFieldName(), field);
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, or null if its not found.
       */
      public static _Fields findByThriftId(int fieldId) {
        switch(fieldId) {
          case 0: // SUCCESS
            return SUCCESS;
          case 1: // IRE
            return IRE;
          case 2: // ACE
            return ACE;
          case 3: // ASE
            return ASE;
          case 4: // 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 IllegalArgumentException("Field " + fieldId + " doesn't exist!");
        return fields;
      }

      /**
       * Find the _Fields constant that matches name, or null if its not found.
       */
      public static _Fields findByName(String name) {
        return byName.get(name);
      }

      private final short _thriftId;
      private final String _fieldName;

      _Fields(short thriftId, String fieldName) {
        _thriftId = thriftId;
        _fieldName = fieldName;
      }

      public short getThriftFieldId() {
        return _thriftId;
      }

      public String getFieldName() {
        return _fieldName;
      }
    }

    // isset id assignments
    public static final Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
    static {
      Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new EnumMap<_Fields, org.apache.thrift.meta_data.FieldMetaData>(_Fields.class);
      tmpMap.put(_Fields.SUCCESS, new org.apache.thrift.meta_data.FieldMetaData("success", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.ListMetaData(org.apache.thrift.protocol.TType.LIST, 
              new org.apache.thrift.meta_data.StructMetaData(org.apache.thrift.protocol.TType.STRUCT, org.apache.airavata.model.appcatalog.gatewayprofile.DataStoragePreference.class))));
      tmpMap.put(_Fields.IRE, new org.apache.thrift.meta_data.FieldMetaData("ire", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRUCT)));
      tmpMap.put(_Fields.ACE, new org.apache.thrift.meta_data.FieldMetaData("ace", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRUCT)));
      tmpMap.put(_Fields.ASE, new org.apache.thrift.meta_data.FieldMetaData("ase", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRUCT)));
      tmpMap.put(_Fields.AE, new org.apache.thrift.meta_data.FieldMetaData("ae", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRUCT)));
      metaDataMap = Collections.unmodifiableMap(tmpMap);
      org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(getAllGatewayDataStoragePreferences_result.class, metaDataMap);
    }

    public getAllGatewayDataStoragePreferences_result() {
    }

    public getAllGatewayDataStoragePreferences_result(
      List<org.apache.airavata.model.appcatalog.gatewayprofile.DataStoragePreference> success,
      org.apache.airavata.model.error.InvalidRequestException ire,
      org.apache.airavata.model.error.AiravataClientException ace,
      org.apache.airavata.model.error.AiravataSystemException ase,
      org.apache.airavata.model.error.AuthorizationException ae)
    {
      this();
      this.success = success;
      this.ire = ire;
      this.ace = ace;
      this.ase = ase;
      this.ae = ae;
    }

    /**
     * Performs a deep copy on <i>other</i>.
     */
    public getAllGatewayDataStoragePreferences_result(getAllGatewayDataStoragePreferences_result other) {
      if (other.isSetSuccess()) {
        List<org.apache.airavata.model.appcatalog.gatewayprofile.DataStoragePreference> __this__success = new ArrayList<org.apache.airavata.model.appcatalog.gatewayprofile.DataStoragePreference>(other.success.size());
        for (org.apache.airavata.model.appcatalog.gatewayprofile.DataStoragePreference other_element : other.success) {
          __this__success.add(new org.apache.airavata.model.appcatalog.gatewayprofile.DataStoragePreference(other_element));
        }
        this.success = __this__success;
      }
      if (other.isSetIre()) {
        this.ire = new org.apache.airavata.model.error.InvalidRequestException(other.ire);
      }
      if (other.isSetAce()) {
        this.ace = new org.apache.airavata.model.error.AiravataClientException(other.ace);
      }
      if (other.isSetAse()) {
        this.ase = new org.apache.airavata.model.error.AiravataSystemException(other.ase);
      }
      if (other.isSetAe()) {
        this.ae = new org.apache.airavata.model.error.AuthorizationException(other.ae);
      }
    }

    public getAllGatewayDataStoragePreferences_result deepCopy() {
      return new getAllGatewayDataStoragePreferences_result(this);
    }

    @Override
    public void clear() {
      this.success = null;
      this.ire = null;
      this.ace = null;
      this.ase = null;
      this.ae = null;
    }

    public int getSuccessSize() {
      return (this.success == null) ? 0 : this.success.size();
    }

    public java.util.Iterator<org.apache.airavata.model.appcatalog.gatewayprofile.DataStoragePreference> getSuccessIterator() {
      return (this.success == null) ? null : this.success.iterator();
    }

    public void addToSuccess(org.apache.airavata.model.appcatalog.gatewayprofile.DataStoragePreference elem) {
      if (this.success == null) {
        this.success = new ArrayList<org.apache.airavata.model.appcatalog.gatewayprofile.DataStoragePreference>();
      }
      this.success.add(elem);
    }

    public List<org.apache.airavata.model.appcatalog.gatewayprofile.DataStoragePreference> getSuccess() {
      return this.success;
    }

    public getAllGatewayDataStoragePreferences_result setSuccess(List<org.apache.airavata.model.appcatalog.gatewayprofile.DataStoragePreference> 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.model.error.InvalidRequestException getIre() {
      return this.ire;
    }

    public getAllGatewayDataStoragePreferences_result setIre(org.apache.airavata.model.error.InvalidRequestException ire) {
      this.ire = ire;
      return this;
    }

    public void unsetIre() {
      this.ire = null;
    }

    /** Returns true if field ire is set (has been assigned a value) and false otherwise */
    public boolean isSetIre() {
      return this.ire != null;
    }

    public void setIreIsSet(boolean value) {
      if (!value) {
        this.ire = null;
      }
    }

    public org.apache.airavata.model.error.AiravataClientException getAce() {
      return this.ace;
    }

    public getAllGatewayDataStoragePreferences_result setAce(org.apache.airavata.model.error.AiravataClientException ace) {
      this.ace = ace;
      return this;
    }

    public void unsetAce() {
      this.ace = null;
    }

    /** Returns true if field ace is set (has been assigned a value) and false otherwise */
    public boolean isSetAce() {
      return this.ace != null;
    }

    public void setAceIsSet(boolean value) {
      if (!value) {
        this.ace = null;
      }
    }

    public org.apache.airavata.model.error.AiravataSystemException getAse() {
      return this.ase;
    }

    public getAllGatewayDataStoragePreferences_result setAse(org.apache.airavata.model.error.AiravataSystemException ase) {
      this.ase = ase;
      return this;
    }

    public void unsetAse() {
      this.ase = null;
    }

    /** Returns true if field ase is set (has been assigned a value) and false otherwise */
    public boolean isSetAse() {
      return this.ase != null;
    }

    public void setAseIsSet(boolean value) {
      if (!value) {
        this.ase = null;
      }
    }

    public org.apache.airavata.model.error.AuthorizationException getAe() {
      return this.ae;
    }

    public getAllGatewayDataStoragePreferences_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, Object value) {
      switch (field) {
      case SUCCESS:
        if (value == null) {
          unsetSuccess();
        } else {
          setSuccess((List<org.apache.airavata.model.appcatalog.gatewayprofile.DataStoragePreference>)value);
        }
        break;

      case IRE:
        if (value == null) {
          unsetIre();
        } else {
          setIre((org.apache.airavata.model.error.InvalidRequestException)value);
        }
        break;

      case ACE:
        if (value == null) {
          unsetAce();
        } else {
          setAce((org.apache.airavata.model.error.AiravataClientException)value);
        }
        break;

      case ASE:
        if (value == null) {
          unsetAse();
        } else {
          setAse((org.apache.airavata.model.error.AiravataSystemException)value);
        }
        break;

      case AE:
        if (value == null) {
          unsetAe();
        } else {
          setAe((org.apache.airavata.model.error.AuthorizationException)value);
        }
        break;

      }
    }

    public Object getFieldValue(_Fields field) {
      switch (field) {
      case SUCCESS:
        return getSuccess();

      case IRE:
        return getIre();

      case ACE:
        return getAce();

      case ASE:
        return getAse();

      case AE:
        return getAe();

      }
      throw new IllegalStateException();
    }

    /** Returns true if field corresponding to fieldID is set (has been assigned a value) and false otherwise */
    public boolean isSet(_Fields field) {
      if (field == null) {
        throw new IllegalArgumentException();
      }

      switch (field) {
      case SUCCESS:
        return isSetSuccess();
      case IRE:
        return isSetIre();
      case ACE:
        return isSetAce();
      case ASE:
        return isSetAse();
      case AE:
        return isSetAe();
      }
      throw new IllegalStateException();
    }

    @Override
    public boolean equals(Object that) {
      if (that == null)
        return false;
      if (that instanceof getAllGatewayDataStoragePreferences_result)
        return this.equals((getAllGatewayDataStoragePreferences_result)that);
      return false;
    }

    public boolean equals(getAllGatewayDataStoragePreferences_result that) {
      if (that == null)
        return false;

      boolean this_present_success = true && this.isSetSuccess();
      boolean that_present_success = true && that.isSetSuccess();
      if (this_present_success || that_present_success) {
        if (!(this_present_success && that_present_success))
          return false;
        if (!this.success.equals(that.success))
          return false;
      }

      boolean this_present_ire = true && this.isSetIre();
      boolean that_present_ire = true && that.isSetIre();
      if (this_present_ire || that_present_ire) {
        if (!(this_present_ire && that_present_ire))
          return false;
        if (!this.ire.equals(that.ire))
          return false;
      }

      boolean this_present_ace = true && this.isSetAce();
      boolean that_present_ace = true && that.isSetAce();
      if (this_present_ace || that_present_ace) {
        if (!(this_present_ace && that_present_ace))
          return false;
        if (!this.ace.equals(that.ace))
          return false;
      }

      boolean this_present_ase = true && this.isSetAse();
      boolean that_present_ase = true && that.isSetAse();
      if (this_present_ase || that_present_ase) {
        if (!(this_present_ase && that_present_ase))
          return false;
        if (!this.ase.equals(that.ase))
          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() {
      List<Object> list = new ArrayList<Object>();

      boolean present_success = true && (isSetSuccess());
      list.add(present_success);
      if (present_success)
        list.add(success);

      boolean present_ire = true && (isSetIre());
      list.add(present_ire);
      if (present_ire)
        list.add(ire);

      boolean present_ace = true && (isSetAce());
      list.add(present_ace);
      if (present_ace)
        list.add(ace);

      boolean present_ase = true && (isSetAse());
      list.add(present_ase);
      if (present_ase)
        list.add(ase);

      boolean present_ae = true && (isSetAe());
      list.add(present_ae);
      if (present_ae)
        list.add(ae);

      return list.hashCode();
    }

    @Override
    public int compareTo(getAllGatewayDataStoragePreferences_result other) {
      if (!getClass().equals(other.getClass())) {
        return getClass().getName().compareTo(other.getClass().getName());
      }

      int lastComparison = 0;

      lastComparison = Boolean.valueOf(isSetSuccess()).compareTo(other.isSetSuccess());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetSuccess()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.success, other.success);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = Boolean.valueOf(isSetIre()).compareTo(other.isSetIre());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetIre()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.ire, other.ire);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = Boolean.valueOf(isSetAce()).compareTo(other.isSetAce());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetAce()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.ace, other.ace);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = Boolean.valueOf(isSetAse()).compareTo(other.isSetAse());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetAse()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.ase, other.ase);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = 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 {
      schemes.get(iprot.getScheme()).getScheme().read(iprot, this);
    }

    public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException {
      schemes.get(oprot.getScheme()).getScheme().write(oprot, this);
      }

    @Override
    public String toString() {
      StringBuilder sb = new StringBuilder("getAllGatewayDataStoragePreferences_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("ire:");
      if (this.ire == null) {
        sb.append("null");
      } else {
        sb.append(this.ire);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("ace:");
      if (this.ace == null) {
        sb.append("null");
      } else {
        sb.append(this.ace);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("ase:");
      if (this.ase == null) {
        sb.append("null");
      } else {
        sb.append(this.ase);
      }
      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, 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 getAllGatewayDataStoragePreferences_resultStandardSchemeFactory implements SchemeFactory {
      public getAllGatewayDataStoragePreferences_resultStandardScheme getScheme() {
        return new getAllGatewayDataStoragePreferences_resultStandardScheme();
      }
    }

    private static class getAllGatewayDataStoragePreferences_resultStandardScheme extends StandardScheme<getAllGatewayDataStoragePreferences_result> {

      public void read(org.apache.thrift.protocol.TProtocol iprot, getAllGatewayDataStoragePreferences_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 _list256 = iprot.readListBegin();
                  struct.success = new ArrayList<org.apache.airavata.model.appcatalog.gatewayprofile.DataStoragePreference>(_list256.size);
                  org.apache.airavata.model.appcatalog.gatewayprofile.DataStoragePreference _elem257;
                  for (int _i258 = 0; _i258 < _list256.size; ++_i258)
                  {
                    _elem257 = new org.apache.airavata.model.appcatalog.gatewayprofile.DataStoragePreference();
                    _elem257.read(iprot);
                    struct.success.add(_elem257);
                  }
                  iprot.readListEnd();
                }
                struct.setSuccessIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 1: // IRE
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.ire = new org.apache.airavata.model.error.InvalidRequestException();
                struct.ire.read(iprot);
                struct.setIreIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 2: // ACE
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.ace = new org.apache.airavata.model.error.AiravataClientException();
                struct.ace.read(iprot);
                struct.setAceIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 3: // ASE
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.ase = new org.apache.airavata.model.error.AiravataSystemException();
                struct.ase.read(iprot);
                struct.setAseIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 4: // 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, getAllGatewayDataStoragePreferences_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.appcatalog.gatewayprofile.DataStoragePreference _iter259 : struct.success)
            {
              _iter259.write(oprot);
            }
            oprot.writeListEnd();
          }
          oprot.writeFieldEnd();
        }
        if (struct.ire != null) {
          oprot.writeFieldBegin(IRE_FIELD_DESC);
          struct.ire.write(oprot);
          oprot.writeFieldEnd();
        }
        if (struct.ace != null) {
          oprot.writeFieldBegin(ACE_FIELD_DESC);
          struct.ace.write(oprot);
          oprot.writeFieldEnd();
        }
        if (struct.ase != null) {
          oprot.writeFieldBegin(ASE_FIELD_DESC);
          struct.ase.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 getAllGatewayDataStoragePreferences_resultTupleSchemeFactory implements SchemeFactory {
      public getAllGatewayDataStoragePreferences_resultTupleScheme getScheme() {
        return new getAllGatewayDataStoragePreferences_resultTupleScheme();
      }
    }

    private static class getAllGatewayDataStoragePreferences_resultTupleScheme extends TupleScheme<getAllGatewayDataStoragePreferences_result> {

      @Override
      public void write(org.apache.thrift.protocol.TProtocol prot, getAllGatewayDataStoragePreferences_result struct) throws org.apache.thrift.TException {
        TTupleProtocol oprot = (TTupleProtocol) prot;
        BitSet optionals = new BitSet();
        if (struct.isSetSuccess()) {
          optionals.set(0);
        }
        if (struct.isSetIre()) {
          optionals.set(1);
        }
        if (struct.isSetAce()) {
          optionals.set(2);
        }
        if (struct.isSetAse()) {
          optionals.set(3);
        }
        if (struct.isSetAe()) {
          optionals.set(4);
        }
        oprot.writeBitSet(optionals, 5);
        if (struct.isSetSuccess()) {
          {
            oprot.writeI32(struct.success.size());
            for (org.apache.airavata.model.appcatalog.gatewayprofile.DataStoragePreference _iter260 : struct.success)
            {
              _iter260.write(oprot);
            }
          }
        }
        if (struct.isSetIre()) {
          struct.ire.write(oprot);
        }
        if (struct.isSetAce()) {
          struct.ace.write(oprot);
        }
        if (struct.isSetAse()) {
          struct.ase.write(oprot);
        }
        if (struct.isSetAe()) {
          struct.ae.write(oprot);
        }
      }

      @Override
      public void read(org.apache.thrift.protocol.TProtocol prot, getAllGatewayDataStoragePreferences_result struct) throws org.apache.thrift.TException {
        TTupleProtocol iprot = (TTupleProtocol) prot;
        BitSet incoming = iprot.readBitSet(5);
        if (incoming.get(0)) {
          {
            org.apache.thrift.protocol.TList _list261 = new org.apache.thrift.protocol.TList(org.apache.thrift.protocol.TType.STRUCT, iprot.readI32());
            struct.success = new ArrayList<org.apache.airavata.model.appcatalog.gatewayprofile.DataStoragePreference>(_list261.size);
            org.apache.airavata.model.appcatalog.gatewayprofile.DataStoragePreference _elem262;
            for (int _i263 = 0; _i263 < _list261.size; ++_i263)
            {
              _elem262 = new org.apache.airavata.model.appcatalog.gatewayprofile.DataStoragePreference();
              _elem262.read(iprot);
              struct.success.add(_elem262);
            }
          }
          struct.setSuccessIsSet(true);
        }
        if (incoming.get(1)) {
          struct.ire = new org.apache.airavata.model.error.InvalidRequestException();
          struct.ire.read(iprot);
          struct.setIreIsSet(true);
        }
        if (incoming.get(2)) {
          struct.ace = new org.apache.airavata.model.error.AiravataClientException();
          struct.ace.read(iprot);
          struct.setAceIsSet(true);
        }
        if (incoming.get(3)) {
          struct.ase = new org.apache.airavata.model.error.AiravataSystemException();
          struct.ase.read(iprot);
          struct.setAseIsSet(true);
        }
        if (incoming.get(4)) {
          struct.ae = new org.apache.airavata.model.error.AuthorizationException();
          struct.ae.read(iprot);
          struct.setAeIsSet(true);
        }
      }
    }

  }

  public static class getAllGatewayResourceProfiles_args implements org.apache.thrift.TBase<getAllGatewayResourceProfiles_args, getAllGatewayResourceProfiles_args._Fields>, java.io.Serializable, Cloneable, Comparable<getAllGatewayResourceProfiles_args>   {
    private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("getAllGatewayResourceProfiles_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 Map<Class<? extends IScheme>, SchemeFactory> schemes = new HashMap<Class<? extends IScheme>, SchemeFactory>();
    static {
      schemes.put(StandardScheme.class, new getAllGatewayResourceProfiles_argsStandardSchemeFactory());
      schemes.put(TupleScheme.class, new getAllGatewayResourceProfiles_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 Map<String, _Fields> byName = new HashMap<String, _Fields>();

      static {
        for (_Fields field : EnumSet.allOf(_Fields.class)) {
          byName.put(field.getFieldName(), field);
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, or null if its not found.
       */
      public static _Fields findByThriftId(int fieldId) {
        switch(fieldId) {
          case 1: // 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 IllegalArgumentException("Field " + fieldId + " doesn't exist!");
        return fields;
      }

      /**
       * Find the _Fields constant that matches name, or null if its not found.
       */
      public static _Fields findByName(String name) {
        return byName.get(name);
      }

      private final short _thriftId;
      private final String _fieldName;

      _Fields(short thriftId, String fieldName) {
        _thriftId = thriftId;
        _fieldName = fieldName;
      }

      public short getThriftFieldId() {
        return _thriftId;
      }

      public String getFieldName() {
        return _fieldName;
      }
    }

    // isset id assignments
    public static final Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
    static {
      Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new EnumMap<_Fields, org.apache.thrift.meta_data.FieldMetaData>(_Fields.class);
      tmpMap.put(_Fields.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 = Collections.unmodifiableMap(tmpMap);
      org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(getAllGatewayResourceProfiles_args.class, metaDataMap);
    }

    public getAllGatewayResourceProfiles_args() {
    }

    public getAllGatewayResourceProfiles_args(
      org.apache.airavata.model.security.AuthzToken authzToken)
    {
      this();
      this.authzToken = authzToken;
    }

    /**
     * Performs a deep copy on <i>other</i>.
     */
    public getAllGatewayResourceProfiles_args(getAllGatewayResourceProfiles_args other) {
      if (other.isSetAuthzToken()) {
        this.authzToken = new org.apache.airavata.model.security.AuthzToken(other.authzToken);
      }
    }

    public getAllGatewayResourceProfiles_args deepCopy() {
      return new getAllGatewayResourceProfiles_args(this);
    }

    @Override
    public void clear() {
      this.authzToken = null;
    }

    public org.apache.airavata.model.security.AuthzToken getAuthzToken() {
      return this.authzToken;
    }

    public getAllGatewayResourceProfiles_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, Object value) {
      switch (field) {
      case AUTHZ_TOKEN:
        if (value == null) {
          unsetAuthzToken();
        } else {
          setAuthzToken((org.apache.airavata.model.security.AuthzToken)value);
        }
        break;

      }
    }

    public Object getFieldValue(_Fields field) {
      switch (field) {
      case AUTHZ_TOKEN:
        return getAuthzToken();

      }
      throw new IllegalStateException();
    }

    /** Returns true if field corresponding to fieldID is set (has been assigned a value) and false otherwise */
    public boolean isSet(_Fields field) {
      if (field == null) {
        throw new IllegalArgumentException();
      }

      switch (field) {
      case AUTHZ_TOKEN:
        return isSetAuthzToken();
      }
      throw new IllegalStateException();
    }

    @Override
    public boolean equals(Object that) {
      if (that == null)
        return false;
      if (that instanceof getAllGatewayResourceProfiles_args)
        return this.equals((getAllGatewayResourceProfiles_args)that);
      return false;
    }

    public boolean equals(getAllGatewayResourceProfiles_args that) {
      if (that == null)
        return false;

      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() {
      List<Object> list = new ArrayList<Object>();

      boolean present_authzToken = true && (isSetAuthzToken());
      list.add(present_authzToken);
      if (present_authzToken)
        list.add(authzToken);

      return list.hashCode();
    }

    @Override
    public int compareTo(getAllGatewayResourceProfiles_args other) {
      if (!getClass().equals(other.getClass())) {
        return getClass().getName().compareTo(other.getClass().getName());
      }

      int lastComparison = 0;

      lastComparison = 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 {
      schemes.get(iprot.getScheme()).getScheme().read(iprot, this);
    }

    public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException {
      schemes.get(oprot.getScheme()).getScheme().write(oprot, this);
    }

    @Override
    public String toString() {
      StringBuilder sb = new StringBuilder("getAllGatewayResourceProfiles_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, 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 getAllGatewayResourceProfiles_argsStandardSchemeFactory implements SchemeFactory {
      public getAllGatewayResourceProfiles_argsStandardScheme getScheme() {
        return new getAllGatewayResourceProfiles_argsStandardScheme();
      }
    }

    private static class getAllGatewayResourceProfiles_argsStandardScheme extends StandardScheme<getAllGatewayResourceProfiles_args> {

      public void read(org.apache.thrift.protocol.TProtocol iprot, getAllGatewayResourceProfiles_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, getAllGatewayResourceProfiles_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 getAllGatewayResourceProfiles_argsTupleSchemeFactory implements SchemeFactory {
      public getAllGatewayResourceProfiles_argsTupleScheme getScheme() {
        return new getAllGatewayResourceProfiles_argsTupleScheme();
      }
    }

    private static class getAllGatewayResourceProfiles_argsTupleScheme extends TupleScheme<getAllGatewayResourceProfiles_args> {

      @Override
      public void write(org.apache.thrift.protocol.TProtocol prot, getAllGatewayResourceProfiles_args struct) throws org.apache.thrift.TException {
        TTupleProtocol oprot = (TTupleProtocol) prot;
        struct.authzToken.write(oprot);
      }

      @Override
      public void read(org.apache.thrift.protocol.TProtocol prot, getAllGatewayResourceProfiles_args struct) throws org.apache.thrift.TException {
        TTupleProtocol iprot = (TTupleProtocol) prot;
        struct.authzToken = new org.apache.airavata.model.security.AuthzToken();
        struct.authzToken.read(iprot);
        struct.setAuthzTokenIsSet(true);
      }
    }

  }

  public static class getAllGatewayResourceProfiles_result implements org.apache.thrift.TBase<getAllGatewayResourceProfiles_result, getAllGatewayResourceProfiles_result._Fields>, java.io.Serializable, Cloneable, Comparable<getAllGatewayResourceProfiles_result>   {
    private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("getAllGatewayResourceProfiles_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 IRE_FIELD_DESC = new org.apache.thrift.protocol.TField("ire", org.apache.thrift.protocol.TType.STRUCT, (short)1);
    private static final org.apache.thrift.protocol.TField ACE_FIELD_DESC = new org.apache.thrift.protocol.TField("ace", org.apache.thrift.protocol.TType.STRUCT, (short)2);
    private static final org.apache.thrift.protocol.TField ASE_FIELD_DESC = new org.apache.thrift.protocol.TField("ase", org.apache.thrift.protocol.TType.STRUCT, (short)3);
    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)4);

    private static final Map<Class<? extends IScheme>, SchemeFactory> schemes = new HashMap<Class<? extends IScheme>, SchemeFactory>();
    static {
      schemes.put(StandardScheme.class, new getAllGatewayResourceProfiles_resultStandardSchemeFactory());
      schemes.put(TupleScheme.class, new getAllGatewayResourceProfiles_resultTupleSchemeFactory());
    }

    public List<org.apache.airavata.model.appcatalog.gatewayprofile.GatewayResourceProfile> success; // required
    public org.apache.airavata.model.error.InvalidRequestException ire; // required
    public org.apache.airavata.model.error.AiravataClientException ace; // required
    public org.apache.airavata.model.error.AiravataSystemException ase; // 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"),
      IRE((short)1, "ire"),
      ACE((short)2, "ace"),
      ASE((short)3, "ase"),
      AE((short)4, "ae");

      private static final Map<String, _Fields> byName = new HashMap<String, _Fields>();

      static {
        for (_Fields field : EnumSet.allOf(_Fields.class)) {
          byName.put(field.getFieldName(), field);
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, or null if its not found.
       */
      public static _Fields findByThriftId(int fieldId) {
        switch(fieldId) {
          case 0: // SUCCESS
            return SUCCESS;
          case 1: // IRE
            return IRE;
          case 2: // ACE
            return ACE;
          case 3: // ASE
            return ASE;
          case 4: // 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 IllegalArgumentException("Field " + fieldId + " doesn't exist!");
        return fields;
      }

      /**
       * Find the _Fields constant that matches name, or null if its not found.
       */
      public static _Fields findByName(String name) {
        return byName.get(name);
      }

      private final short _thriftId;
      private final String _fieldName;

      _Fields(short thriftId, String fieldName) {
        _thriftId = thriftId;
        _fieldName = fieldName;
      }

      public short getThriftFieldId() {
        return _thriftId;
      }

      public String getFieldName() {
        return _fieldName;
      }
    }

    // isset id assignments
    public static final Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
    static {
      Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new EnumMap<_Fields, org.apache.thrift.meta_data.FieldMetaData>(_Fields.class);
      tmpMap.put(_Fields.SUCCESS, new org.apache.thrift.meta_data.FieldMetaData("success", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.ListMetaData(org.apache.thrift.protocol.TType.LIST, 
              new org.apache.thrift.meta_data.StructMetaData(org.apache.thrift.protocol.TType.STRUCT, org.apache.airavata.model.appcatalog.gatewayprofile.GatewayResourceProfile.class))));
      tmpMap.put(_Fields.IRE, new org.apache.thrift.meta_data.FieldMetaData("ire", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRUCT)));
      tmpMap.put(_Fields.ACE, new org.apache.thrift.meta_data.FieldMetaData("ace", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRUCT)));
      tmpMap.put(_Fields.ASE, new org.apache.thrift.meta_data.FieldMetaData("ase", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRUCT)));
      tmpMap.put(_Fields.AE, new org.apache.thrift.meta_data.FieldMetaData("ae", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRUCT)));
      metaDataMap = Collections.unmodifiableMap(tmpMap);
      org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(getAllGatewayResourceProfiles_result.class, metaDataMap);
    }

    public getAllGatewayResourceProfiles_result() {
    }

    public getAllGatewayResourceProfiles_result(
      List<org.apache.airavata.model.appcatalog.gatewayprofile.GatewayResourceProfile> success,
      org.apache.airavata.model.error.InvalidRequestException ire,
      org.apache.airavata.model.error.AiravataClientException ace,
      org.apache.airavata.model.error.AiravataSystemException ase,
      org.apache.airavata.model.error.AuthorizationException ae)
    {
      this();
      this.success = success;
      this.ire = ire;
      this.ace = ace;
      this.ase = ase;
      this.ae = ae;
    }

    /**
     * Performs a deep copy on <i>other</i>.
     */
    public getAllGatewayResourceProfiles_result(getAllGatewayResourceProfiles_result other) {
      if (other.isSetSuccess()) {
        List<org.apache.airavata.model.appcatalog.gatewayprofile.GatewayResourceProfile> __this__success = new ArrayList<org.apache.airavata.model.appcatalog.gatewayprofile.GatewayResourceProfile>(other.success.size());
        for (org.apache.airavata.model.appcatalog.gatewayprofile.GatewayResourceProfile other_element : other.success) {
          __this__success.add(new org.apache.airavata.model.appcatalog.gatewayprofile.GatewayResourceProfile(other_element));
        }
        this.success = __this__success;
      }
      if (other.isSetIre()) {
        this.ire = new org.apache.airavata.model.error.InvalidRequestException(other.ire);
      }
      if (other.isSetAce()) {
        this.ace = new org.apache.airavata.model.error.AiravataClientException(other.ace);
      }
      if (other.isSetAse()) {
        this.ase = new org.apache.airavata.model.error.AiravataSystemException(other.ase);
      }
      if (other.isSetAe()) {
        this.ae = new org.apache.airavata.model.error.AuthorizationException(other.ae);
      }
    }

    public getAllGatewayResourceProfiles_result deepCopy() {
      return new getAllGatewayResourceProfiles_result(this);
    }

    @Override
    public void clear() {
      this.success = null;
      this.ire = null;
      this.ace = null;
      this.ase = null;
      this.ae = null;
    }

    public int getSuccessSize() {
      return (this.success == null) ? 0 : this.success.size();
    }

    public java.util.Iterator<org.apache.airavata.model.appcatalog.gatewayprofile.GatewayResourceProfile> getSuccessIterator() {
      return (this.success == null) ? null : this.success.iterator();
    }

    public void addToSuccess(org.apache.airavata.model.appcatalog.gatewayprofile.GatewayResourceProfile elem) {
      if (this.success == null) {
        this.success = new ArrayList<org.apache.airavata.model.appcatalog.gatewayprofile.GatewayResourceProfile>();
      }
      this.success.add(elem);
    }

    public List<org.apache.airavata.model.appcatalog.gatewayprofile.GatewayResourceProfile> getSuccess() {
      return this.success;
    }

    public getAllGatewayResourceProfiles_result setSuccess(List<org.apache.airavata.model.appcatalog.gatewayprofile.GatewayResourceProfile> 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.model.error.InvalidRequestException getIre() {
      return this.ire;
    }

    public getAllGatewayResourceProfiles_result setIre(org.apache.airavata.model.error.InvalidRequestException ire) {
      this.ire = ire;
      return this;
    }

    public void unsetIre() {
      this.ire = null;
    }

    /** Returns true if field ire is set (has been assigned a value) and false otherwise */
    public boolean isSetIre() {
      return this.ire != null;
    }

    public void setIreIsSet(boolean value) {
      if (!value) {
        this.ire = null;
      }
    }

    public org.apache.airavata.model.error.AiravataClientException getAce() {
      return this.ace;
    }

    public getAllGatewayResourceProfiles_result setAce(org.apache.airavata.model.error.AiravataClientException ace) {
      this.ace = ace;
      return this;
    }

    public void unsetAce() {
      this.ace = null;
    }

    /** Returns true if field ace is set (has been assigned a value) and false otherwise */
    public boolean isSetAce() {
      return this.ace != null;
    }

    public void setAceIsSet(boolean value) {
      if (!value) {
        this.ace = null;
      }
    }

    public org.apache.airavata.model.error.AiravataSystemException getAse() {
      return this.ase;
    }

    public getAllGatewayResourceProfiles_result setAse(org.apache.airavata.model.error.AiravataSystemException ase) {
      this.ase = ase;
      return this;
    }

    public void unsetAse() {
      this.ase = null;
    }

    /** Returns true if field ase is set (has been assigned a value) and false otherwise */
    public boolean isSetAse() {
      return this.ase != null;
    }

    public void setAseIsSet(boolean value) {
      if (!value) {
        this.ase = null;
      }
    }

    public org.apache.airavata.model.error.AuthorizationException getAe() {
      return this.ae;
    }

    public getAllGatewayResourceProfiles_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, Object value) {
      switch (field) {
      case SUCCESS:
        if (value == null) {
          unsetSuccess();
        } else {
          setSuccess((List<org.apache.airavata.model.appcatalog.gatewayprofile.GatewayResourceProfile>)value);
        }
        break;

      case IRE:
        if (value == null) {
          unsetIre();
        } else {
          setIre((org.apache.airavata.model.error.InvalidRequestException)value);
        }
        break;

      case ACE:
        if (value == null) {
          unsetAce();
        } else {
          setAce((org.apache.airavata.model.error.AiravataClientException)value);
        }
        break;

      case ASE:
        if (value == null) {
          unsetAse();
        } else {
          setAse((org.apache.airavata.model.error.AiravataSystemException)value);
        }
        break;

      case AE:
        if (value == null) {
          unsetAe();
        } else {
          setAe((org.apache.airavata.model.error.AuthorizationException)value);
        }
        break;

      }
    }

    public Object getFieldValue(_Fields field) {
      switch (field) {
      case SUCCESS:
        return getSuccess();

      case IRE:
        return getIre();

      case ACE:
        return getAce();

      case ASE:
        return getAse();

      case AE:
        return getAe();

      }
      throw new IllegalStateException();
    }

    /** Returns true if field corresponding to fieldID is set (has been assigned a value) and false otherwise */
    public boolean isSet(_Fields field) {
      if (field == null) {
        throw new IllegalArgumentException();
      }

      switch (field) {
      case SUCCESS:
        return isSetSuccess();
      case IRE:
        return isSetIre();
      case ACE:
        return isSetAce();
      case ASE:
        return isSetAse();
      case AE:
        return isSetAe();
      }
      throw new IllegalStateException();
    }

    @Override
    public boolean equals(Object that) {
      if (that == null)
        return false;
      if (that instanceof getAllGatewayResourceProfiles_result)
        return this.equals((getAllGatewayResourceProfiles_result)that);
      return false;
    }

    public boolean equals(getAllGatewayResourceProfiles_result that) {
      if (that == null)
        return false;

      boolean this_present_success = true && this.isSetSuccess();
      boolean that_present_success = true && that.isSetSuccess();
      if (this_present_success || that_present_success) {
        if (!(this_present_success && that_present_success))
          return false;
        if (!this.success.equals(that.success))
          return false;
      }

      boolean this_present_ire = true && this.isSetIre();
      boolean that_present_ire = true && that.isSetIre();
      if (this_present_ire || that_present_ire) {
        if (!(this_present_ire && that_present_ire))
          return false;
        if (!this.ire.equals(that.ire))
          return false;
      }

      boolean this_present_ace = true && this.isSetAce();
      boolean that_present_ace = true && that.isSetAce();
      if (this_present_ace || that_present_ace) {
        if (!(this_present_ace && that_present_ace))
          return false;
        if (!this.ace.equals(that.ace))
          return false;
      }

      boolean this_present_ase = true && this.isSetAse();
      boolean that_present_ase = true && that.isSetAse();
      if (this_present_ase || that_present_ase) {
        if (!(this_present_ase && that_present_ase))
          return false;
        if (!this.ase.equals(that.ase))
          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() {
      List<Object> list = new ArrayList<Object>();

      boolean present_success = true && (isSetSuccess());
      list.add(present_success);
      if (present_success)
        list.add(success);

      boolean present_ire = true && (isSetIre());
      list.add(present_ire);
      if (present_ire)
        list.add(ire);

      boolean present_ace = true && (isSetAce());
      list.add(present_ace);
      if (present_ace)
        list.add(ace);

      boolean present_ase = true && (isSetAse());
      list.add(present_ase);
      if (present_ase)
        list.add(ase);

      boolean present_ae = true && (isSetAe());
      list.add(present_ae);
      if (present_ae)
        list.add(ae);

      return list.hashCode();
    }

    @Override
    public int compareTo(getAllGatewayResourceProfiles_result other) {
      if (!getClass().equals(other.getClass())) {
        return getClass().getName().compareTo(other.getClass().getName());
      }

      int lastComparison = 0;

      lastComparison = Boolean.valueOf(isSetSuccess()).compareTo(other.isSetSuccess());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetSuccess()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.success, other.success);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = Boolean.valueOf(isSetIre()).compareTo(other.isSetIre());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetIre()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.ire, other.ire);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = Boolean.valueOf(isSetAce()).compareTo(other.isSetAce());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetAce()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.ace, other.ace);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = Boolean.valueOf(isSetAse()).compareTo(other.isSetAse());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetAse()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.ase, other.ase);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = 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 {
      schemes.get(iprot.getScheme()).getScheme().read(iprot, this);
    }

    public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException {
      schemes.get(oprot.getScheme()).getScheme().write(oprot, this);
      }

    @Override
    public String toString() {
      StringBuilder sb = new StringBuilder("getAllGatewayResourceProfiles_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("ire:");
      if (this.ire == null) {
        sb.append("null");
      } else {
        sb.append(this.ire);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("ace:");
      if (this.ace == null) {
        sb.append("null");
      } else {
        sb.append(this.ace);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("ase:");
      if (this.ase == null) {
        sb.append("null");
      } else {
        sb.append(this.ase);
      }
      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, 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 getAllGatewayResourceProfiles_resultStandardSchemeFactory implements SchemeFactory {
      public getAllGatewayResourceProfiles_resultStandardScheme getScheme() {
        return new getAllGatewayResourceProfiles_resultStandardScheme();
      }
    }

    private static class getAllGatewayResourceProfiles_resultStandardScheme extends StandardScheme<getAllGatewayResourceProfiles_result> {

      public void read(org.apache.thrift.protocol.TProtocol iprot, getAllGatewayResourceProfiles_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 _list264 = iprot.readListBegin();
                  struct.success = new ArrayList<org.apache.airavata.model.appcatalog.gatewayprofile.GatewayResourceProfile>(_list264.size);
                  org.apache.airavata.model.appcatalog.gatewayprofile.GatewayResourceProfile _elem265;
                  for (int _i266 = 0; _i266 < _list264.size; ++_i266)
                  {
                    _elem265 = new org.apache.airavata.model.appcatalog.gatewayprofile.GatewayResourceProfile();
                    _elem265.read(iprot);
                    struct.success.add(_elem265);
                  }
                  iprot.readListEnd();
                }
                struct.setSuccessIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 1: // IRE
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.ire = new org.apache.airavata.model.error.InvalidRequestException();
                struct.ire.read(iprot);
                struct.setIreIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 2: // ACE
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.ace = new org.apache.airavata.model.error.AiravataClientException();
                struct.ace.read(iprot);
                struct.setAceIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 3: // ASE
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.ase = new org.apache.airavata.model.error.AiravataSystemException();
                struct.ase.read(iprot);
                struct.setAseIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 4: // 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, getAllGatewayResourceProfiles_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.appcatalog.gatewayprofile.GatewayResourceProfile _iter267 : struct.success)
            {
              _iter267.write(oprot);
            }
            oprot.writeListEnd();
          }
          oprot.writeFieldEnd();
        }
        if (struct.ire != null) {
          oprot.writeFieldBegin(IRE_FIELD_DESC);
          struct.ire.write(oprot);
          oprot.writeFieldEnd();
        }
        if (struct.ace != null) {
          oprot.writeFieldBegin(ACE_FIELD_DESC);
          struct.ace.write(oprot);
          oprot.writeFieldEnd();
        }
        if (struct.ase != null) {
          oprot.writeFieldBegin(ASE_FIELD_DESC);
          struct.ase.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 getAllGatewayResourceProfiles_resultTupleSchemeFactory implements SchemeFactory {
      public getAllGatewayResourceProfiles_resultTupleScheme getScheme() {
        return new getAllGatewayResourceProfiles_resultTupleScheme();
      }
    }

    private static class getAllGatewayResourceProfiles_resultTupleScheme extends TupleScheme<getAllGatewayResourceProfiles_result> {

      @Override
      public void write(org.apache.thrift.protocol.TProtocol prot, getAllGatewayResourceProfiles_result struct) throws org.apache.thrift.TException {
        TTupleProtocol oprot = (TTupleProtocol) prot;
        BitSet optionals = new BitSet();
        if (struct.isSetSuccess()) {
          optionals.set(0);
        }
        if (struct.isSetIre()) {
          optionals.set(1);
        }
        if (struct.isSetAce()) {
          optionals.set(2);
        }
        if (struct.isSetAse()) {
          optionals.set(3);
        }
        if (struct.isSetAe()) {
          optionals.set(4);
        }
        oprot.writeBitSet(optionals, 5);
        if (struct.isSetSuccess()) {
          {
            oprot.writeI32(struct.success.size());
            for (org.apache.airavata.model.appcatalog.gatewayprofile.GatewayResourceProfile _iter268 : struct.success)
            {
              _iter268.write(oprot);
            }
          }
        }
        if (struct.isSetIre()) {
          struct.ire.write(oprot);
        }
        if (struct.isSetAce()) {
          struct.ace.write(oprot);
        }
        if (struct.isSetAse()) {
          struct.ase.write(oprot);
        }
        if (struct.isSetAe()) {
          struct.ae.write(oprot);
        }
      }

      @Override
      public void read(org.apache.thrift.protocol.TProtocol prot, getAllGatewayResourceProfiles_result struct) throws org.apache.thrift.TException {
        TTupleProtocol iprot = (TTupleProtocol) prot;
        BitSet incoming = iprot.readBitSet(5);
        if (incoming.get(0)) {
          {
            org.apache.thrift.protocol.TList _list269 = new org.apache.thrift.protocol.TList(org.apache.thrift.protocol.TType.STRUCT, iprot.readI32());
            struct.success = new ArrayList<org.apache.airavata.model.appcatalog.gatewayprofile.GatewayResourceProfile>(_list269.size);
            org.apache.airavata.model.appcatalog.gatewayprofile.GatewayResourceProfile _elem270;
            for (int _i271 = 0; _i271 < _list269.size; ++_i271)
            {
              _elem270 = new org.apache.airavata.model.appcatalog.gatewayprofile.GatewayResourceProfile();
              _elem270.read(iprot);
              struct.success.add(_elem270);
            }
          }
          struct.setSuccessIsSet(true);
        }
        if (incoming.get(1)) {
          struct.ire = new org.apache.airavata.model.error.InvalidRequestException();
          struct.ire.read(iprot);
          struct.setIreIsSet(true);
        }
        if (incoming.get(2)) {
          struct.ace = new org.apache.airavata.model.error.AiravataClientException();
          struct.ace.read(iprot);
          struct.setAceIsSet(true);
        }
        if (incoming.get(3)) {
          struct.ase = new org.apache.airavata.model.error.AiravataSystemException();
          struct.ase.read(iprot);
          struct.setAseIsSet(true);
        }
        if (incoming.get(4)) {
          struct.ae = new org.apache.airavata.model.error.AuthorizationException();
          struct.ae.read(iprot);
          struct.setAeIsSet(true);
        }
      }
    }

  }

  public static class updateGatewayComputeResourcePreference_args implements org.apache.thrift.TBase<updateGatewayComputeResourcePreference_args, updateGatewayComputeResourcePreference_args._Fields>, java.io.Serializable, Cloneable, Comparable<updateGatewayComputeResourcePreference_args>   {
    private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("updateGatewayComputeResourcePreference_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.protocol.TField COMPUTE_RESOURCE_ID_FIELD_DESC = new org.apache.thrift.protocol.TField("computeResourceId", org.apache.thrift.protocol.TType.STRING, (short)3);
    private static final org.apache.thrift.protocol.TField COMPUTE_RESOURCE_PREFERENCE_FIELD_DESC = new org.apache.thrift.protocol.TField("computeResourcePreference", org.apache.thrift.protocol.TType.STRUCT, (short)4);

    private static final Map<Class<? extends IScheme>, SchemeFactory> schemes = new HashMap<Class<? extends IScheme>, SchemeFactory>();
    static {
      schemes.put(StandardScheme.class, new updateGatewayComputeResourcePreference_argsStandardSchemeFactory());
      schemes.put(TupleScheme.class, new updateGatewayComputeResourcePreference_argsTupleSchemeFactory());
    }

    public org.apache.airavata.model.security.AuthzToken authzToken; // required
    public String gatewayID; // required
    public String computeResourceId; // required
    public org.apache.airavata.model.appcatalog.gatewayprofile.ComputeResourcePreference computeResourcePreference; // required

    /** 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"),
      COMPUTE_RESOURCE_ID((short)3, "computeResourceId"),
      COMPUTE_RESOURCE_PREFERENCE((short)4, "computeResourcePreference");

      private static final Map<String, _Fields> byName = new HashMap<String, _Fields>();

      static {
        for (_Fields field : EnumSet.allOf(_Fields.class)) {
          byName.put(field.getFieldName(), field);
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, or null if its not found.
       */
      public static _Fields findByThriftId(int fieldId) {
        switch(fieldId) {
          case 1: // AUTHZ_TOKEN
            return AUTHZ_TOKEN;
          case 2: // GATEWAY_ID
            return GATEWAY_ID;
          case 3: // COMPUTE_RESOURCE_ID
            return COMPUTE_RESOURCE_ID;
          case 4: // COMPUTE_RESOURCE_PREFERENCE
            return COMPUTE_RESOURCE_PREFERENCE;
          default:
            return null;
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, throwing an exception
       * if it is not found.
       */
      public static _Fields findByThriftIdOrThrow(int fieldId) {
        _Fields fields = findByThriftId(fieldId);
        if (fields == null) throw new IllegalArgumentException("Field " + fieldId + " doesn't exist!");
        return fields;
      }

      /**
       * Find the _Fields constant that matches name, or null if its not found.
       */
      public static _Fields findByName(String name) {
        return byName.get(name);
      }

      private final short _thriftId;
      private final String _fieldName;

      _Fields(short thriftId, String fieldName) {
        _thriftId = thriftId;
        _fieldName = fieldName;
      }

      public short getThriftFieldId() {
        return _thriftId;
      }

      public String getFieldName() {
        return _fieldName;
      }
    }

    // isset id assignments
    public static final Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
    static {
      Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new EnumMap<_Fields, org.apache.thrift.meta_data.FieldMetaData>(_Fields.class);
      tmpMap.put(_Fields.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)));
      tmpMap.put(_Fields.COMPUTE_RESOURCE_ID, new org.apache.thrift.meta_data.FieldMetaData("computeResourceId", org.apache.thrift.TFieldRequirementType.REQUIRED, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING)));
      tmpMap.put(_Fields.COMPUTE_RESOURCE_PREFERENCE, new org.apache.thrift.meta_data.FieldMetaData("computeResourcePreference", org.apache.thrift.TFieldRequirementType.REQUIRED, 
          new org.apache.thrift.meta_data.StructMetaData(org.apache.thrift.protocol.TType.STRUCT, org.apache.airavata.model.appcatalog.gatewayprofile.ComputeResourcePreference.class)));
      metaDataMap = Collections.unmodifiableMap(tmpMap);
      org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(updateGatewayComputeResourcePreference_args.class, metaDataMap);
    }

    public updateGatewayComputeResourcePreference_args() {
    }

    public updateGatewayComputeResourcePreference_args(
      org.apache.airavata.model.security.AuthzToken authzToken,
      String gatewayID,
      String computeResourceId,
      org.apache.airavata.model.appcatalog.gatewayprofile.ComputeResourcePreference computeResourcePreference)
    {
      this();
      this.authzToken = authzToken;
      this.gatewayID = gatewayID;
      this.computeResourceId = computeResourceId;
      this.computeResourcePreference = computeResourcePreference;
    }

    /**
     * Performs a deep copy on <i>other</i>.
     */
    public updateGatewayComputeResourcePreference_args(updateGatewayComputeResourcePreference_args other) {
      if (other.isSetAuthzToken()) {
        this.authzToken = new org.apache.airavata.model.security.AuthzToken(other.authzToken);
      }
      if (other.isSetGatewayID()) {
        this.gatewayID = other.gatewayID;
      }
      if (other.isSetComputeResourceId()) {
        this.computeResourceId = other.computeResourceId;
      }
      if (other.isSetComputeResourcePreference()) {
        this.computeResourcePreference = new org.apache.airavata.model.appcatalog.gatewayprofile.ComputeResourcePreference(other.computeResourcePreference);
      }
    }

    public updateGatewayComputeResourcePreference_args deepCopy() {
      return new updateGatewayComputeResourcePreference_args(this);
    }

    @Override
    public void clear() {
      this.authzToken = null;
      this.gatewayID = null;
      this.computeResourceId = null;
      this.computeResourcePreference = null;
    }

    public org.apache.airavata.model.security.AuthzToken getAuthzToken() {
      return this.authzToken;
    }

    public updateGatewayComputeResourcePreference_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 String getGatewayID() {
      return this.gatewayID;
    }

    public updateGatewayComputeResourcePreference_args setGatewayID(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 String getComputeResourceId() {
      return this.computeResourceId;
    }

    public updateGatewayComputeResourcePreference_args setComputeResourceId(String computeResourceId) {
      this.computeResourceId = computeResourceId;
      return this;
    }

    public void unsetComputeResourceId() {
      this.computeResourceId = null;
    }

    /** Returns true if field computeResourceId is set (has been assigned a value) and false otherwise */
    public boolean isSetComputeResourceId() {
      return this.computeResourceId != null;
    }

    public void setComputeResourceIdIsSet(boolean value) {
      if (!value) {
        this.computeResourceId = null;
      }
    }

    public org.apache.airavata.model.appcatalog.gatewayprofile.ComputeResourcePreference getComputeResourcePreference() {
      return this.computeResourcePreference;
    }

    public updateGatewayComputeResourcePreference_args setComputeResourcePreference(org.apache.airavata.model.appcatalog.gatewayprofile.ComputeResourcePreference computeResourcePreference) {
      this.computeResourcePreference = computeResourcePreference;
      return this;
    }

    public void unsetComputeResourcePreference() {
      this.computeResourcePreference = null;
    }

    /** Returns true if field computeResourcePreference is set (has been assigned a value) and false otherwise */
    public boolean isSetComputeResourcePreference() {
      return this.computeResourcePreference != null;
    }

    public void setComputeResourcePreferenceIsSet(boolean value) {
      if (!value) {
        this.computeResourcePreference = null;
      }
    }

    public void setFieldValue(_Fields field, 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((String)value);
        }
        break;

      case COMPUTE_RESOURCE_ID:
        if (value == null) {
          unsetComputeResourceId();
        } else {
          setComputeResourceId((String)value);
        }
        break;

      case COMPUTE_RESOURCE_PREFERENCE:
        if (value == null) {
          unsetComputeResourcePreference();
        } else {
          setComputeResourcePreference((org.apache.airavata.model.appcatalog.gatewayprofile.ComputeResourcePreference)value);
        }
        break;

      }
    }

    public Object getFieldValue(_Fields field) {
      switch (field) {
      case AUTHZ_TOKEN:
        return getAuthzToken();

      case GATEWAY_ID:
        return getGatewayID();

      case COMPUTE_RESOURCE_ID:
        return getComputeResourceId();

      case COMPUTE_RESOURCE_PREFERENCE:
        return getComputeResourcePreference();

      }
      throw new IllegalStateException();
    }

    /** Returns true if field corresponding to fieldID is set (has been assigned a value) and false otherwise */
    public boolean isSet(_Fields field) {
      if (field == null) {
        throw new IllegalArgumentException();
      }

      switch (field) {
      case AUTHZ_TOKEN:
        return isSetAuthzToken();
      case GATEWAY_ID:
        return isSetGatewayID();
      case COMPUTE_RESOURCE_ID:
        return isSetComputeResourceId();
      case COMPUTE_RESOURCE_PREFERENCE:
        return isSetComputeResourcePreference();
      }
      throw new IllegalStateException();
    }

    @Override
    public boolean equals(Object that) {
      if (that == null)
        return false;
      if (that instanceof updateGatewayComputeResourcePreference_args)
        return this.equals((updateGatewayComputeResourcePreference_args)that);
      return false;
    }

    public boolean equals(updateGatewayComputeResourcePreference_args that) {
      if (that == null)
        return false;

      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;
      }

      boolean this_present_computeResourceId = true && this.isSetComputeResourceId();
      boolean that_present_computeResourceId = true && that.isSetComputeResourceId();
      if (this_present_computeResourceId || that_present_computeResourceId) {
        if (!(this_present_computeResourceId && that_present_computeResourceId))
          return false;
        if (!this.computeResourceId.equals(that.computeResourceId))
          return false;
      }

      boolean this_present_computeResourcePreference = true && this.isSetComputeResourcePreference();
      boolean that_present_computeResourcePreference = true && that.isSetComputeResourcePreference();
      if (this_present_computeResourcePreference || that_present_computeResourcePreference) {
        if (!(this_present_computeResourcePreference && that_present_computeResourcePreference))
          return false;
        if (!this.computeResourcePreference.equals(that.computeResourcePreference))
          return false;
      }

      return true;
    }

    @Override
    public int hashCode() {
      List<Object> list = new ArrayList<Object>();

      boolean present_authzToken = true && (isSetAuthzToken());
      list.add(present_authzToken);
      if (present_authzToken)
        list.add(authzToken);

      boolean present_gatewayID = true && (isSetGatewayID());
      list.add(present_gatewayID);
      if (present_gatewayID)
        list.add(gatewayID);

      boolean present_computeResourceId = true && (isSetComputeResourceId());
      list.add(present_computeResourceId);
      if (present_computeResourceId)
        list.add(computeResourceId);

      boolean present_computeResourcePreference = true && (isSetComputeResourcePreference());
      list.add(present_computeResourcePreference);
      if (present_computeResourcePreference)
        list.add(computeResourcePreference);

      return list.hashCode();
    }

    @Override
    public int compareTo(updateGatewayComputeResourcePreference_args other) {
      if (!getClass().equals(other.getClass())) {
        return getClass().getName().compareTo(other.getClass().getName());
      }

      int lastComparison = 0;

      lastComparison = 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 = 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;
        }
      }
      lastComparison = Boolean.valueOf(isSetComputeResourceId()).compareTo(other.isSetComputeResourceId());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetComputeResourceId()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.computeResourceId, other.computeResourceId);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = Boolean.valueOf(isSetComputeResourcePreference()).compareTo(other.isSetComputeResourcePreference());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetComputeResourcePreference()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.computeResourcePreference, other.computeResourcePreference);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      return 0;
    }

    public _Fields fieldForId(int fieldId) {
      return _Fields.findByThriftId(fieldId);
    }

    public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
      schemes.get(iprot.getScheme()).getScheme().read(iprot, this);
    }

    public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException {
      schemes.get(oprot.getScheme()).getScheme().write(oprot, this);
    }

    @Override
    public String toString() {
      StringBuilder sb = new StringBuilder("updateGatewayComputeResourcePreference_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;
      if (!first) sb.append(", ");
      sb.append("computeResourceId:");
      if (this.computeResourceId == null) {
        sb.append("null");
      } else {
        sb.append(this.computeResourceId);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("computeResourcePreference:");
      if (this.computeResourcePreference == null) {
        sb.append("null");
      } else {
        sb.append(this.computeResourcePreference);
      }
      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());
      }
      if (computeResourceId == null) {
        throw new org.apache.thrift.protocol.TProtocolException("Required field 'computeResourceId' was not present! Struct: " + toString());
      }
      if (computeResourcePreference == null) {
        throw new org.apache.thrift.protocol.TProtocolException("Required field 'computeResourcePreference' was not present! Struct: " + toString());
      }
      // check for sub-struct validity
      if (authzToken != null) {
        authzToken.validate();
      }
      if (computeResourcePreference != null) {
        computeResourcePreference.validate();
      }
    }

    private void writeObject(java.io.ObjectOutputStream out) throws java.io.IOException {
      try {
        write(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(out)));
      } catch (org.apache.thrift.TException te) {
        throw new java.io.IOException(te);
      }
    }

    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, ClassNotFoundException {
      try {
        read(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(in)));
      } catch (org.apache.thrift.TException te) {
        throw new java.io.IOException(te);
      }
    }

    private static class updateGatewayComputeResourcePreference_argsStandardSchemeFactory implements SchemeFactory {
      public updateGatewayComputeResourcePreference_argsStandardScheme getScheme() {
        return new updateGatewayComputeResourcePreference_argsStandardScheme();
      }
    }

    private static class updateGatewayComputeResourcePreference_argsStandardScheme extends StandardScheme<updateGatewayComputeResourcePreference_args> {

      public void read(org.apache.thrift.protocol.TProtocol iprot, updateGatewayComputeResourcePreference_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;
            case 3: // COMPUTE_RESOURCE_ID
              if (schemeField.type == org.apache.thrift.protocol.TType.STRING) {
                struct.computeResourceId = iprot.readString();
                struct.setComputeResourceIdIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 4: // COMPUTE_RESOURCE_PREFERENCE
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.computeResourcePreference = new org.apache.airavata.model.appcatalog.gatewayprofile.ComputeResourcePreference();
                struct.computeResourcePreference.read(iprot);
                struct.setComputeResourcePreferenceIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            default:
              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
          }
          iprot.readFieldEnd();
        }
        iprot.readStructEnd();

        // check for required fields of primitive type, which can't be checked in the validate method
        struct.validate();
      }

      public void write(org.apache.thrift.protocol.TProtocol oprot, updateGatewayComputeResourcePreference_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();
        }
        if (struct.computeResourceId != null) {
          oprot.writeFieldBegin(COMPUTE_RESOURCE_ID_FIELD_DESC);
          oprot.writeString(struct.computeResourceId);
          oprot.writeFieldEnd();
        }
        if (struct.computeResourcePreference != null) {
          oprot.writeFieldBegin(COMPUTE_RESOURCE_PREFERENCE_FIELD_DESC);
          struct.computeResourcePreference.write(oprot);
          oprot.writeFieldEnd();
        }
        oprot.writeFieldStop();
        oprot.writeStructEnd();
      }

    }

    private static class updateGatewayComputeResourcePreference_argsTupleSchemeFactory implements SchemeFactory {
      public updateGatewayComputeResourcePreference_argsTupleScheme getScheme() {
        return new updateGatewayComputeResourcePreference_argsTupleScheme();
      }
    }

    private static class updateGatewayComputeResourcePreference_argsTupleScheme extends TupleScheme<updateGatewayComputeResourcePreference_args> {

      @Override
      public void write(org.apache.thrift.protocol.TProtocol prot, updateGatewayComputeResourcePreference_args struct) throws org.apache.thrift.TException {
        TTupleProtocol oprot = (TTupleProtocol) prot;
        struct.authzToken.write(oprot);
        oprot.writeString(struct.gatewayID);
        oprot.writeString(struct.computeResourceId);
        struct.computeResourcePreference.write(oprot);
      }

      @Override
      public void read(org.apache.thrift.protocol.TProtocol prot, updateGatewayComputeResourcePreference_args struct) throws org.apache.thrift.TException {
        TTupleProtocol iprot = (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);
        struct.computeResourceId = iprot.readString();
        struct.setComputeResourceIdIsSet(true);
        struct.computeResourcePreference = new org.apache.airavata.model.appcatalog.gatewayprofile.ComputeResourcePreference();
        struct.computeResourcePreference.read(iprot);
        struct.setComputeResourcePreferenceIsSet(true);
      }
    }

  }

  public static class updateGatewayComputeResourcePreference_result implements org.apache.thrift.TBase<updateGatewayComputeResourcePreference_result, updateGatewayComputeResourcePreference_result._Fields>, java.io.Serializable, Cloneable, Comparable<updateGatewayComputeResourcePreference_result>   {
    private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("updateGatewayComputeResourcePreference_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 IRE_FIELD_DESC = new org.apache.thrift.protocol.TField("ire", org.apache.thrift.protocol.TType.STRUCT, (short)1);
    private static final org.apache.thrift.protocol.TField ACE_FIELD_DESC = new org.apache.thrift.protocol.TField("ace", org.apache.thrift.protocol.TType.STRUCT, (short)2);
    private static final org.apache.thrift.protocol.TField ASE_FIELD_DESC = new org.apache.thrift.protocol.TField("ase", org.apache.thrift.protocol.TType.STRUCT, (short)3);
    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)4);

    private static final Map<Class<? extends IScheme>, SchemeFactory> schemes = new HashMap<Class<? extends IScheme>, SchemeFactory>();
    static {
      schemes.put(StandardScheme.class, new updateGatewayComputeResourcePreference_resultStandardSchemeFactory());
      schemes.put(TupleScheme.class, new updateGatewayComputeResourcePreference_resultTupleSchemeFactory());
    }

    public boolean success; // required
    public org.apache.airavata.model.error.InvalidRequestException ire; // required
    public org.apache.airavata.model.error.AiravataClientException ace; // required
    public org.apache.airavata.model.error.AiravataSystemException ase; // 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"),
      IRE((short)1, "ire"),
      ACE((short)2, "ace"),
      ASE((short)3, "ase"),
      AE((short)4, "ae");

      private static final Map<String, _Fields> byName = new HashMap<String, _Fields>();

      static {
        for (_Fields field : EnumSet.allOf(_Fields.class)) {
          byName.put(field.getFieldName(), field);
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, or null if its not found.
       */
      public static _Fields findByThriftId(int fieldId) {
        switch(fieldId) {
          case 0: // SUCCESS
            return SUCCESS;
          case 1: // IRE
            return IRE;
          case 2: // ACE
            return ACE;
          case 3: // ASE
            return ASE;
          case 4: // 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 IllegalArgumentException("Field " + fieldId + " doesn't exist!");
        return fields;
      }

      /**
       * Find the _Fields constant that matches name, or null if its not found.
       */
      public static _Fields findByName(String name) {
        return byName.get(name);
      }

      private final short _thriftId;
      private final String _fieldName;

      _Fields(short thriftId, String fieldName) {
        _thriftId = thriftId;
        _fieldName = fieldName;
      }

      public short getThriftFieldId() {
        return _thriftId;
      }

      public String getFieldName() {
        return _fieldName;
      }
    }

    // isset id assignments
    private static final int __SUCCESS_ISSET_ID = 0;
    private byte __isset_bitfield = 0;
    public static final Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
    static {
      Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new EnumMap<_Fields, org.apache.thrift.meta_data.FieldMetaData>(_Fields.class);
      tmpMap.put(_Fields.SUCCESS, new org.apache.thrift.meta_data.FieldMetaData("success", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.BOOL)));
      tmpMap.put(_Fields.IRE, new org.apache.thrift.meta_data.FieldMetaData("ire", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRUCT)));
      tmpMap.put(_Fields.ACE, new org.apache.thrift.meta_data.FieldMetaData("ace", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRUCT)));
      tmpMap.put(_Fields.ASE, new org.apache.thrift.meta_data.FieldMetaData("ase", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRUCT)));
      tmpMap.put(_Fields.AE, new org.apache.thrift.meta_data.FieldMetaData("ae", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRUCT)));
      metaDataMap = Collections.unmodifiableMap(tmpMap);
      org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(updateGatewayComputeResourcePreference_result.class, metaDataMap);
    }

    public updateGatewayComputeResourcePreference_result() {
    }

    public updateGatewayComputeResourcePreference_result(
      boolean success,
      org.apache.airavata.model.error.InvalidRequestException ire,
      org.apache.airavata.model.error.AiravataClientException ace,
      org.apache.airavata.model.error.AiravataSystemException ase,
      org.apache.airavata.model.error.AuthorizationException ae)
    {
      this();
      this.success = success;
      setSuccessIsSet(true);
      this.ire = ire;
      this.ace = ace;
      this.ase = ase;
      this.ae = ae;
    }

    /**
     * Performs a deep copy on <i>other</i>.
     */
    public updateGatewayComputeResourcePreference_result(updateGatewayComputeResourcePreference_result other) {
      __isset_bitfield = other.__isset_bitfield;
      this.success = other.success;
      if (other.isSetIre()) {
        this.ire = new org.apache.airavata.model.error.InvalidRequestException(other.ire);
      }
      if (other.isSetAce()) {
        this.ace = new org.apache.airavata.model.error.AiravataClientException(other.ace);
      }
      if (other.isSetAse()) {
        this.ase = new org.apache.airavata.model.error.AiravataSystemException(other.ase);
      }
      if (other.isSetAe()) {
        this.ae = new org.apache.airavata.model.error.AuthorizationException(other.ae);
      }
    }

    public updateGatewayComputeResourcePreference_result deepCopy() {
      return new updateGatewayComputeResourcePreference_result(this);
    }

    @Override
    public void clear() {
      setSuccessIsSet(false);
      this.success = false;
      this.ire = null;
      this.ace = null;
      this.ase = null;
      this.ae = null;
    }

    public boolean isSuccess() {
      return this.success;
    }

    public updateGatewayComputeResourcePreference_result setSuccess(boolean success) {
      this.success = success;
      setSuccessIsSet(true);
      return this;
    }

    public void unsetSuccess() {
      __isset_bitfield = EncodingUtils.clearBit(__isset_bitfield, __SUCCESS_ISSET_ID);
    }

    /** Returns true if field success is set (has been assigned a value) and false otherwise */
    public boolean isSetSuccess() {
      return EncodingUtils.testBit(__isset_bitfield, __SUCCESS_ISSET_ID);
    }

    public void setSuccessIsSet(boolean value) {
      __isset_bitfield = EncodingUtils.setBit(__isset_bitfield, __SUCCESS_ISSET_ID, value);
    }

    public org.apache.airavata.model.error.InvalidRequestException getIre() {
      return this.ire;
    }

    public updateGatewayComputeResourcePreference_result setIre(org.apache.airavata.model.error.InvalidRequestException ire) {
      this.ire = ire;
      return this;
    }

    public void unsetIre() {
      this.ire = null;
    }

    /** Returns true if field ire is set (has been assigned a value) and false otherwise */
    public boolean isSetIre() {
      return this.ire != null;
    }

    public void setIreIsSet(boolean value) {
      if (!value) {
        this.ire = null;
      }
    }

    public org.apache.airavata.model.error.AiravataClientException getAce() {
      return this.ace;
    }

    public updateGatewayComputeResourcePreference_result setAce(org.apache.airavata.model.error.AiravataClientException ace) {
      this.ace = ace;
      return this;
    }

    public void unsetAce() {
      this.ace = null;
    }

    /** Returns true if field ace is set (has been assigned a value) and false otherwise */
    public boolean isSetAce() {
      return this.ace != null;
    }

    public void setAceIsSet(boolean value) {
      if (!value) {
        this.ace = null;
      }
    }

    public org.apache.airavata.model.error.AiravataSystemException getAse() {
      return this.ase;
    }

    public updateGatewayComputeResourcePreference_result setAse(org.apache.airavata.model.error.AiravataSystemException ase) {
      this.ase = ase;
      return this;
    }

    public void unsetAse() {
      this.ase = null;
    }

    /** Returns true if field ase is set (has been assigned a value) and false otherwise */
    public boolean isSetAse() {
      return this.ase != null;
    }

    public void setAseIsSet(boolean value) {
      if (!value) {
        this.ase = null;
      }
    }

    public org.apache.airavata.model.error.AuthorizationException getAe() {
      return this.ae;
    }

    public updateGatewayComputeResourcePreference_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, Object value) {
      switch (field) {
      case SUCCESS:
        if (value == null) {
          unsetSuccess();
        } else {
          setSuccess((Boolean)value);
        }
        break;

      case IRE:
        if (value == null) {
          unsetIre();
        } else {
          setIre((org.apache.airavata.model.error.InvalidRequestException)value);
        }
        break;

      case ACE:
        if (value == null) {
          unsetAce();
        } else {
          setAce((org.apache.airavata.model.error.AiravataClientException)value);
        }
        break;

      case ASE:
        if (value == null) {
          unsetAse();
        } else {
          setAse((org.apache.airavata.model.error.AiravataSystemException)value);
        }
        break;

      case AE:
        if (value == null) {
          unsetAe();
        } else {
          setAe((org.apache.airavata.model.error.AuthorizationException)value);
        }
        break;

      }
    }

    public Object getFieldValue(_Fields field) {
      switch (field) {
      case SUCCESS:
        return Boolean.valueOf(isSuccess());

      case IRE:
        return getIre();

      case ACE:
        return getAce();

      case ASE:
        return getAse();

      case AE:
        return getAe();

      }
      throw new IllegalStateException();
    }

    /** Returns true if field corresponding to fieldID is set (has been assigned a value) and false otherwise */
    public boolean isSet(_Fields field) {
      if (field == null) {
        throw new IllegalArgumentException();
      }

      switch (field) {
      case SUCCESS:
        return isSetSuccess();
      case IRE:
        return isSetIre();
      case ACE:
        return isSetAce();
      case ASE:
        return isSetAse();
      case AE:
        return isSetAe();
      }
      throw new IllegalStateException();
    }

    @Override
    public boolean equals(Object that) {
      if (that == null)
        return false;
      if (that instanceof updateGatewayComputeResourcePreference_result)
        return this.equals((updateGatewayComputeResourcePreference_result)that);
      return false;
    }

    public boolean equals(updateGatewayComputeResourcePreference_result that) {
      if (that == null)
        return false;

      boolean this_present_success = true;
      boolean that_present_success = true;
      if (this_present_success || that_present_success) {
        if (!(this_present_success && that_present_success))
          return false;
        if (this.success != that.success)
          return false;
      }

      boolean this_present_ire = true && this.isSetIre();
      boolean that_present_ire = true && that.isSetIre();
      if (this_present_ire || that_present_ire) {
        if (!(this_present_ire && that_present_ire))
          return false;
        if (!this.ire.equals(that.ire))
          return false;
      }

      boolean this_present_ace = true && this.isSetAce();
      boolean that_present_ace = true && that.isSetAce();
      if (this_present_ace || that_present_ace) {
        if (!(this_present_ace && that_present_ace))
          return false;
        if (!this.ace.equals(that.ace))
          return false;
      }

      boolean this_present_ase = true && this.isSetAse();
      boolean that_present_ase = true && that.isSetAse();
      if (this_present_ase || that_present_ase) {
        if (!(this_present_ase && that_present_ase))
          return false;
        if (!this.ase.equals(that.ase))
          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() {
      List<Object> list = new ArrayList<Object>();

      boolean present_success = true;
      list.add(present_success);
      if (present_success)
        list.add(success);

      boolean present_ire = true && (isSetIre());
      list.add(present_ire);
      if (present_ire)
        list.add(ire);

      boolean present_ace = true && (isSetAce());
      list.add(present_ace);
      if (present_ace)
        list.add(ace);

      boolean present_ase = true && (isSetAse());
      list.add(present_ase);
      if (present_ase)
        list.add(ase);

      boolean present_ae = true && (isSetAe());
      list.add(present_ae);
      if (present_ae)
        list.add(ae);

      return list.hashCode();
    }

    @Override
    public int compareTo(updateGatewayComputeResourcePreference_result other) {
      if (!getClass().equals(other.getClass())) {
        return getClass().getName().compareTo(other.getClass().getName());
      }

      int lastComparison = 0;

      lastComparison = Boolean.valueOf(isSetSuccess()).compareTo(other.isSetSuccess());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetSuccess()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.success, other.success);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = Boolean.valueOf(isSetIre()).compareTo(other.isSetIre());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetIre()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.ire, other.ire);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = Boolean.valueOf(isSetAce()).compareTo(other.isSetAce());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetAce()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.ace, other.ace);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = Boolean.valueOf(isSetAse()).compareTo(other.isSetAse());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetAse()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.ase, other.ase);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = 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 {
      schemes.get(iprot.getScheme()).getScheme().read(iprot, this);
    }

    public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException {
      schemes.get(oprot.getScheme()).getScheme().write(oprot, this);
      }

    @Override
    public String toString() {
      StringBuilder sb = new StringBuilder("updateGatewayComputeResourcePreference_result(");
      boolean first = true;

      sb.append("success:");
      sb.append(this.success);
      first = false;
      if (!first) sb.append(", ");
      sb.append("ire:");
      if (this.ire == null) {
        sb.append("null");
      } else {
        sb.append(this.ire);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("ace:");
      if (this.ace == null) {
        sb.append("null");
      } else {
        sb.append(this.ace);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("ase:");
      if (this.ase == null) {
        sb.append("null");
      } else {
        sb.append(this.ase);
      }
      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, 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 updateGatewayComputeResourcePreference_resultStandardSchemeFactory implements SchemeFactory {
      public updateGatewayComputeResourcePreference_resultStandardScheme getScheme() {
        return new updateGatewayComputeResourcePreference_resultStandardScheme();
      }
    }

    private static class updateGatewayComputeResourcePreference_resultStandardScheme extends StandardScheme<updateGatewayComputeResourcePreference_result> {

      public void read(org.apache.thrift.protocol.TProtocol iprot, updateGatewayComputeResourcePreference_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: // IRE
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.ire = new org.apache.airavata.model.error.InvalidRequestException();
                struct.ire.read(iprot);
                struct.setIreIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 2: // ACE
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.ace = new org.apache.airavata.model.error.AiravataClientException();
                struct.ace.read(iprot);
                struct.setAceIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 3: // ASE
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.ase = new org.apache.airavata.model.error.AiravataSystemException();
                struct.ase.read(iprot);
                struct.setAseIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 4: // 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, updateGatewayComputeResourcePreference_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.ire != null) {
          oprot.writeFieldBegin(IRE_FIELD_DESC);
          struct.ire.write(oprot);
          oprot.writeFieldEnd();
        }
        if (struct.ace != null) {
          oprot.writeFieldBegin(ACE_FIELD_DESC);
          struct.ace.write(oprot);
          oprot.writeFieldEnd();
        }
        if (struct.ase != null) {
          oprot.writeFieldBegin(ASE_FIELD_DESC);
          struct.ase.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 updateGatewayComputeResourcePreference_resultTupleSchemeFactory implements SchemeFactory {
      public updateGatewayComputeResourcePreference_resultTupleScheme getScheme() {
        return new updateGatewayComputeResourcePreference_resultTupleScheme();
      }
    }

    private static class updateGatewayComputeResourcePreference_resultTupleScheme extends TupleScheme<updateGatewayComputeResourcePreference_result> {

      @Override
      public void write(org.apache.thrift.protocol.TProtocol prot, updateGatewayComputeResourcePreference_result struct) throws org.apache.thrift.TException {
        TTupleProtocol oprot = (TTupleProtocol) prot;
        BitSet optionals = new BitSet();
        if (struct.isSetSuccess()) {
          optionals.set(0);
        }
        if (struct.isSetIre()) {
          optionals.set(1);
        }
        if (struct.isSetAce()) {
          optionals.set(2);
        }
        if (struct.isSetAse()) {
          optionals.set(3);
        }
        if (struct.isSetAe()) {
          optionals.set(4);
        }
        oprot.writeBitSet(optionals, 5);
        if (struct.isSetSuccess()) {
          oprot.writeBool(struct.success);
        }
        if (struct.isSetIre()) {
          struct.ire.write(oprot);
        }
        if (struct.isSetAce()) {
          struct.ace.write(oprot);
        }
        if (struct.isSetAse()) {
          struct.ase.write(oprot);
        }
        if (struct.isSetAe()) {
          struct.ae.write(oprot);
        }
      }

      @Override
      public void read(org.apache.thrift.protocol.TProtocol prot, updateGatewayComputeResourcePreference_result struct) throws org.apache.thrift.TException {
        TTupleProtocol iprot = (TTupleProtocol) prot;
        BitSet incoming = iprot.readBitSet(5);
        if (incoming.get(0)) {
          struct.success = iprot.readBool();
          struct.setSuccessIsSet(true);
        }
        if (incoming.get(1)) {
          struct.ire = new org.apache.airavata.model.error.InvalidRequestException();
          struct.ire.read(iprot);
          struct.setIreIsSet(true);
        }
        if (incoming.get(2)) {
          struct.ace = new org.apache.airavata.model.error.AiravataClientException();
          struct.ace.read(iprot);
          struct.setAceIsSet(true);
        }
        if (incoming.get(3)) {
          struct.ase = new org.apache.airavata.model.error.AiravataSystemException();
          struct.ase.read(iprot);
          struct.setAseIsSet(true);
        }
        if (incoming.get(4)) {
          struct.ae = new org.apache.airavata.model.error.AuthorizationException();
          struct.ae.read(iprot);
          struct.setAeIsSet(true);
        }
      }
    }

  }

  public static class updateGatewayDataStoragePreference_args implements org.apache.thrift.TBase<updateGatewayDataStoragePreference_args, updateGatewayDataStoragePreference_args._Fields>, java.io.Serializable, Cloneable, Comparable<updateGatewayDataStoragePreference_args>   {
    private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("updateGatewayDataStoragePreference_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.protocol.TField DATA_MOVE_ID_FIELD_DESC = new org.apache.thrift.protocol.TField("dataMoveId", org.apache.thrift.protocol.TType.STRING, (short)3);
    private static final org.apache.thrift.protocol.TField DATA_STORAGE_PREFERENCE_FIELD_DESC = new org.apache.thrift.protocol.TField("dataStoragePreference", org.apache.thrift.protocol.TType.STRUCT, (short)4);

    private static final Map<Class<? extends IScheme>, SchemeFactory> schemes = new HashMap<Class<? extends IScheme>, SchemeFactory>();
    static {
      schemes.put(StandardScheme.class, new updateGatewayDataStoragePreference_argsStandardSchemeFactory());
      schemes.put(TupleScheme.class, new updateGatewayDataStoragePreference_argsTupleSchemeFactory());
    }

    public org.apache.airavata.model.security.AuthzToken authzToken; // required
    public String gatewayID; // required
    public String dataMoveId; // required
    public org.apache.airavata.model.appcatalog.gatewayprofile.DataStoragePreference dataStoragePreference; // required

    /** 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"),
      DATA_MOVE_ID((short)3, "dataMoveId"),
      DATA_STORAGE_PREFERENCE((short)4, "dataStoragePreference");

      private static final Map<String, _Fields> byName = new HashMap<String, _Fields>();

      static {
        for (_Fields field : EnumSet.allOf(_Fields.class)) {
          byName.put(field.getFieldName(), field);
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, or null if its not found.
       */
      public static _Fields findByThriftId(int fieldId) {
        switch(fieldId) {
          case 1: // AUTHZ_TOKEN
            return AUTHZ_TOKEN;
          case 2: // GATEWAY_ID
            return GATEWAY_ID;
          case 3: // DATA_MOVE_ID
            return DATA_MOVE_ID;
          case 4: // DATA_STORAGE_PREFERENCE
            return DATA_STORAGE_PREFERENCE;
          default:
            return null;
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, throwing an exception
       * if it is not found.
       */
      public static _Fields findByThriftIdOrThrow(int fieldId) {
        _Fields fields = findByThriftId(fieldId);
        if (fields == null) throw new IllegalArgumentException("Field " + fieldId + " doesn't exist!");
        return fields;
      }

      /**
       * Find the _Fields constant that matches name, or null if its not found.
       */
      public static _Fields findByName(String name) {
        return byName.get(name);
      }

      private final short _thriftId;
      private final String _fieldName;

      _Fields(short thriftId, String fieldName) {
        _thriftId = thriftId;
        _fieldName = fieldName;
      }

      public short getThriftFieldId() {
        return _thriftId;
      }

      public String getFieldName() {
        return _fieldName;
      }
    }

    // isset id assignments
    public static final Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
    static {
      Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new EnumMap<_Fields, org.apache.thrift.meta_data.FieldMetaData>(_Fields.class);
      tmpMap.put(_Fields.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)));
      tmpMap.put(_Fields.DATA_MOVE_ID, new org.apache.thrift.meta_data.FieldMetaData("dataMoveId", org.apache.thrift.TFieldRequirementType.REQUIRED, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING)));
      tmpMap.put(_Fields.DATA_STORAGE_PREFERENCE, new org.apache.thrift.meta_data.FieldMetaData("dataStoragePreference", org.apache.thrift.TFieldRequirementType.REQUIRED, 
          new org.apache.thrift.meta_data.StructMetaData(org.apache.thrift.protocol.TType.STRUCT, org.apache.airavata.model.appcatalog.gatewayprofile.DataStoragePreference.class)));
      metaDataMap = Collections.unmodifiableMap(tmpMap);
      org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(updateGatewayDataStoragePreference_args.class, metaDataMap);
    }

    public updateGatewayDataStoragePreference_args() {
    }

    public updateGatewayDataStoragePreference_args(
      org.apache.airavata.model.security.AuthzToken authzToken,
      String gatewayID,
      String dataMoveId,
      org.apache.airavata.model.appcatalog.gatewayprofile.DataStoragePreference dataStoragePreference)
    {
      this();
      this.authzToken = authzToken;
      this.gatewayID = gatewayID;
      this.dataMoveId = dataMoveId;
      this.dataStoragePreference = dataStoragePreference;
    }

    /**
     * Performs a deep copy on <i>other</i>.
     */
    public updateGatewayDataStoragePreference_args(updateGatewayDataStoragePreference_args other) {
      if (other.isSetAuthzToken()) {
        this.authzToken = new org.apache.airavata.model.security.AuthzToken(other.authzToken);
      }
      if (other.isSetGatewayID()) {
        this.gatewayID = other.gatewayID;
      }
      if (other.isSetDataMoveId()) {
        this.dataMoveId = other.dataMoveId;
      }
      if (other.isSetDataStoragePreference()) {
        this.dataStoragePreference = new org.apache.airavata.model.appcatalog.gatewayprofile.DataStoragePreference(other.dataStoragePreference);
      }
    }

    public updateGatewayDataStoragePreference_args deepCopy() {
      return new updateGatewayDataStoragePreference_args(this);
    }

    @Override
    public void clear() {
      this.authzToken = null;
      this.gatewayID = null;
      this.dataMoveId = null;
      this.dataStoragePreference = null;
    }

    public org.apache.airavata.model.security.AuthzToken getAuthzToken() {
      return this.authzToken;
    }

    public updateGatewayDataStoragePreference_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 String getGatewayID() {
      return this.gatewayID;
    }

    public updateGatewayDataStoragePreference_args setGatewayID(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 String getDataMoveId() {
      return this.dataMoveId;
    }

    public updateGatewayDataStoragePreference_args setDataMoveId(String dataMoveId) {
      this.dataMoveId = dataMoveId;
      return this;
    }

    public void unsetDataMoveId() {
      this.dataMoveId = null;
    }

    /** Returns true if field dataMoveId is set (has been assigned a value) and false otherwise */
    public boolean isSetDataMoveId() {
      return this.dataMoveId != null;
    }

    public void setDataMoveIdIsSet(boolean value) {
      if (!value) {
        this.dataMoveId = null;
      }
    }

    public org.apache.airavata.model.appcatalog.gatewayprofile.DataStoragePreference getDataStoragePreference() {
      return this.dataStoragePreference;
    }

    public updateGatewayDataStoragePreference_args setDataStoragePreference(org.apache.airavata.model.appcatalog.gatewayprofile.DataStoragePreference dataStoragePreference) {
      this.dataStoragePreference = dataStoragePreference;
      return this;
    }

    public void unsetDataStoragePreference() {
      this.dataStoragePreference = null;
    }

    /** Returns true if field dataStoragePreference is set (has been assigned a value) and false otherwise */
    public boolean isSetDataStoragePreference() {
      return this.dataStoragePreference != null;
    }

    public void setDataStoragePreferenceIsSet(boolean value) {
      if (!value) {
        this.dataStoragePreference = null;
      }
    }

    public void setFieldValue(_Fields field, 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((String)value);
        }
        break;

      case DATA_MOVE_ID:
        if (value == null) {
          unsetDataMoveId();
        } else {
          setDataMoveId((String)value);
        }
        break;

      case DATA_STORAGE_PREFERENCE:
        if (value == null) {
          unsetDataStoragePreference();
        } else {
          setDataStoragePreference((org.apache.airavata.model.appcatalog.gatewayprofile.DataStoragePreference)value);
        }
        break;

      }
    }

    public Object getFieldValue(_Fields field) {
      switch (field) {
      case AUTHZ_TOKEN:
        return getAuthzToken();

      case GATEWAY_ID:
        return getGatewayID();

      case DATA_MOVE_ID:
        return getDataMoveId();

      case DATA_STORAGE_PREFERENCE:
        return getDataStoragePreference();

      }
      throw new IllegalStateException();
    }

    /** Returns true if field corresponding to fieldID is set (has been assigned a value) and false otherwise */
    public boolean isSet(_Fields field) {
      if (field == null) {
        throw new IllegalArgumentException();
      }

      switch (field) {
      case AUTHZ_TOKEN:
        return isSetAuthzToken();
      case GATEWAY_ID:
        return isSetGatewayID();
      case DATA_MOVE_ID:
        return isSetDataMoveId();
      case DATA_STORAGE_PREFERENCE:
        return isSetDataStoragePreference();
      }
      throw new IllegalStateException();
    }

    @Override
    public boolean equals(Object that) {
      if (that == null)
        return false;
      if (that instanceof updateGatewayDataStoragePreference_args)
        return this.equals((updateGatewayDataStoragePreference_args)that);
      return false;
    }

    public boolean equals(updateGatewayDataStoragePreference_args that) {
      if (that == null)
        return false;

      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;
      }

      boolean this_present_dataMoveId = true && this.isSetDataMoveId();
      boolean that_present_dataMoveId = true && that.isSetDataMoveId();
      if (this_present_dataMoveId || that_present_dataMoveId) {
        if (!(this_present_dataMoveId && that_present_dataMoveId))
          return false;
        if (!this.dataMoveId.equals(that.dataMoveId))
          return false;
      }

      boolean this_present_dataStoragePreference = true && this.isSetDataStoragePreference();
      boolean that_present_dataStoragePreference = true && that.isSetDataStoragePreference();
      if (this_present_dataStoragePreference || that_present_dataStoragePreference) {
        if (!(this_present_dataStoragePreference && that_present_dataStoragePreference))
          return false;
        if (!this.dataStoragePreference.equals(that.dataStoragePreference))
          return false;
      }

      return true;
    }

    @Override
    public int hashCode() {
      List<Object> list = new ArrayList<Object>();

      boolean present_authzToken = true && (isSetAuthzToken());
      list.add(present_authzToken);
      if (present_authzToken)
        list.add(authzToken);

      boolean present_gatewayID = true && (isSetGatewayID());
      list.add(present_gatewayID);
      if (present_gatewayID)
        list.add(gatewayID);

      boolean present_dataMoveId = true && (isSetDataMoveId());
      list.add(present_dataMoveId);
      if (present_dataMoveId)
        list.add(dataMoveId);

      boolean present_dataStoragePreference = true && (isSetDataStoragePreference());
      list.add(present_dataStoragePreference);
      if (present_dataStoragePreference)
        list.add(dataStoragePreference);

      return list.hashCode();
    }

    @Override
    public int compareTo(updateGatewayDataStoragePreference_args other) {
      if (!getClass().equals(other.getClass())) {
        return getClass().getName().compareTo(other.getClass().getName());
      }

      int lastComparison = 0;

      lastComparison = 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 = 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;
        }
      }
      lastComparison = Boolean.valueOf(isSetDataMoveId()).compareTo(other.isSetDataMoveId());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetDataMoveId()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.dataMoveId, other.dataMoveId);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = Boolean.valueOf(isSetDataStoragePreference()).compareTo(other.isSetDataStoragePreference());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetDataStoragePreference()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.dataStoragePreference, other.dataStoragePreference);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      return 0;
    }

    public _Fields fieldForId(int fieldId) {
      return _Fields.findByThriftId(fieldId);
    }

    public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
      schemes.get(iprot.getScheme()).getScheme().read(iprot, this);
    }

    public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException {
      schemes.get(oprot.getScheme()).getScheme().write(oprot, this);
    }

    @Override
    public String toString() {
      StringBuilder sb = new StringBuilder("updateGatewayDataStoragePreference_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;
      if (!first) sb.append(", ");
      sb.append("dataMoveId:");
      if (this.dataMoveId == null) {
        sb.append("null");
      } else {
        sb.append(this.dataMoveId);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("dataStoragePreference:");
      if (this.dataStoragePreference == null) {
        sb.append("null");
      } else {
        sb.append(this.dataStoragePreference);
      }
      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());
      }
      if (dataMoveId == null) {
        throw new org.apache.thrift.protocol.TProtocolException("Required field 'dataMoveId' was not present! Struct: " + toString());
      }
      if (dataStoragePreference == null) {
        throw new org.apache.thrift.protocol.TProtocolException("Required field 'dataStoragePreference' was not present! Struct: " + toString());
      }
      // check for sub-struct validity
      if (authzToken != null) {
        authzToken.validate();
      }
      if (dataStoragePreference != null) {
        dataStoragePreference.validate();
      }
    }

    private void writeObject(java.io.ObjectOutputStream out) throws java.io.IOException {
      try {
        write(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(out)));
      } catch (org.apache.thrift.TException te) {
        throw new java.io.IOException(te);
      }
    }

    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, ClassNotFoundException {
      try {
        read(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(in)));
      } catch (org.apache.thrift.TException te) {
        throw new java.io.IOException(te);
      }
    }

    private static class updateGatewayDataStoragePreference_argsStandardSchemeFactory implements SchemeFactory {
      public updateGatewayDataStoragePreference_argsStandardScheme getScheme() {
        return new updateGatewayDataStoragePreference_argsStandardScheme();
      }
    }

    private static class updateGatewayDataStoragePreference_argsStandardScheme extends StandardScheme<updateGatewayDataStoragePreference_args> {

      public void read(org.apache.thrift.protocol.TProtocol iprot, updateGatewayDataStoragePreference_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;
            case 3: // DATA_MOVE_ID
              if (schemeField.type == org.apache.thrift.protocol.TType.STRING) {
                struct.dataMoveId = iprot.readString();
                struct.setDataMoveIdIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 4: // DATA_STORAGE_PREFERENCE
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.dataStoragePreference = new org.apache.airavata.model.appcatalog.gatewayprofile.DataStoragePreference();
                struct.dataStoragePreference.read(iprot);
                struct.setDataStoragePreferenceIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            default:
              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
          }
          iprot.readFieldEnd();
        }
        iprot.readStructEnd();

        // check for required fields of primitive type, which can't be checked in the validate method
        struct.validate();
      }

      public void write(org.apache.thrift.protocol.TProtocol oprot, updateGatewayDataStoragePreference_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();
        }
        if (struct.dataMoveId != null) {
          oprot.writeFieldBegin(DATA_MOVE_ID_FIELD_DESC);
          oprot.writeString(struct.dataMoveId);
          oprot.writeFieldEnd();
        }
        if (struct.dataStoragePreference != null) {
          oprot.writeFieldBegin(DATA_STORAGE_PREFERENCE_FIELD_DESC);
          struct.dataStoragePreference.write(oprot);
          oprot.writeFieldEnd();
        }
        oprot.writeFieldStop();
        oprot.writeStructEnd();
      }

    }

    private static class updateGatewayDataStoragePreference_argsTupleSchemeFactory implements SchemeFactory {
      public updateGatewayDataStoragePreference_argsTupleScheme getScheme() {
        return new updateGatewayDataStoragePreference_argsTupleScheme();
      }
    }

    private static class updateGatewayDataStoragePreference_argsTupleScheme extends TupleScheme<updateGatewayDataStoragePreference_args> {

      @Override
      public void write(org.apache.thrift.protocol.TProtocol prot, updateGatewayDataStoragePreference_args struct) throws org.apache.thrift.TException {
        TTupleProtocol oprot = (TTupleProtocol) prot;
        struct.authzToken.write(oprot);
        oprot.writeString(struct.gatewayID);
        oprot.writeString(struct.dataMoveId);
        struct.dataStoragePreference.write(oprot);
      }

      @Override
      public void read(org.apache.thrift.protocol.TProtocol prot, updateGatewayDataStoragePreference_args struct) throws org.apache.thrift.TException {
        TTupleProtocol iprot = (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);
        struct.dataMoveId = iprot.readString();
        struct.setDataMoveIdIsSet(true);
        struct.dataStoragePreference = new org.apache.airavata.model.appcatalog.gatewayprofile.DataStoragePreference();
        struct.dataStoragePreference.read(iprot);
        struct.setDataStoragePreferenceIsSet(true);
      }
    }

  }

  public static class updateGatewayDataStoragePreference_result implements org.apache.thrift.TBase<updateGatewayDataStoragePreference_result, updateGatewayDataStoragePreference_result._Fields>, java.io.Serializable, Cloneable, Comparable<updateGatewayDataStoragePreference_result>   {
    private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("updateGatewayDataStoragePreference_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 IRE_FIELD_DESC = new org.apache.thrift.protocol.TField("ire", org.apache.thrift.protocol.TType.STRUCT, (short)1);
    private static final org.apache.thrift.protocol.TField ACE_FIELD_DESC = new org.apache.thrift.protocol.TField("ace", org.apache.thrift.protocol.TType.STRUCT, (short)2);
    private static final org.apache.thrift.protocol.TField ASE_FIELD_DESC = new org.apache.thrift.protocol.TField("ase", org.apache.thrift.protocol.TType.STRUCT, (short)3);
    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)4);

    private static final Map<Class<? extends IScheme>, SchemeFactory> schemes = new HashMap<Class<? extends IScheme>, SchemeFactory>();
    static {
      schemes.put(StandardScheme.class, new updateGatewayDataStoragePreference_resultStandardSchemeFactory());
      schemes.put(TupleScheme.class, new updateGatewayDataStoragePreference_resultTupleSchemeFactory());
    }

    public boolean success; // required
    public org.apache.airavata.model.error.InvalidRequestException ire; // required
    public org.apache.airavata.model.error.AiravataClientException ace; // required
    public org.apache.airavata.model.error.AiravataSystemException ase; // 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"),
      IRE((short)1, "ire"),
      ACE((short)2, "ace"),
      ASE((short)3, "ase"),
      AE((short)4, "ae");

      private static final Map<String, _Fields> byName = new HashMap<String, _Fields>();

      static {
        for (_Fields field : EnumSet.allOf(_Fields.class)) {
          byName.put(field.getFieldName(), field);
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, or null if its not found.
       */
      public static _Fields findByThriftId(int fieldId) {
        switch(fieldId) {
          case 0: // SUCCESS
            return SUCCESS;
          case 1: // IRE
            return IRE;
          case 2: // ACE
            return ACE;
          case 3: // ASE
            return ASE;
          case 4: // 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 IllegalArgumentException("Field " + fieldId + " doesn't exist!");
        return fields;
      }

      /**
       * Find the _Fields constant that matches name, or null if its not found.
       */
      public static _Fields findByName(String name) {
        return byName.get(name);
      }

      private final short _thriftId;
      private final String _fieldName;

      _Fields(short thriftId, String fieldName) {
        _thriftId = thriftId;
        _fieldName = fieldName;
      }

      public short getThriftFieldId() {
        return _thriftId;
      }

      public String getFieldName() {
        return _fieldName;
      }
    }

    // isset id assignments
    private static final int __SUCCESS_ISSET_ID = 0;
    private byte __isset_bitfield = 0;
    public static final Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
    static {
      Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new EnumMap<_Fields, org.apache.thrift.meta_data.FieldMetaData>(_Fields.class);
      tmpMap.put(_Fields.SUCCESS, new org.apache.thrift.meta_data.FieldMetaData("success", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.BOOL)));
      tmpMap.put(_Fields.IRE, new org.apache.thrift.meta_data.FieldMetaData("ire", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRUCT)));
      tmpMap.put(_Fields.ACE, new org.apache.thrift.meta_data.FieldMetaData("ace", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRUCT)));
      tmpMap.put(_Fields.ASE, new org.apache.thrift.meta_data.FieldMetaData("ase", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRUCT)));
      tmpMap.put(_Fields.AE, new org.apache.thrift.meta_data.FieldMetaData("ae", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRUCT)));
      metaDataMap = Collections.unmodifiableMap(tmpMap);
      org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(updateGatewayDataStoragePreference_result.class, metaDataMap);
    }

    public updateGatewayDataStoragePreference_result() {
    }

    public updateGatewayDataStoragePreference_result(
      boolean success,
      org.apache.airavata.model.error.InvalidRequestException ire,
      org.apache.airavata.model.error.AiravataClientException ace,
      org.apache.airavata.model.error.AiravataSystemException ase,
      org.apache.airavata.model.error.AuthorizationException ae)
    {
      this();
      this.success = success;
      setSuccessIsSet(true);
      this.ire = ire;
      this.ace = ace;
      this.ase = ase;
      this.ae = ae;
    }

    /**
     * Performs a deep copy on <i>other</i>.
     */
    public updateGatewayDataStoragePreference_result(updateGatewayDataStoragePreference_result other) {
      __isset_bitfield = other.__isset_bitfield;
      this.success = other.success;
      if (other.isSetIre()) {
        this.ire = new org.apache.airavata.model.error.InvalidRequestException(other.ire);
      }
      if (other.isSetAce()) {
        this.ace = new org.apache.airavata.model.error.AiravataClientException(other.ace);
      }
      if (other.isSetAse()) {
        this.ase = new org.apache.airavata.model.error.AiravataSystemException(other.ase);
      }
      if (other.isSetAe()) {
        this.ae = new org.apache.airavata.model.error.AuthorizationException(other.ae);
      }
    }

    public updateGatewayDataStoragePreference_result deepCopy() {
      return new updateGatewayDataStoragePreference_result(this);
    }

    @Override
    public void clear() {
      setSuccessIsSet(false);
      this.success = false;
      this.ire = null;
      this.ace = null;
      this.ase = null;
      this.ae = null;
    }

    public boolean isSuccess() {
      return this.success;
    }

    public updateGatewayDataStoragePreference_result setSuccess(boolean success) {
      this.success = success;
      setSuccessIsSet(true);
      return this;
    }

    public void unsetSuccess() {
      __isset_bitfield = EncodingUtils.clearBit(__isset_bitfield, __SUCCESS_ISSET_ID);
    }

    /** Returns true if field success is set (has been assigned a value) and false otherwise */
    public boolean isSetSuccess() {
      return EncodingUtils.testBit(__isset_bitfield, __SUCCESS_ISSET_ID);
    }

    public void setSuccessIsSet(boolean value) {
      __isset_bitfield = EncodingUtils.setBit(__isset_bitfield, __SUCCESS_ISSET_ID, value);
    }

    public org.apache.airavata.model.error.InvalidRequestException getIre() {
      return this.ire;
    }

    public updateGatewayDataStoragePreference_result setIre(org.apache.airavata.model.error.InvalidRequestException ire) {
      this.ire = ire;
      return this;
    }

    public void unsetIre() {
      this.ire = null;
    }

    /** Returns true if field ire is set (has been assigned a value) and false otherwise */
    public boolean isSetIre() {
      return this.ire != null;
    }

    public void setIreIsSet(boolean value) {
      if (!value) {
        this.ire = null;
      }
    }

    public org.apache.airavata.model.error.AiravataClientException getAce() {
      return this.ace;
    }

    public updateGatewayDataStoragePreference_result setAce(org.apache.airavata.model.error.AiravataClientException ace) {
      this.ace = ace;
      return this;
    }

    public void unsetAce() {
      this.ace = null;
    }

    /** Returns true if field ace is set (has been assigned a value) and false otherwise */
    public boolean isSetAce() {
      return this.ace != null;
    }

    public void setAceIsSet(boolean value) {
      if (!value) {
        this.ace = null;
      }
    }

    public org.apache.airavata.model.error.AiravataSystemException getAse() {
      return this.ase;
    }

    public updateGatewayDataStoragePreference_result setAse(org.apache.airavata.model.error.AiravataSystemException ase) {
      this.ase = ase;
      return this;
    }

    public void unsetAse() {
      this.ase = null;
    }

    /** Returns true if field ase is set (has been assigned a value) and false otherwise */
    public boolean isSetAse() {
      return this.ase != null;
    }

    public void setAseIsSet(boolean value) {
      if (!value) {
        this.ase = null;
      }
    }

    public org.apache.airavata.model.error.AuthorizationException getAe() {
      return this.ae;
    }

    public updateGatewayDataStoragePreference_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, Object value) {
      switch (field) {
      case SUCCESS:
        if (value == null) {
          unsetSuccess();
        } else {
          setSuccess((Boolean)value);
        }
        break;

      case IRE:
        if (value == null) {
          unsetIre();
        } else {
          setIre((org.apache.airavata.model.error.InvalidRequestException)value);
        }
        break;

      case ACE:
        if (value == null) {
          unsetAce();
        } else {
          setAce((org.apache.airavata.model.error.AiravataClientException)value);
        }
        break;

      case ASE:
        if (value == null) {
          unsetAse();
        } else {
          setAse((org.apache.airavata.model.error.AiravataSystemException)value);
        }
        break;

      case AE:
        if (value == null) {
          unsetAe();
        } else {
          setAe((org.apache.airavata.model.error.AuthorizationException)value);
        }
        break;

      }
    }

    public Object getFieldValue(_Fields field) {
      switch (field) {
      case SUCCESS:
        return Boolean.valueOf(isSuccess());

      case IRE:
        return getIre();

      case ACE:
        return getAce();

      case ASE:
        return getAse();

      case AE:
        return getAe();

      }
      throw new IllegalStateException();
    }

    /** Returns true if field corresponding to fieldID is set (has been assigned a value) and false otherwise */
    public boolean isSet(_Fields field) {
      if (field == null) {
        throw new IllegalArgumentException();
      }

      switch (field) {
      case SUCCESS:
        return isSetSuccess();
      case IRE:
        return isSetIre();
      case ACE:
        return isSetAce();
      case ASE:
        return isSetAse();
      case AE:
        return isSetAe();
      }
      throw new IllegalStateException();
    }

    @Override
    public boolean equals(Object that) {
      if (that == null)
        return false;
      if (that instanceof updateGatewayDataStoragePreference_result)
        return this.equals((updateGatewayDataStoragePreference_result)that);
      return false;
    }

    public boolean equals(updateGatewayDataStoragePreference_result that) {
      if (that == null)
        return false;

      boolean this_present_success = true;
      boolean that_present_success = true;
      if (this_present_success || that_present_success) {
        if (!(this_present_success && that_present_success))
          return false;
        if (this.success != that.success)
          return false;
      }

      boolean this_present_ire = true && this.isSetIre();
      boolean that_present_ire = true && that.isSetIre();
      if (this_present_ire || that_present_ire) {
        if (!(this_present_ire && that_present_ire))
          return false;
        if (!this.ire.equals(that.ire))
          return false;
      }

      boolean this_present_ace = true && this.isSetAce();
      boolean that_present_ace = true && that.isSetAce();
      if (this_present_ace || that_present_ace) {
        if (!(this_present_ace && that_present_ace))
          return false;
        if (!this.ace.equals(that.ace))
          return false;
      }

      boolean this_present_ase = true && this.isSetAse();
      boolean that_present_ase = true && that.isSetAse();
      if (this_present_ase || that_present_ase) {
        if (!(this_present_ase && that_present_ase))
          return false;
        if (!this.ase.equals(that.ase))
          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() {
      List<Object> list = new ArrayList<Object>();

      boolean present_success = true;
      list.add(present_success);
      if (present_success)
        list.add(success);

      boolean present_ire = true && (isSetIre());
      list.add(present_ire);
      if (present_ire)
        list.add(ire);

      boolean present_ace = true && (isSetAce());
      list.add(present_ace);
      if (present_ace)
        list.add(ace);

      boolean present_ase = true && (isSetAse());
      list.add(present_ase);
      if (present_ase)
        list.add(ase);

      boolean present_ae = true && (isSetAe());
      list.add(present_ae);
      if (present_ae)
        list.add(ae);

      return list.hashCode();
    }

    @Override
    public int compareTo(updateGatewayDataStoragePreference_result other) {
      if (!getClass().equals(other.getClass())) {
        return getClass().getName().compareTo(other.getClass().getName());
      }

      int lastComparison = 0;

      lastComparison = Boolean.valueOf(isSetSuccess()).compareTo(other.isSetSuccess());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetSuccess()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.success, other.success);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = Boolean.valueOf(isSetIre()).compareTo(other.isSetIre());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetIre()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.ire, other.ire);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = Boolean.valueOf(isSetAce()).compareTo(other.isSetAce());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetAce()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.ace, other.ace);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = Boolean.valueOf(isSetAse()).compareTo(other.isSetAse());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetAse()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.ase, other.ase);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = 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 {
      schemes.get(iprot.getScheme()).getScheme().read(iprot, this);
    }

    public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException {
      schemes.get(oprot.getScheme()).getScheme().write(oprot, this);
      }

    @Override
    public String toString() {
      StringBuilder sb = new StringBuilder("updateGatewayDataStoragePreference_result(");
      boolean first = true;

      sb.append("success:");
      sb.append(this.success);
      first = false;
      if (!first) sb.append(", ");
      sb.append("ire:");
      if (this.ire == null) {
        sb.append("null");
      } else {
        sb.append(this.ire);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("ace:");
      if (this.ace == null) {
        sb.append("null");
      } else {
        sb.append(this.ace);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("ase:");
      if (this.ase == null) {
        sb.append("null");
      } else {
        sb.append(this.ase);
      }
      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, 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 updateGatewayDataStoragePreference_resultStandardSchemeFactory implements SchemeFactory {
      public updateGatewayDataStoragePreference_resultStandardScheme getScheme() {
        return new updateGatewayDataStoragePreference_resultStandardScheme();
      }
    }

    private static class updateGatewayDataStoragePreference_resultStandardScheme extends StandardScheme<updateGatewayDataStoragePreference_result> {

      public void read(org.apache.thrift.protocol.TProtocol iprot, updateGatewayDataStoragePreference_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: // IRE
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.ire = new org.apache.airavata.model.error.InvalidRequestException();
                struct.ire.read(iprot);
                struct.setIreIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 2: // ACE
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.ace = new org.apache.airavata.model.error.AiravataClientException();
                struct.ace.read(iprot);
                struct.setAceIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 3: // ASE
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.ase = new org.apache.airavata.model.error.AiravataSystemException();
                struct.ase.read(iprot);
                struct.setAseIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 4: // 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, updateGatewayDataStoragePreference_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.ire != null) {
          oprot.writeFieldBegin(IRE_FIELD_DESC);
          struct.ire.write(oprot);
          oprot.writeFieldEnd();
        }
        if (struct.ace != null) {
          oprot.writeFieldBegin(ACE_FIELD_DESC);
          struct.ace.write(oprot);
          oprot.writeFieldEnd();
        }
        if (struct.ase != null) {
          oprot.writeFieldBegin(ASE_FIELD_DESC);
          struct.ase.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 updateGatewayDataStoragePreference_resultTupleSchemeFactory implements SchemeFactory {
      public updateGatewayDataStoragePreference_resultTupleScheme getScheme() {
        return new updateGatewayDataStoragePreference_resultTupleScheme();
      }
    }

    private static class updateGatewayDataStoragePreference_resultTupleScheme extends TupleScheme<updateGatewayDataStoragePreference_result> {

      @Override
      public void write(org.apache.thrift.protocol.TProtocol prot, updateGatewayDataStoragePreference_result struct) throws org.apache.thrift.TException {
        TTupleProtocol oprot = (TTupleProtocol) prot;
        BitSet optionals = new BitSet();
        if (struct.isSetSuccess()) {
          optionals.set(0);
        }
        if (struct.isSetIre()) {
          optionals.set(1);
        }
        if (struct.isSetAce()) {
          optionals.set(2);
        }
        if (struct.isSetAse()) {
          optionals.set(3);
        }
        if (struct.isSetAe()) {
          optionals.set(4);
        }
        oprot.writeBitSet(optionals, 5);
        if (struct.isSetSuccess()) {
          oprot.writeBool(struct.success);
        }
        if (struct.isSetIre()) {
          struct.ire.write(oprot);
        }
        if (struct.isSetAce()) {
          struct.ace.write(oprot);
        }
        if (struct.isSetAse()) {
          struct.ase.write(oprot);
        }
        if (struct.isSetAe()) {
          struct.ae.write(oprot);
        }
      }

      @Override
      public void read(org.apache.thrift.protocol.TProtocol prot, updateGatewayDataStoragePreference_result struct) throws org.apache.thrift.TException {
        TTupleProtocol iprot = (TTupleProtocol) prot;
        BitSet incoming = iprot.readBitSet(5);
        if (incoming.get(0)) {
          struct.success = iprot.readBool();
          struct.setSuccessIsSet(true);
        }
        if (incoming.get(1)) {
          struct.ire = new org.apache.airavata.model.error.InvalidRequestException();
          struct.ire.read(iprot);
          struct.setIreIsSet(true);
        }
        if (incoming.get(2)) {
          struct.ace = new org.apache.airavata.model.error.AiravataClientException();
          struct.ace.read(iprot);
          struct.setAceIsSet(true);
        }
        if (incoming.get(3)) {
          struct.ase = new org.apache.airavata.model.error.AiravataSystemException();
          struct.ase.read(iprot);
          struct.setAseIsSet(true);
        }
        if (incoming.get(4)) {
          struct.ae = new org.apache.airavata.model.error.AuthorizationException();
          struct.ae.read(iprot);
          struct.setAeIsSet(true);
        }
      }
    }

  }

  public static class deleteGatewayComputeResourcePreference_args implements org.apache.thrift.TBase<deleteGatewayComputeResourcePreference_args, deleteGatewayComputeResourcePreference_args._Fields>, java.io.Serializable, Cloneable, Comparable<deleteGatewayComputeResourcePreference_args>   {
    private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("deleteGatewayComputeResourcePreference_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.protocol.TField COMPUTE_RESOURCE_ID_FIELD_DESC = new org.apache.thrift.protocol.TField("computeResourceId", org.apache.thrift.protocol.TType.STRING, (short)3);

    private static final Map<Class<? extends IScheme>, SchemeFactory> schemes = new HashMap<Class<? extends IScheme>, SchemeFactory>();
    static {
      schemes.put(StandardScheme.class, new deleteGatewayComputeResourcePreference_argsStandardSchemeFactory());
      schemes.put(TupleScheme.class, new deleteGatewayComputeResourcePreference_argsTupleSchemeFactory());
    }

    public org.apache.airavata.model.security.AuthzToken authzToken; // required
    public String gatewayID; // required
    public String computeResourceId; // required

    /** 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"),
      COMPUTE_RESOURCE_ID((short)3, "computeResourceId");

      private static final Map<String, _Fields> byName = new HashMap<String, _Fields>();

      static {
        for (_Fields field : EnumSet.allOf(_Fields.class)) {
          byName.put(field.getFieldName(), field);
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, or null if its not found.
       */
      public static _Fields findByThriftId(int fieldId) {
        switch(fieldId) {
          case 1: // AUTHZ_TOKEN
            return AUTHZ_TOKEN;
          case 2: // GATEWAY_ID
            return GATEWAY_ID;
          case 3: // COMPUTE_RESOURCE_ID
            return COMPUTE_RESOURCE_ID;
          default:
            return null;
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, throwing an exception
       * if it is not found.
       */
      public static _Fields findByThriftIdOrThrow(int fieldId) {
        _Fields fields = findByThriftId(fieldId);
        if (fields == null) throw new IllegalArgumentException("Field " + fieldId + " doesn't exist!");
        return fields;
      }

      /**
       * Find the _Fields constant that matches name, or null if its not found.
       */
      public static _Fields findByName(String name) {
        return byName.get(name);
      }

      private final short _thriftId;
      private final String _fieldName;

      _Fields(short thriftId, String fieldName) {
        _thriftId = thriftId;
        _fieldName = fieldName;
      }

      public short getThriftFieldId() {
        return _thriftId;
      }

      public String getFieldName() {
        return _fieldName;
      }
    }

    // isset id assignments
    public static final Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
    static {
      Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new EnumMap<_Fields, org.apache.thrift.meta_data.FieldMetaData>(_Fields.class);
      tmpMap.put(_Fields.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)));
      tmpMap.put(_Fields.COMPUTE_RESOURCE_ID, new org.apache.thrift.meta_data.FieldMetaData("computeResourceId", org.apache.thrift.TFieldRequirementType.REQUIRED, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING)));
      metaDataMap = Collections.unmodifiableMap(tmpMap);
      org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(deleteGatewayComputeResourcePreference_args.class, metaDataMap);
    }

    public deleteGatewayComputeResourcePreference_args() {
    }

    public deleteGatewayComputeResourcePreference_args(
      org.apache.airavata.model.security.AuthzToken authzToken,
      String gatewayID,
      String computeResourceId)
    {
      this();
      this.authzToken = authzToken;
      this.gatewayID = gatewayID;
      this.computeResourceId = computeResourceId;
    }

    /**
     * Performs a deep copy on <i>other</i>.
     */
    public deleteGatewayComputeResourcePreference_args(deleteGatewayComputeResourcePreference_args other) {
      if (other.isSetAuthzToken()) {
        this.authzToken = new org.apache.airavata.model.security.AuthzToken(other.authzToken);
      }
      if (other.isSetGatewayID()) {
        this.gatewayID = other.gatewayID;
      }
      if (other.isSetComputeResourceId()) {
        this.computeResourceId = other.computeResourceId;
      }
    }

    public deleteGatewayComputeResourcePreference_args deepCopy() {
      return new deleteGatewayComputeResourcePreference_args(this);
    }

    @Override
    public void clear() {
      this.authzToken = null;
      this.gatewayID = null;
      this.computeResourceId = null;
    }

    public org.apache.airavata.model.security.AuthzToken getAuthzToken() {
      return this.authzToken;
    }

    public deleteGatewayComputeResourcePreference_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 String getGatewayID() {
      return this.gatewayID;
    }

    public deleteGatewayComputeResourcePreference_args setGatewayID(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 String getComputeResourceId() {
      return this.computeResourceId;
    }

    public deleteGatewayComputeResourcePreference_args setComputeResourceId(String computeResourceId) {
      this.computeResourceId = computeResourceId;
      return this;
    }

    public void unsetComputeResourceId() {
      this.computeResourceId = null;
    }

    /** Returns true if field computeResourceId is set (has been assigned a value) and false otherwise */
    public boolean isSetComputeResourceId() {
      return this.computeResourceId != null;
    }

    public void setComputeResourceIdIsSet(boolean value) {
      if (!value) {
        this.computeResourceId = null;
      }
    }

    public void setFieldValue(_Fields field, 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((String)value);
        }
        break;

      case COMPUTE_RESOURCE_ID:
        if (value == null) {
          unsetComputeResourceId();
        } else {
          setComputeResourceId((String)value);
        }
        break;

      }
    }

    public Object getFieldValue(_Fields field) {
      switch (field) {
      case AUTHZ_TOKEN:
        return getAuthzToken();

      case GATEWAY_ID:
        return getGatewayID();

      case COMPUTE_RESOURCE_ID:
        return getComputeResourceId();

      }
      throw new IllegalStateException();
    }

    /** Returns true if field corresponding to fieldID is set (has been assigned a value) and false otherwise */
    public boolean isSet(_Fields field) {
      if (field == null) {
        throw new IllegalArgumentException();
      }

      switch (field) {
      case AUTHZ_TOKEN:
        return isSetAuthzToken();
      case GATEWAY_ID:
        return isSetGatewayID();
      case COMPUTE_RESOURCE_ID:
        return isSetComputeResourceId();
      }
      throw new IllegalStateException();
    }

    @Override
    public boolean equals(Object that) {
      if (that == null)
        return false;
      if (that instanceof deleteGatewayComputeResourcePreference_args)
        return this.equals((deleteGatewayComputeResourcePreference_args)that);
      return false;
    }

    public boolean equals(deleteGatewayComputeResourcePreference_args that) {
      if (that == null)
        return false;

      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;
      }

      boolean this_present_computeResourceId = true && this.isSetComputeResourceId();
      boolean that_present_computeResourceId = true && that.isSetComputeResourceId();
      if (this_present_computeResourceId || that_present_computeResourceId) {
        if (!(this_present_computeResourceId && that_present_computeResourceId))
          return false;
        if (!this.computeResourceId.equals(that.computeResourceId))
          return false;
      }

      return true;
    }

    @Override
    public int hashCode() {
      List<Object> list = new ArrayList<Object>();

      boolean present_authzToken = true && (isSetAuthzToken());
      list.add(present_authzToken);
      if (present_authzToken)
        list.add(authzToken);

      boolean present_gatewayID = true && (isSetGatewayID());
      list.add(present_gatewayID);
      if (present_gatewayID)
        list.add(gatewayID);

      boolean present_computeResourceId = true && (isSetComputeResourceId());
      list.add(present_computeResourceId);
      if (present_computeResourceId)
        list.add(computeResourceId);

      return list.hashCode();
    }

    @Override
    public int compareTo(deleteGatewayComputeResourcePreference_args other) {
      if (!getClass().equals(other.getClass())) {
        return getClass().getName().compareTo(other.getClass().getName());
      }

      int lastComparison = 0;

      lastComparison = 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 = 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;
        }
      }
      lastComparison = Boolean.valueOf(isSetComputeResourceId()).compareTo(other.isSetComputeResourceId());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetComputeResourceId()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.computeResourceId, other.computeResourceId);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      return 0;
    }

    public _Fields fieldForId(int fieldId) {
      return _Fields.findByThriftId(fieldId);
    }

    public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
      schemes.get(iprot.getScheme()).getScheme().read(iprot, this);
    }

    public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException {
      schemes.get(oprot.getScheme()).getScheme().write(oprot, this);
    }

    @Override
    public String toString() {
      StringBuilder sb = new StringBuilder("deleteGatewayComputeResourcePreference_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;
      if (!first) sb.append(", ");
      sb.append("computeResourceId:");
      if (this.computeResourceId == null) {
        sb.append("null");
      } else {
        sb.append(this.computeResourceId);
      }
      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());
      }
      if (computeResourceId == null) {
        throw new org.apache.thrift.protocol.TProtocolException("Required field 'computeResourceId' 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, 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 deleteGatewayComputeResourcePreference_argsStandardSchemeFactory implements SchemeFactory {
      public deleteGatewayComputeResourcePreference_argsStandardScheme getScheme() {
        return new deleteGatewayComputeResourcePreference_argsStandardScheme();
      }
    }

    private static class deleteGatewayComputeResourcePreference_argsStandardScheme extends StandardScheme<deleteGatewayComputeResourcePreference_args> {

      public void read(org.apache.thrift.protocol.TProtocol iprot, deleteGatewayComputeResourcePreference_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;
            case 3: // COMPUTE_RESOURCE_ID
              if (schemeField.type == org.apache.thrift.protocol.TType.STRING) {
                struct.computeResourceId = iprot.readString();
                struct.setComputeResourceIdIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            default:
              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
          }
          iprot.readFieldEnd();
        }
        iprot.readStructEnd();

        // check for required fields of primitive type, which can't be checked in the validate method
        struct.validate();
      }

      public void write(org.apache.thrift.protocol.TProtocol oprot, deleteGatewayComputeResourcePreference_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();
        }
        if (struct.computeResourceId != null) {
          oprot.writeFieldBegin(COMPUTE_RESOURCE_ID_FIELD_DESC);
          oprot.writeString(struct.computeResourceId);
          oprot.writeFieldEnd();
        }
        oprot.writeFieldStop();
        oprot.writeStructEnd();
      }

    }

    private static class deleteGatewayComputeResourcePreference_argsTupleSchemeFactory implements SchemeFactory {
      public deleteGatewayComputeResourcePreference_argsTupleScheme getScheme() {
        return new deleteGatewayComputeResourcePreference_argsTupleScheme();
      }
    }

    private static class deleteGatewayComputeResourcePreference_argsTupleScheme extends TupleScheme<deleteGatewayComputeResourcePreference_args> {

      @Override
      public void write(org.apache.thrift.protocol.TProtocol prot, deleteGatewayComputeResourcePreference_args struct) throws org.apache.thrift.TException {
        TTupleProtocol oprot = (TTupleProtocol) prot;
        struct.authzToken.write(oprot);
        oprot.writeString(struct.gatewayID);
        oprot.writeString(struct.computeResourceId);
      }

      @Override
      public void read(org.apache.thrift.protocol.TProtocol prot, deleteGatewayComputeResourcePreference_args struct) throws org.apache.thrift.TException {
        TTupleProtocol iprot = (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);
        struct.computeResourceId = iprot.readString();
        struct.setComputeResourceIdIsSet(true);
      }
    }

  }

  public static class deleteGatewayComputeResourcePreference_result implements org.apache.thrift.TBase<deleteGatewayComputeResourcePreference_result, deleteGatewayComputeResourcePreference_result._Fields>, java.io.Serializable, Cloneable, Comparable<deleteGatewayComputeResourcePreference_result>   {
    private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("deleteGatewayComputeResourcePreference_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 IRE_FIELD_DESC = new org.apache.thrift.protocol.TField("ire", org.apache.thrift.protocol.TType.STRUCT, (short)1);
    private static final org.apache.thrift.protocol.TField ACE_FIELD_DESC = new org.apache.thrift.protocol.TField("ace", org.apache.thrift.protocol.TType.STRUCT, (short)2);
    private static final org.apache.thrift.protocol.TField ASE_FIELD_DESC = new org.apache.thrift.protocol.TField("ase", org.apache.thrift.protocol.TType.STRUCT, (short)3);
    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)4);

    private static final Map<Class<? extends IScheme>, SchemeFactory> schemes = new HashMap<Class<? extends IScheme>, SchemeFactory>();
    static {
      schemes.put(StandardScheme.class, new deleteGatewayComputeResourcePreference_resultStandardSchemeFactory());
      schemes.put(TupleScheme.class, new deleteGatewayComputeResourcePreference_resultTupleSchemeFactory());
    }

    public boolean success; // required
    public org.apache.airavata.model.error.InvalidRequestException ire; // required
    public org.apache.airavata.model.error.AiravataClientException ace; // required
    public org.apache.airavata.model.error.AiravataSystemException ase; // 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"),
      IRE((short)1, "ire"),
      ACE((short)2, "ace"),
      ASE((short)3, "ase"),
      AE((short)4, "ae");

      private static final Map<String, _Fields> byName = new HashMap<String, _Fields>();

      static {
        for (_Fields field : EnumSet.allOf(_Fields.class)) {
          byName.put(field.getFieldName(), field);
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, or null if its not found.
       */
      public static _Fields findByThriftId(int fieldId) {
        switch(fieldId) {
          case 0: // SUCCESS
            return SUCCESS;
          case 1: // IRE
            return IRE;
          case 2: // ACE
            return ACE;
          case 3: // ASE
            return ASE;
          case 4: // 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 IllegalArgumentException("Field " + fieldId + " doesn't exist!");
        return fields;
      }

      /**
       * Find the _Fields constant that matches name, or null if its not found.
       */
      public static _Fields findByName(String name) {
        return byName.get(name);
      }

      private final short _thriftId;
      private final String _fieldName;

      _Fields(short thriftId, String fieldName) {
        _thriftId = thriftId;
        _fieldName = fieldName;
      }

      public short getThriftFieldId() {
        return _thriftId;
      }

      public String getFieldName() {
        return _fieldName;
      }
    }

    // isset id assignments
    private static final int __SUCCESS_ISSET_ID = 0;
    private byte __isset_bitfield = 0;
    public static final Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
    static {
      Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new EnumMap<_Fields, org.apache.thrift.meta_data.FieldMetaData>(_Fields.class);
      tmpMap.put(_Fields.SUCCESS, new org.apache.thrift.meta_data.FieldMetaData("success", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.BOOL)));
      tmpMap.put(_Fields.IRE, new org.apache.thrift.meta_data.FieldMetaData("ire", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRUCT)));
      tmpMap.put(_Fields.ACE, new org.apache.thrift.meta_data.FieldMetaData("ace", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRUCT)));
      tmpMap.put(_Fields.ASE, new org.apache.thrift.meta_data.FieldMetaData("ase", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRUCT)));
      tmpMap.put(_Fields.AE, new org.apache.thrift.meta_data.FieldMetaData("ae", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRUCT)));
      metaDataMap = Collections.unmodifiableMap(tmpMap);
      org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(deleteGatewayComputeResourcePreference_result.class, metaDataMap);
    }

    public deleteGatewayComputeResourcePreference_result() {
    }

    public deleteGatewayComputeResourcePreference_result(
      boolean success,
      org.apache.airavata.model.error.InvalidRequestException ire,
      org.apache.airavata.model.error.AiravataClientException ace,
      org.apache.airavata.model.error.AiravataSystemException ase,
      org.apache.airavata.model.error.AuthorizationException ae)
    {
      this();
      this.success = success;
      setSuccessIsSet(true);
      this.ire = ire;
      this.ace = ace;
      this.ase = ase;
      this.ae = ae;
    }

    /**
     * Performs a deep copy on <i>other</i>.
     */
    public deleteGatewayComputeResourcePreference_result(deleteGatewayComputeResourcePreference_result other) {
      __isset_bitfield = other.__isset_bitfield;
      this.success = other.success;
      if (other.isSetIre()) {
        this.ire = new org.apache.airavata.model.error.InvalidRequestException(other.ire);
      }
      if (other.isSetAce()) {
        this.ace = new org.apache.airavata.model.error.AiravataClientException(other.ace);
      }
      if (other.isSetAse()) {
        this.ase = new org.apache.airavata.model.error.AiravataSystemException(other.ase);
      }
      if (other.isSetAe()) {
        this.ae = new org.apache.airavata.model.error.AuthorizationException(other.ae);
      }
    }

    public deleteGatewayComputeResourcePreference_result deepCopy() {
      return new deleteGatewayComputeResourcePreference_result(this);
    }

    @Override
    public void clear() {
      setSuccessIsSet(false);
      this.success = false;
      this.ire = null;
      this.ace = null;
      this.ase = null;
      this.ae = null;
    }

    public boolean isSuccess() {
      return this.success;
    }

    public deleteGatewayComputeResourcePreference_result setSuccess(boolean success) {
      this.success = success;
      setSuccessIsSet(true);
      return this;
    }

    public void unsetSuccess() {
      __isset_bitfield = EncodingUtils.clearBit(__isset_bitfield, __SUCCESS_ISSET_ID);
    }

    /** Returns true if field success is set (has been assigned a value) and false otherwise */
    public boolean isSetSuccess() {
      return EncodingUtils.testBit(__isset_bitfield, __SUCCESS_ISSET_ID);
    }

    public void setSuccessIsSet(boolean value) {
      __isset_bitfield = EncodingUtils.setBit(__isset_bitfield, __SUCCESS_ISSET_ID, value);
    }

    public org.apache.airavata.model.error.InvalidRequestException getIre() {
      return this.ire;
    }

    public deleteGatewayComputeResourcePreference_result setIre(org.apache.airavata.model.error.InvalidRequestException ire) {
      this.ire = ire;
      return this;
    }

    public void unsetIre() {
      this.ire = null;
    }

    /** Returns true if field ire is set (has been assigned a value) and false otherwise */
    public boolean isSetIre() {
      return this.ire != null;
    }

    public void setIreIsSet(boolean value) {
      if (!value) {
        this.ire = null;
      }
    }

    public org.apache.airavata.model.error.AiravataClientException getAce() {
      return this.ace;
    }

    public deleteGatewayComputeResourcePreference_result setAce(org.apache.airavata.model.error.AiravataClientException ace) {
      this.ace = ace;
      return this;
    }

    public void unsetAce() {
      this.ace = null;
    }

    /** Returns true if field ace is set (has been assigned a value) and false otherwise */
    public boolean isSetAce() {
      return this.ace != null;
    }

    public void setAceIsSet(boolean value) {
      if (!value) {
        this.ace = null;
      }
    }

    public org.apache.airavata.model.error.AiravataSystemException getAse() {
      return this.ase;
    }

    public deleteGatewayComputeResourcePreference_result setAse(org.apache.airavata.model.error.AiravataSystemException ase) {
      this.ase = ase;
      return this;
    }

    public void unsetAse() {
      this.ase = null;
    }

    /** Returns true if field ase is set (has been assigned a value) and false otherwise */
    public boolean isSetAse() {
      return this.ase != null;
    }

    public void setAseIsSet(boolean value) {
      if (!value) {
        this.ase = null;
      }
    }

    public org.apache.airavata.model.error.AuthorizationException getAe() {
      return this.ae;
    }

    public deleteGatewayComputeResourcePreference_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, Object value) {
      switch (field) {
      case SUCCESS:
        if (value == null) {
          unsetSuccess();
        } else {
          setSuccess((Boolean)value);
        }
        break;

      case IRE:
        if (value == null) {
          unsetIre();
        } else {
          setIre((org.apache.airavata.model.error.InvalidRequestException)value);
        }
        break;

      case ACE:
        if (value == null) {
          unsetAce();
        } else {
          setAce((org.apache.airavata.model.error.AiravataClientException)value);
        }
        break;

      case ASE:
        if (value == null) {
          unsetAse();
        } else {
          setAse((org.apache.airavata.model.error.AiravataSystemException)value);
        }
        break;

      case AE:
        if (value == null) {
          unsetAe();
        } else {
          setAe((org.apache.airavata.model.error.AuthorizationException)value);
        }
        break;

      }
    }

    public Object getFieldValue(_Fields field) {
      switch (field) {
      case SUCCESS:
        return Boolean.valueOf(isSuccess());

      case IRE:
        return getIre();

      case ACE:
        return getAce();

      case ASE:
        return getAse();

      case AE:
        return getAe();

      }
      throw new IllegalStateException();
    }

    /** Returns true if field corresponding to fieldID is set (has been assigned a value) and false otherwise */
    public boolean isSet(_Fields field) {
      if (field == null) {
        throw new IllegalArgumentException();
      }

      switch (field) {
      case SUCCESS:
        return isSetSuccess();
      case IRE:
        return isSetIre();
      case ACE:
        return isSetAce();
      case ASE:
        return isSetAse();
      case AE:
        return isSetAe();
      }
      throw new IllegalStateException();
    }

    @Override
    public boolean equals(Object that) {
      if (that == null)
        return false;
      if (that instanceof deleteGatewayComputeResourcePreference_result)
        return this.equals((deleteGatewayComputeResourcePreference_result)that);
      return false;
    }

    public boolean equals(deleteGatewayComputeResourcePreference_result that) {
      if (that == null)
        return false;

      boolean this_present_success = true;
      boolean that_present_success = true;
      if (this_present_success || that_present_success) {
        if (!(this_present_success && that_present_success))
          return false;
        if (this.success != that.success)
          return false;
      }

      boolean this_present_ire = true && this.isSetIre();
      boolean that_present_ire = true && that.isSetIre();
      if (this_present_ire || that_present_ire) {
        if (!(this_present_ire && that_present_ire))
          return false;
        if (!this.ire.equals(that.ire))
          return false;
      }

      boolean this_present_ace = true && this.isSetAce();
      boolean that_present_ace = true && that.isSetAce();
      if (this_present_ace || that_present_ace) {
        if (!(this_present_ace && that_present_ace))
          return false;
        if (!this.ace.equals(that.ace))
          return false;
      }

      boolean this_present_ase = true && this.isSetAse();
      boolean that_present_ase = true && that.isSetAse();
      if (this_present_ase || that_present_ase) {
        if (!(this_present_ase && that_present_ase))
          return false;
        if (!this.ase.equals(that.ase))
          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() {
      List<Object> list = new ArrayList<Object>();

      boolean present_success = true;
      list.add(present_success);
      if (present_success)
        list.add(success);

      boolean present_ire = true && (isSetIre());
      list.add(present_ire);
      if (present_ire)
        list.add(ire);

      boolean present_ace = true && (isSetAce());
      list.add(present_ace);
      if (present_ace)
        list.add(ace);

      boolean present_ase = true && (isSetAse());
      list.add(present_ase);
      if (present_ase)
        list.add(ase);

      boolean present_ae = true && (isSetAe());
      list.add(present_ae);
      if (present_ae)
        list.add(ae);

      return list.hashCode();
    }

    @Override
    public int compareTo(deleteGatewayComputeResourcePreference_result other) {
      if (!getClass().equals(other.getClass())) {
        return getClass().getName().compareTo(other.getClass().getName());
      }

      int lastComparison = 0;

      lastComparison = Boolean.valueOf(isSetSuccess()).compareTo(other.isSetSuccess());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetSuccess()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.success, other.success);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = Boolean.valueOf(isSetIre()).compareTo(other.isSetIre());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetIre()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.ire, other.ire);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = Boolean.valueOf(isSetAce()).compareTo(other.isSetAce());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetAce()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.ace, other.ace);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = Boolean.valueOf(isSetAse()).compareTo(other.isSetAse());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetAse()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.ase, other.ase);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = 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 {
      schemes.get(iprot.getScheme()).getScheme().read(iprot, this);
    }

    public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException {
      schemes.get(oprot.getScheme()).getScheme().write(oprot, this);
      }

    @Override
    public String toString() {
      StringBuilder sb = new StringBuilder("deleteGatewayComputeResourcePreference_result(");
      boolean first = true;

      sb.append("success:");
      sb.append(this.success);
      first = false;
      if (!first) sb.append(", ");
      sb.append("ire:");
      if (this.ire == null) {
        sb.append("null");
      } else {
        sb.append(this.ire);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("ace:");
      if (this.ace == null) {
        sb.append("null");
      } else {
        sb.append(this.ace);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("ase:");
      if (this.ase == null) {
        sb.append("null");
      } else {
        sb.append(this.ase);
      }
      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, 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 deleteGatewayComputeResourcePreference_resultStandardSchemeFactory implements SchemeFactory {
      public deleteGatewayComputeResourcePreference_resultStandardScheme getScheme() {
        return new deleteGatewayComputeResourcePreference_resultStandardScheme();
      }
    }

    private static class deleteGatewayComputeResourcePreference_resultStandardScheme extends StandardScheme<deleteGatewayComputeResourcePreference_result> {

      public void read(org.apache.thrift.protocol.TProtocol iprot, deleteGatewayComputeResourcePreference_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: // IRE
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.ire = new org.apache.airavata.model.error.InvalidRequestException();
                struct.ire.read(iprot);
                struct.setIreIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 2: // ACE
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.ace = new org.apache.airavata.model.error.AiravataClientException();
                struct.ace.read(iprot);
                struct.setAceIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 3: // ASE
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.ase = new org.apache.airavata.model.error.AiravataSystemException();
                struct.ase.read(iprot);
                struct.setAseIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 4: // 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, deleteGatewayComputeResourcePreference_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.ire != null) {
          oprot.writeFieldBegin(IRE_FIELD_DESC);
          struct.ire.write(oprot);
          oprot.writeFieldEnd();
        }
        if (struct.ace != null) {
          oprot.writeFieldBegin(ACE_FIELD_DESC);
          struct.ace.write(oprot);
          oprot.writeFieldEnd();
        }
        if (struct.ase != null) {
          oprot.writeFieldBegin(ASE_FIELD_DESC);
          struct.ase.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 deleteGatewayComputeResourcePreference_resultTupleSchemeFactory implements SchemeFactory {
      public deleteGatewayComputeResourcePreference_resultTupleScheme getScheme() {
        return new deleteGatewayComputeResourcePreference_resultTupleScheme();
      }
    }

    private static class deleteGatewayComputeResourcePreference_resultTupleScheme extends TupleScheme<deleteGatewayComputeResourcePreference_result> {

      @Override
      public void write(org.apache.thrift.protocol.TProtocol prot, deleteGatewayComputeResourcePreference_result struct) throws org.apache.thrift.TException {
        TTupleProtocol oprot = (TTupleProtocol) prot;
        BitSet optionals = new BitSet();
        if (struct.isSetSuccess()) {
          optionals.set(0);
        }
        if (struct.isSetIre()) {
          optionals.set(1);
        }
        if (struct.isSetAce()) {
          optionals.set(2);
        }
        if (struct.isSetAse()) {
          optionals.set(3);
        }
        if (struct.isSetAe()) {
          optionals.set(4);
        }
        oprot.writeBitSet(optionals, 5);
        if (struct.isSetSuccess()) {
          oprot.writeBool(struct.success);
        }
        if (struct.isSetIre()) {
          struct.ire.write(oprot);
        }
        if (struct.isSetAce()) {
          struct.ace.write(oprot);
        }
        if (struct.isSetAse()) {
          struct.ase.write(oprot);
        }
        if (struct.isSetAe()) {
          struct.ae.write(oprot);
        }
      }

      @Override
      public void read(org.apache.thrift.protocol.TProtocol prot, deleteGatewayComputeResourcePreference_result struct) throws org.apache.thrift.TException {
        TTupleProtocol iprot = (TTupleProtocol) prot;
        BitSet incoming = iprot.readBitSet(5);
        if (incoming.get(0)) {
          struct.success = iprot.readBool();
          struct.setSuccessIsSet(true);
        }
        if (incoming.get(1)) {
          struct.ire = new org.apache.airavata.model.error.InvalidRequestException();
          struct.ire.read(iprot);
          struct.setIreIsSet(true);
        }
        if (incoming.get(2)) {
          struct.ace = new org.apache.airavata.model.error.AiravataClientException();
          struct.ace.read(iprot);
          struct.setAceIsSet(true);
        }
        if (incoming.get(3)) {
          struct.ase = new org.apache.airavata.model.error.AiravataSystemException();
          struct.ase.read(iprot);
          struct.setAseIsSet(true);
        }
        if (incoming.get(4)) {
          struct.ae = new org.apache.airavata.model.error.AuthorizationException();
          struct.ae.read(iprot);
          struct.setAeIsSet(true);
        }
      }
    }

  }

  public static class deleteGatewayDataStoragePreference_args implements org.apache.thrift.TBase<deleteGatewayDataStoragePreference_args, deleteGatewayDataStoragePreference_args._Fields>, java.io.Serializable, Cloneable, Comparable<deleteGatewayDataStoragePreference_args>   {
    private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("deleteGatewayDataStoragePreference_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.protocol.TField DATA_MOVE_ID_FIELD_DESC = new org.apache.thrift.protocol.TField("dataMoveId", org.apache.thrift.protocol.TType.STRING, (short)3);

    private static final Map<Class<? extends IScheme>, SchemeFactory> schemes = new HashMap<Class<? extends IScheme>, SchemeFactory>();
    static {
      schemes.put(StandardScheme.class, new deleteGatewayDataStoragePreference_argsStandardSchemeFactory());
      schemes.put(TupleScheme.class, new deleteGatewayDataStoragePreference_argsTupleSchemeFactory());
    }

    public org.apache.airavata.model.security.AuthzToken authzToken; // required
    public String gatewayID; // required
    public String dataMoveId; // required

    /** 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"),
      DATA_MOVE_ID((short)3, "dataMoveId");

      private static final Map<String, _Fields> byName = new HashMap<String, _Fields>();

      static {
        for (_Fields field : EnumSet.allOf(_Fields.class)) {
          byName.put(field.getFieldName(), field);
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, or null if its not found.
       */
      public static _Fields findByThriftId(int fieldId) {
        switch(fieldId) {
          case 1: // AUTHZ_TOKEN
            return AUTHZ_TOKEN;
          case 2: // GATEWAY_ID
            return GATEWAY_ID;
          case 3: // DATA_MOVE_ID
            return DATA_MOVE_ID;
          default:
            return null;
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, throwing an exception
       * if it is not found.
       */
      public static _Fields findByThriftIdOrThrow(int fieldId) {
        _Fields fields = findByThriftId(fieldId);
        if (fields == null) throw new IllegalArgumentException("Field " + fieldId + " doesn't exist!");
        return fields;
      }

      /**
       * Find the _Fields constant that matches name, or null if its not found.
       */
      public static _Fields findByName(String name) {
        return byName.get(name);
      }

      private final short _thriftId;
      private final String _fieldName;

      _Fields(short thriftId, String fieldName) {
        _thriftId = thriftId;
        _fieldName = fieldName;
      }

      public short getThriftFieldId() {
        return _thriftId;
      }

      public String getFieldName() {
        return _fieldName;
      }
    }

    // isset id assignments
    public static final Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
    static {
      Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new EnumMap<_Fields, org.apache.thrift.meta_data.FieldMetaData>(_Fields.class);
      tmpMap.put(_Fields.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)));
      tmpMap.put(_Fields.DATA_MOVE_ID, new org.apache.thrift.meta_data.FieldMetaData("dataMoveId", org.apache.thrift.TFieldRequirementType.REQUIRED, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING)));
      metaDataMap = Collections.unmodifiableMap(tmpMap);
      org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(deleteGatewayDataStoragePreference_args.class, metaDataMap);
    }

    public deleteGatewayDataStoragePreference_args() {
    }

    public deleteGatewayDataStoragePreference_args(
      org.apache.airavata.model.security.AuthzToken authzToken,
      String gatewayID,
      String dataMoveId)
    {
      this();
      this.authzToken = authzToken;
      this.gatewayID = gatewayID;
      this.dataMoveId = dataMoveId;
    }

    /**
     * Performs a deep copy on <i>other</i>.
     */
    public deleteGatewayDataStoragePreference_args(deleteGatewayDataStoragePreference_args other) {
      if (other.isSetAuthzToken()) {
        this.authzToken = new org.apache.airavata.model.security.AuthzToken(other.authzToken);
      }
      if (other.isSetGatewayID()) {
        this.gatewayID = other.gatewayID;
      }
      if (other.isSetDataMoveId()) {
        this.dataMoveId = other.dataMoveId;
      }
    }

    public deleteGatewayDataStoragePreference_args deepCopy() {
      return new deleteGatewayDataStoragePreference_args(this);
    }

    @Override
    public void clear() {
      this.authzToken = null;
      this.gatewayID = null;
      this.dataMoveId = null;
    }

    public org.apache.airavata.model.security.AuthzToken getAuthzToken() {
      return this.authzToken;
    }

    public deleteGatewayDataStoragePreference_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 String getGatewayID() {
      return this.gatewayID;
    }

    public deleteGatewayDataStoragePreference_args setGatewayID(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 String getDataMoveId() {
      return this.dataMoveId;
    }

    public deleteGatewayDataStoragePreference_args setDataMoveId(String dataMoveId) {
      this.dataMoveId = dataMoveId;
      return this;
    }

    public void unsetDataMoveId() {
      this.dataMoveId = null;
    }

    /** Returns true if field dataMoveId is set (has been assigned a value) and false otherwise */
    public boolean isSetDataMoveId() {
      return this.dataMoveId != null;
    }

    public void setDataMoveIdIsSet(boolean value) {
      if (!value) {
        this.dataMoveId = null;
      }
    }

    public void setFieldValue(_Fields field, 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((String)value);
        }
        break;

      case DATA_MOVE_ID:
        if (value == null) {
          unsetDataMoveId();
        } else {
          setDataMoveId((String)value);
        }
        break;

      }
    }

    public Object getFieldValue(_Fields field) {
      switch (field) {
      case AUTHZ_TOKEN:
        return getAuthzToken();

      case GATEWAY_ID:
        return getGatewayID();

      case DATA_MOVE_ID:
        return getDataMoveId();

      }
      throw new IllegalStateException();
    }

    /** Returns true if field corresponding to fieldID is set (has been assigned a value) and false otherwise */
    public boolean isSet(_Fields field) {
      if (field == null) {
        throw new IllegalArgumentException();
      }

      switch (field) {
      case AUTHZ_TOKEN:
        return isSetAuthzToken();
      case GATEWAY_ID:
        return isSetGatewayID();
      case DATA_MOVE_ID:
        return isSetDataMoveId();
      }
      throw new IllegalStateException();
    }

    @Override
    public boolean equals(Object that) {
      if (that == null)
        return false;
      if (that instanceof deleteGatewayDataStoragePreference_args)
        return this.equals((deleteGatewayDataStoragePreference_args)that);
      return false;
    }

    public boolean equals(deleteGatewayDataStoragePreference_args that) {
      if (that == null)
        return false;

      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;
      }

      boolean this_present_dataMoveId = true && this.isSetDataMoveId();
      boolean that_present_dataMoveId = true && that.isSetDataMoveId();
      if (this_present_dataMoveId || that_present_dataMoveId) {
        if (!(this_present_dataMoveId && that_present_dataMoveId))
          return false;
        if (!this.dataMoveId.equals(that.dataMoveId))
          return false;
      }

      return true;
    }

    @Override
    public int hashCode() {
      List<Object> list = new ArrayList<Object>();

      boolean present_authzToken = true && (isSetAuthzToken());
      list.add(present_authzToken);
      if (present_authzToken)
        list.add(authzToken);

      boolean present_gatewayID = true && (isSetGatewayID());
      list.add(present_gatewayID);
      if (present_gatewayID)
        list.add(gatewayID);

      boolean present_dataMoveId = true && (isSetDataMoveId());
      list.add(present_dataMoveId);
      if (present_dataMoveId)
        list.add(dataMoveId);

      return list.hashCode();
    }

    @Override
    public int compareTo(deleteGatewayDataStoragePreference_args other) {
      if (!getClass().equals(other.getClass())) {
        return getClass().getName().compareTo(other.getClass().getName());
      }

      int lastComparison = 0;

      lastComparison = 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 = 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;
        }
      }
      lastComparison = Boolean.valueOf(isSetDataMoveId()).compareTo(other.isSetDataMoveId());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetDataMoveId()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.dataMoveId, other.dataMoveId);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      return 0;
    }

    public _Fields fieldForId(int fieldId) {
      return _Fields.findByThriftId(fieldId);
    }

    public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
      schemes.get(iprot.getScheme()).getScheme().read(iprot, this);
    }

    public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException {
      schemes.get(oprot.getScheme()).getScheme().write(oprot, this);
    }

    @Override
    public String toString() {
      StringBuilder sb = new StringBuilder("deleteGatewayDataStoragePreference_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;
      if (!first) sb.append(", ");
      sb.append("dataMoveId:");
      if (this.dataMoveId == null) {
        sb.append("null");
      } else {
        sb.append(this.dataMoveId);
      }
      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());
      }
      if (dataMoveId == null) {
        throw new org.apache.thrift.protocol.TProtocolException("Required field 'dataMoveId' 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, 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 deleteGatewayDataStoragePreference_argsStandardSchemeFactory implements SchemeFactory {
      public deleteGatewayDataStoragePreference_argsStandardScheme getScheme() {
        return new deleteGatewayDataStoragePreference_argsStandardScheme();
      }
    }

    private static class deleteGatewayDataStoragePreference_argsStandardScheme extends StandardScheme<deleteGatewayDataStoragePreference_args> {

      public void read(org.apache.thrift.protocol.TProtocol iprot, deleteGatewayDataStoragePreference_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;
            case 3: // DATA_MOVE_ID
              if (schemeField.type == org.apache.thrift.protocol.TType.STRING) {
                struct.dataMoveId = iprot.readString();
                struct.setDataMoveIdIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            default:
              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
          }
          iprot.readFieldEnd();
        }
        iprot.readStructEnd();

        // check for required fields of primitive type, which can't be checked in the validate method
        struct.validate();
      }

      public void write(org.apache.thrift.protocol.TProtocol oprot, deleteGatewayDataStoragePreference_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();
        }
        if (struct.dataMoveId != null) {
          oprot.writeFieldBegin(DATA_MOVE_ID_FIELD_DESC);
          oprot.writeString(struct.dataMoveId);
          oprot.writeFieldEnd();
        }
        oprot.writeFieldStop();
        oprot.writeStructEnd();
      }

    }

    private static class deleteGatewayDataStoragePreference_argsTupleSchemeFactory implements SchemeFactory {
      public deleteGatewayDataStoragePreference_argsTupleScheme getScheme() {
        return new deleteGatewayDataStoragePreference_argsTupleScheme();
      }
    }

    private static class deleteGatewayDataStoragePreference_argsTupleScheme extends TupleScheme<deleteGatewayDataStoragePreference_args> {

      @Override
      public void write(org.apache.thrift.protocol.TProtocol prot, deleteGatewayDataStoragePreference_args struct) throws org.apache.thrift.TException {
        TTupleProtocol oprot = (TTupleProtocol) prot;
        struct.authzToken.write(oprot);
        oprot.writeString(struct.gatewayID);
        oprot.writeString(struct.dataMoveId);
      }

      @Override
      public void read(org.apache.thrift.protocol.TProtocol prot, deleteGatewayDataStoragePreference_args struct) throws org.apache.thrift.TException {
        TTupleProtocol iprot = (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);
        struct.dataMoveId = iprot.readString();
        struct.setDataMoveIdIsSet(true);
      }
    }

  }

  public static class deleteGatewayDataStoragePreference_result implements org.apache.thrift.TBase<deleteGatewayDataStoragePreference_result, deleteGatewayDataStoragePreference_result._Fields>, java.io.Serializable, Cloneable, Comparable<deleteGatewayDataStoragePreference_result>   {
    private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("deleteGatewayDataStoragePreference_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 IRE_FIELD_DESC = new org.apache.thrift.protocol.TField("ire", org.apache.thrift.protocol.TType.STRUCT, (short)1);
    private static final org.apache.thrift.protocol.TField ACE_FIELD_DESC = new org.apache.thrift.protocol.TField("ace", org.apache.thrift.protocol.TType.STRUCT, (short)2);
    private static final org.apache.thrift.protocol.TField ASE_FIELD_DESC = new org.apache.thrift.protocol.TField("ase", org.apache.thrift.protocol.TType.STRUCT, (short)3);
    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)4);

    private static final Map<Class<? extends IScheme>, SchemeFactory> schemes = new HashMap<Class<? extends IScheme>, SchemeFactory>();
    static {
      schemes.put(StandardScheme.class, new deleteGatewayDataStoragePreference_resultStandardSchemeFactory());
      schemes.put(TupleScheme.class, new deleteGatewayDataStoragePreference_resultTupleSchemeFactory());
    }

    public boolean success; // required
    public org.apache.airavata.model.error.InvalidRequestException ire; // required
    public org.apache.airavata.model.error.AiravataClientException ace; // required
    public org.apache.airavata.model.error.AiravataSystemException ase; // 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"),
      IRE((short)1, "ire"),
      ACE((short)2, "ace"),
      ASE((short)3, "ase"),
      AE((short)4, "ae");

      private static final Map<String, _Fields> byName = new HashMap<String, _Fields>();

      static {
        for (_Fields field : EnumSet.allOf(_Fields.class)) {
          byName.put(field.getFieldName(), field);
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, or null if its not found.
       */
      public static _Fields findByThriftId(int fieldId) {
        switch(fieldId) {
          case 0: // SUCCESS
            return SUCCESS;
          case 1: // IRE
            return IRE;
          case 2: // ACE
            return ACE;
          case 3: // ASE
            return ASE;
          case 4: // 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 IllegalArgumentException("Field " + fieldId + " doesn't exist!");
        return fields;
      }

      /**
       * Find the _Fields constant that matches name, or null if its not found.
       */
      public static _Fields findByName(String name) {
        return byName.get(name);
      }

      private final short _thriftId;
      private final String _fieldName;

      _Fields(short thriftId, String fieldName) {
        _thriftId = thriftId;
        _fieldName = fieldName;
      }

      public short getThriftFieldId() {
        return _thriftId;
      }

      public String getFieldName() {
        return _fieldName;
      }
    }

    // isset id assignments
    private static final int __SUCCESS_ISSET_ID = 0;
    private byte __isset_bitfield = 0;
    public static final Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
    static {
      Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new EnumMap<_Fields, org.apache.thrift.meta_data.FieldMetaData>(_Fields.class);
      tmpMap.put(_Fields.SUCCESS, new org.apache.thrift.meta_data.FieldMetaData("success", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.BOOL)));
      tmpMap.put(_Fields.IRE, new org.apache.thrift.meta_data.FieldMetaData("ire", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRUCT)));
      tmpMap.put(_Fields.ACE, new org.apache.thrift.meta_data.FieldMetaData("ace", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRUCT)));
      tmpMap.put(_Fields.ASE, new org.apache.thrift.meta_data.FieldMetaData("ase", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRUCT)));
      tmpMap.put(_Fields.AE, new org.apache.thrift.meta_data.FieldMetaData("ae", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRUCT)));
      metaDataMap = Collections.unmodifiableMap(tmpMap);
      org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(deleteGatewayDataStoragePreference_result.class, metaDataMap);
    }

    public deleteGatewayDataStoragePreference_result() {
    }

    public deleteGatewayDataStoragePreference_result(
      boolean success,
      org.apache.airavata.model.error.InvalidRequestException ire,
      org.apache.airavata.model.error.AiravataClientException ace,
      org.apache.airavata.model.error.AiravataSystemException ase,
      org.apache.airavata.model.error.AuthorizationException ae)
    {
      this();
      this.success = success;
      setSuccessIsSet(true);
      this.ire = ire;
      this.ace = ace;
      this.ase = ase;
      this.ae = ae;
    }

    /**
     * Performs a deep copy on <i>other</i>.
     */
    public deleteGatewayDataStoragePreference_result(deleteGatewayDataStoragePreference_result other) {
      __isset_bitfield = other.__isset_bitfield;
      this.success = other.success;
      if (other.isSetIre()) {
        this.ire = new org.apache.airavata.model.error.InvalidRequestException(other.ire);
      }
      if (other.isSetAce()) {
        this.ace = new org.apache.airavata.model.error.AiravataClientException(other.ace);
      }
      if (other.isSetAse()) {
        this.ase = new org.apache.airavata.model.error.AiravataSystemException(other.ase);
      }
      if (other.isSetAe()) {
        this.ae = new org.apache.airavata.model.error.AuthorizationException(other.ae);
      }
    }

    public deleteGatewayDataStoragePreference_result deepCopy() {
      return new deleteGatewayDataStoragePreference_result(this);
    }

    @Override
    public void clear() {
      setSuccessIsSet(false);
      this.success = false;
      this.ire = null;
      this.ace = null;
      this.ase = null;
      this.ae = null;
    }

    public boolean isSuccess() {
      return this.success;
    }

    public deleteGatewayDataStoragePreference_result setSuccess(boolean success) {
      this.success = success;
      setSuccessIsSet(true);
      return this;
    }

    public void unsetSuccess() {
      __isset_bitfield = EncodingUtils.clearBit(__isset_bitfield, __SUCCESS_ISSET_ID);
    }

    /** Returns true if field success is set (has been assigned a value) and false otherwise */
    public boolean isSetSuccess() {
      return EncodingUtils.testBit(__isset_bitfield, __SUCCESS_ISSET_ID);
    }

    public void setSuccessIsSet(boolean value) {
      __isset_bitfield = EncodingUtils.setBit(__isset_bitfield, __SUCCESS_ISSET_ID, value);
    }

    public org.apache.airavata.model.error.InvalidRequestException getIre() {
      return this.ire;
    }

    public deleteGatewayDataStoragePreference_result setIre(org.apache.airavata.model.error.InvalidRequestException ire) {
      this.ire = ire;
      return this;
    }

    public void unsetIre() {
      this.ire = null;
    }

    /** Returns true if field ire is set (has been assigned a value) and false otherwise */
    public boolean isSetIre() {
      return this.ire != null;
    }

    public void setIreIsSet(boolean value) {
      if (!value) {
        this.ire = null;
      }
    }

    public org.apache.airavata.model.error.AiravataClientException getAce() {
      return this.ace;
    }

    public deleteGatewayDataStoragePreference_result setAce(org.apache.airavata.model.error.AiravataClientException ace) {
      this.ace = ace;
      return this;
    }

    public void unsetAce() {
      this.ace = null;
    }

    /** Returns true if field ace is set (has been assigned a value) and false otherwise */
    public boolean isSetAce() {
      return this.ace != null;
    }

    public void setAceIsSet(boolean value) {
      if (!value) {
        this.ace = null;
      }
    }

    public org.apache.airavata.model.error.AiravataSystemException getAse() {
      return this.ase;
    }

    public deleteGatewayDataStoragePreference_result setAse(org.apache.airavata.model.error.AiravataSystemException ase) {
      this.ase = ase;
      return this;
    }

    public void unsetAse() {
      this.ase = null;
    }

    /** Returns true if field ase is set (has been assigned a value) and false otherwise */
    public boolean isSetAse() {
      return this.ase != null;
    }

    public void setAseIsSet(boolean value) {
      if (!value) {
        this.ase = null;
      }
    }

    public org.apache.airavata.model.error.AuthorizationException getAe() {
      return this.ae;
    }

    public deleteGatewayDataStoragePreference_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, Object value) {
      switch (field) {
      case SUCCESS:
        if (value == null) {
          unsetSuccess();
        } else {
          setSuccess((Boolean)value);
        }
        break;

      case IRE:
        if (value == null) {
          unsetIre();
        } else {
          setIre((org.apache.airavata.model.error.InvalidRequestException)value);
        }
        break;

      case ACE:
        if (value == null) {
          unsetAce();
        } else {
          setAce((org.apache.airavata.model.error.AiravataClientException)value);
        }
        break;

      case ASE:
        if (value == null) {
          unsetAse();
        } else {
          setAse((org.apache.airavata.model.error.AiravataSystemException)value);
        }
        break;

      case AE:
        if (value == null) {
          unsetAe();
        } else {
          setAe((org.apache.airavata.model.error.AuthorizationException)value);
        }
        break;

      }
    }

    public Object getFieldValue(_Fields field) {
      switch (field) {
      case SUCCESS:
        return Boolean.valueOf(isSuccess());

      case IRE:
        return getIre();

      case ACE:
        return getAce();

      case ASE:
        return getAse();

      case AE:
        return getAe();

      }
      throw new IllegalStateException();
    }

    /** Returns true if field corresponding to fieldID is set (has been assigned a value) and false otherwise */
    public boolean isSet(_Fields field) {
      if (field == null) {
        throw new IllegalArgumentException();
      }

      switch (field) {
      case SUCCESS:
        return isSetSuccess();
      case IRE:
        return isSetIre();
      case ACE:
        return isSetAce();
      case ASE:
        return isSetAse();
      case AE:
        return isSetAe();
      }
      throw new IllegalStateException();
    }

    @Override
    public boolean equals(Object that) {
      if (that == null)
        return false;
      if (that instanceof deleteGatewayDataStoragePreference_result)
        return this.equals((deleteGatewayDataStoragePreference_result)that);
      return false;
    }

    public boolean equals(deleteGatewayDataStoragePreference_result that) {
      if (that == null)
        return false;

      boolean this_present_success = true;
      boolean that_present_success = true;
      if (this_present_success || that_present_success) {
        if (!(this_present_success && that_present_success))
          return false;
        if (this.success != that.success)
          return false;
      }

      boolean this_present_ire = true && this.isSetIre();
      boolean that_present_ire = true && that.isSetIre();
      if (this_present_ire || that_present_ire) {
        if (!(this_present_ire && that_present_ire))
          return false;
        if (!this.ire.equals(that.ire))
          return false;
      }

      boolean this_present_ace = true && this.isSetAce();
      boolean that_present_ace = true && that.isSetAce();
      if (this_present_ace || that_present_ace) {
        if (!(this_present_ace && that_present_ace))
          return false;
        if (!this.ace.equals(that.ace))
          return false;
      }

      boolean this_present_ase = true && this.isSetAse();
      boolean that_present_ase = true && that.isSetAse();
      if (this_present_ase || that_present_ase) {
        if (!(this_present_ase && that_present_ase))
          return false;
        if (!this.ase.equals(that.ase))
          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() {
      List<Object> list = new ArrayList<Object>();

      boolean present_success = true;
      list.add(present_success);
      if (present_success)
        list.add(success);

      boolean present_ire = true && (isSetIre());
      list.add(present_ire);
      if (present_ire)
        list.add(ire);

      boolean present_ace = true && (isSetAce());
      list.add(present_ace);
      if (present_ace)
        list.add(ace);

      boolean present_ase = true && (isSetAse());
      list.add(present_ase);
      if (present_ase)
        list.add(ase);

      boolean present_ae = true && (isSetAe());
      list.add(present_ae);
      if (present_ae)
        list.add(ae);

      return list.hashCode();
    }

    @Override
    public int compareTo(deleteGatewayDataStoragePreference_result other) {
      if (!getClass().equals(other.getClass())) {
        return getClass().getName().compareTo(other.getClass().getName());
      }

      int lastComparison = 0;

      lastComparison = Boolean.valueOf(isSetSuccess()).compareTo(other.isSetSuccess());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetSuccess()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.success, other.success);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = Boolean.valueOf(isSetIre()).compareTo(other.isSetIre());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetIre()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.ire, other.ire);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = Boolean.valueOf(isSetAce()).compareTo(other.isSetAce());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetAce()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.ace, other.ace);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = Boolean.valueOf(isSetAse()).compareTo(other.isSetAse());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetAse()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.ase, other.ase);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = 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 {
      schemes.get(iprot.getScheme()).getScheme().read(iprot, this);
    }

    public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException {
      schemes.get(oprot.getScheme()).getScheme().write(oprot, this);
      }

    @Override
    public String toString() {
      StringBuilder sb = new StringBuilder("deleteGatewayDataStoragePreference_result(");
      boolean first = true;

      sb.append("success:");
      sb.append(this.success);
      first = false;
      if (!first) sb.append(", ");
      sb.append("ire:");
      if (this.ire == null) {
        sb.append("null");
      } else {
        sb.append(this.ire);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("ace:");
      if (this.ace == null) {
        sb.append("null");
      } else {
        sb.append(this.ace);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("ase:");
      if (this.ase == null) {
        sb.append("null");
      } else {
        sb.append(this.ase);
      }
      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, 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 deleteGatewayDataStoragePreference_resultStandardSchemeFactory implements SchemeFactory {
      public deleteGatewayDataStoragePreference_resultStandardScheme getScheme() {
        return new deleteGatewayDataStoragePreference_resultStandardScheme();
      }
    }

    private static class deleteGatewayDataStoragePreference_resultStandardScheme extends StandardScheme<deleteGatewayDataStoragePreference_result> {

      public void read(org.apache.thrift.protocol.TProtocol iprot, deleteGatewayDataStoragePreference_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: // IRE
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.ire = new org.apache.airavata.model.error.InvalidRequestException();
                struct.ire.read(iprot);
                struct.setIreIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 2: // ACE
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.ace = new org.apache.airavata.model.error.AiravataClientException();
                struct.ace.read(iprot);
                struct.setAceIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 3: // ASE
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.ase = new org.apache.airavata.model.error.AiravataSystemException();
                struct.ase.read(iprot);
                struct.setAseIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 4: // 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, deleteGatewayDataStoragePreference_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.ire != null) {
          oprot.writeFieldBegin(IRE_FIELD_DESC);
          struct.ire.write(oprot);
          oprot.writeFieldEnd();
        }
        if (struct.ace != null) {
          oprot.writeFieldBegin(ACE_FIELD_DESC);
          struct.ace.write(oprot);
          oprot.writeFieldEnd();
        }
        if (struct.ase != null) {
          oprot.writeFieldBegin(ASE_FIELD_DESC);
          struct.ase.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 deleteGatewayDataStoragePreference_resultTupleSchemeFactory implements SchemeFactory {
      public deleteGatewayDataStoragePreference_resultTupleScheme getScheme() {
        return new deleteGatewayDataStoragePreference_resultTupleScheme();
      }
    }

    private static class deleteGatewayDataStoragePreference_resultTupleScheme extends TupleScheme<deleteGatewayDataStoragePreference_result> {

      @Override
      public void write(org.apache.thrift.protocol.TProtocol prot, deleteGatewayDataStoragePreference_result struct) throws org.apache.thrift.TException {
        TTupleProtocol oprot = (TTupleProtocol) prot;
        BitSet optionals = new BitSet();
        if (struct.isSetSuccess()) {
          optionals.set(0);
        }
        if (struct.isSetIre()) {
          optionals.set(1);
        }
        if (struct.isSetAce()) {
          optionals.set(2);
        }
        if (struct.isSetAse()) {
          optionals.set(3);
        }
        if (struct.isSetAe()) {
          optionals.set(4);
        }
        oprot.writeBitSet(optionals, 5);
        if (struct.isSetSuccess()) {
          oprot.writeBool(struct.success);
        }
        if (struct.isSetIre()) {
          struct.ire.write(oprot);
        }
        if (struct.isSetAce()) {
          struct.ace.write(oprot);
        }
        if (struct.isSetAse()) {
          struct.ase.write(oprot);
        }
        if (struct.isSetAe()) {
          struct.ae.write(oprot);
        }
      }

      @Override
      public void read(org.apache.thrift.protocol.TProtocol prot, deleteGatewayDataStoragePreference_result struct) throws org.apache.thrift.TException {
        TTupleProtocol iprot = (TTupleProtocol) prot;
        BitSet incoming = iprot.readBitSet(5);
        if (incoming.get(0)) {
          struct.success = iprot.readBool();
          struct.setSuccessIsSet(true);
        }
        if (incoming.get(1)) {
          struct.ire = new org.apache.airavata.model.error.InvalidRequestException();
          struct.ire.read(iprot);
          struct.setIreIsSet(true);
        }
        if (incoming.get(2)) {
          struct.ace = new org.apache.airavata.model.error.AiravataClientException();
          struct.ace.read(iprot);
          struct.setAceIsSet(true);
        }
        if (incoming.get(3)) {
          struct.ase = new org.apache.airavata.model.error.AiravataSystemException();
          struct.ase.read(iprot);
          struct.setAseIsSet(true);
        }
        if (incoming.get(4)) {
          struct.ae = new org.apache.airavata.model.error.AuthorizationException();
          struct.ae.read(iprot);
          struct.setAeIsSet(true);
        }
      }
    }

  }

  public static class getAllWorkflows_args implements org.apache.thrift.TBase<getAllWorkflows_args, getAllWorkflows_args._Fields>, java.io.Serializable, Cloneable, Comparable<getAllWorkflows_args>   {
    private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("getAllWorkflows_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 Map<Class<? extends IScheme>, SchemeFactory> schemes = new HashMap<Class<? extends IScheme>, SchemeFactory>();
    static {
      schemes.put(StandardScheme.class, new getAllWorkflows_argsStandardSchemeFactory());
      schemes.put(TupleScheme.class, new getAllWorkflows_argsTupleSchemeFactory());
    }

    public org.apache.airavata.model.security.AuthzToken authzToken; // required
    public 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 Map<String, _Fields> byName = new HashMap<String, _Fields>();

      static {
        for (_Fields field : EnumSet.allOf(_Fields.class)) {
          byName.put(field.getFieldName(), field);
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, or null if its not found.
       */
      public static _Fields findByThriftId(int fieldId) {
        switch(fieldId) {
          case 1: // 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 IllegalArgumentException("Field " + fieldId + " doesn't exist!");
        return fields;
      }

      /**
       * Find the _Fields constant that matches name, or null if its not found.
       */
      public static _Fields findByName(String name) {
        return byName.get(name);
      }

      private final short _thriftId;
      private final String _fieldName;

      _Fields(short thriftId, String fieldName) {
        _thriftId = thriftId;
        _fieldName = fieldName;
      }

      public short getThriftFieldId() {
        return _thriftId;
      }

      public String getFieldName() {
        return _fieldName;
      }
    }

    // isset id assignments
    public static final Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
    static {
      Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new EnumMap<_Fields, org.apache.thrift.meta_data.FieldMetaData>(_Fields.class);
      tmpMap.put(_Fields.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 = Collections.unmodifiableMap(tmpMap);
      org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(getAllWorkflows_args.class, metaDataMap);
    }

    public getAllWorkflows_args() {
    }

    public getAllWorkflows_args(
      org.apache.airavata.model.security.AuthzToken authzToken,
      String gatewayId)
    {
      this();
      this.authzToken = authzToken;
      this.gatewayId = gatewayId;
    }

    /**
     * Performs a deep copy on <i>other</i>.
     */
    public getAllWorkflows_args(getAllWorkflows_args other) {
      if (other.isSetAuthzToken()) {
        this.authzToken = new org.apache.airavata.model.security.AuthzToken(other.authzToken);
      }
      if (other.isSetGatewayId()) {
        this.gatewayId = other.gatewayId;
      }
    }

    public getAllWorkflows_args deepCopy() {
      return new getAllWorkflows_args(this);
    }

    @Override
    public void clear() {
      this.authzToken = null;
      this.gatewayId = null;
    }

    public org.apache.airavata.model.security.AuthzToken getAuthzToken() {
      return this.authzToken;
    }

    public getAllWorkflows_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 String getGatewayId() {
      return this.gatewayId;
    }

    public getAllWorkflows_args setGatewayId(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, 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((String)value);
        }
        break;

      }
    }

    public Object getFieldValue(_Fields field) {
      switch (field) {
      case AUTHZ_TOKEN:
        return getAuthzToken();

      case GATEWAY_ID:
        return getGatewayId();

      }
      throw new IllegalStateException();
    }

    /** Returns true if field corresponding to fieldID is set (has been assigned a value) and false otherwise */
    public boolean isSet(_Fields field) {
      if (field == null) {
        throw new IllegalArgumentException();
      }

      switch (field) {
      case AUTHZ_TOKEN:
        return isSetAuthzToken();
      case GATEWAY_ID:
        return isSetGatewayId();
      }
      throw new IllegalStateException();
    }

    @Override
    public boolean equals(Object that) {
      if (that == null)
        return false;
      if (that instanceof getAllWorkflows_args)
        return this.equals((getAllWorkflows_args)that);
      return false;
    }

    public boolean equals(getAllWorkflows_args that) {
      if (that == null)
        return false;

      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() {
      List<Object> list = new ArrayList<Object>();

      boolean present_authzToken = true && (isSetAuthzToken());
      list.add(present_authzToken);
      if (present_authzToken)
        list.add(authzToken);

      boolean present_gatewayId = true && (isSetGatewayId());
      list.add(present_gatewayId);
      if (present_gatewayId)
        list.add(gatewayId);

      return list.hashCode();
    }

    @Override
    public int compareTo(getAllWorkflows_args other) {
      if (!getClass().equals(other.getClass())) {
        return getClass().getName().compareTo(other.getClass().getName());
      }

      int lastComparison = 0;

      lastComparison = 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 = 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 {
      schemes.get(iprot.getScheme()).getScheme().read(iprot, this);
    }

    public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException {
      schemes.get(oprot.getScheme()).getScheme().write(oprot, this);
    }

    @Override
    public String toString() {
      StringBuilder sb = new StringBuilder("getAllWorkflows_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, 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 getAllWorkflows_argsStandardSchemeFactory implements SchemeFactory {
      public getAllWorkflows_argsStandardScheme getScheme() {
        return new getAllWorkflows_argsStandardScheme();
      }
    }

    private static class getAllWorkflows_argsStandardScheme extends StandardScheme<getAllWorkflows_args> {

      public void read(org.apache.thrift.protocol.TProtocol iprot, getAllWorkflows_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, getAllWorkflows_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 getAllWorkflows_argsTupleSchemeFactory implements SchemeFactory {
      public getAllWorkflows_argsTupleScheme getScheme() {
        return new getAllWorkflows_argsTupleScheme();
      }
    }

    private static class getAllWorkflows_argsTupleScheme extends TupleScheme<getAllWorkflows_args> {

      @Override
      public void write(org.apache.thrift.protocol.TProtocol prot, getAllWorkflows_args struct) throws org.apache.thrift.TException {
        TTupleProtocol oprot = (TTupleProtocol) prot;
        struct.authzToken.write(oprot);
        oprot.writeString(struct.gatewayId);
      }

      @Override
      public void read(org.apache.thrift.protocol.TProtocol prot, getAllWorkflows_args struct) throws org.apache.thrift.TException {
        TTupleProtocol iprot = (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);
      }
    }

  }

  public static class getAllWorkflows_result implements org.apache.thrift.TBase<getAllWorkflows_result, getAllWorkflows_result._Fields>, java.io.Serializable, Cloneable, Comparable<getAllWorkflows_result>   {
    private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("getAllWorkflows_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 IRE_FIELD_DESC = new org.apache.thrift.protocol.TField("ire", org.apache.thrift.protocol.TType.STRUCT, (short)1);
    private static final org.apache.thrift.protocol.TField ACE_FIELD_DESC = new org.apache.thrift.protocol.TField("ace", org.apache.thrift.protocol.TType.STRUCT, (short)2);
    private static final org.apache.thrift.protocol.TField ASE_FIELD_DESC = new org.apache.thrift.protocol.TField("ase", org.apache.thrift.protocol.TType.STRUCT, (short)3);
    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)4);

    private static final Map<Class<? extends IScheme>, SchemeFactory> schemes = new HashMap<Class<? extends IScheme>, SchemeFactory>();
    static {
      schemes.put(StandardScheme.class, new getAllWorkflows_resultStandardSchemeFactory());
      schemes.put(TupleScheme.class, new getAllWorkflows_resultTupleSchemeFactory());
    }

    public List<String> success; // required
    public org.apache.airavata.model.error.InvalidRequestException ire; // required
    public org.apache.airavata.model.error.AiravataClientException ace; // required
    public org.apache.airavata.model.error.AiravataSystemException ase; // 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"),
      IRE((short)1, "ire"),
      ACE((short)2, "ace"),
      ASE((short)3, "ase"),
      AE((short)4, "ae");

      private static final Map<String, _Fields> byName = new HashMap<String, _Fields>();

      static {
        for (_Fields field : EnumSet.allOf(_Fields.class)) {
          byName.put(field.getFieldName(), field);
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, or null if its not found.
       */
      public static _Fields findByThriftId(int fieldId) {
        switch(fieldId) {
          case 0: // SUCCESS
            return SUCCESS;
          case 1: // IRE
            return IRE;
          case 2: // ACE
            return ACE;
          case 3: // ASE
            return ASE;
          case 4: // 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 IllegalArgumentException("Field " + fieldId + " doesn't exist!");
        return fields;
      }

      /**
       * Find the _Fields constant that matches name, or null if its not found.
       */
      public static _Fields findByName(String name) {
        return byName.get(name);
      }

      private final short _thriftId;
      private final String _fieldName;

      _Fields(short thriftId, String fieldName) {
        _thriftId = thriftId;
        _fieldName = fieldName;
      }

      public short getThriftFieldId() {
        return _thriftId;
      }

      public String getFieldName() {
        return _fieldName;
      }
    }

    // isset id assignments
    public static final Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
    static {
      Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new EnumMap<_Fields, org.apache.thrift.meta_data.FieldMetaData>(_Fields.class);
      tmpMap.put(_Fields.SUCCESS, new org.apache.thrift.meta_data.FieldMetaData("success", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.ListMetaData(org.apache.thrift.protocol.TType.LIST, 
              new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING))));
      tmpMap.put(_Fields.IRE, new org.apache.thrift.meta_data.FieldMetaData("ire", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRUCT)));
      tmpMap.put(_Fields.ACE, new org.apache.thrift.meta_data.FieldMetaData("ace", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRUCT)));
      tmpMap.put(_Fields.ASE, new org.apache.thrift.meta_data.FieldMetaData("ase", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRUCT)));
      tmpMap.put(_Fields.AE, new org.apache.thrift.meta_data.FieldMetaData("ae", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRUCT)));
      metaDataMap = Collections.unmodifiableMap(tmpMap);
      org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(getAllWorkflows_result.class, metaDataMap);
    }

    public getAllWorkflows_result() {
    }

    public getAllWorkflows_result(
      List<String> success,
      org.apache.airavata.model.error.InvalidRequestException ire,
      org.apache.airavata.model.error.AiravataClientException ace,
      org.apache.airavata.model.error.AiravataSystemException ase,
      org.apache.airavata.model.error.AuthorizationException ae)
    {
      this();
      this.success = success;
      this.ire = ire;
      this.ace = ace;
      this.ase = ase;
      this.ae = ae;
    }

    /**
     * Performs a deep copy on <i>other</i>.
     */
    public getAllWorkflows_result(getAllWorkflows_result other) {
      if (other.isSetSuccess()) {
        List<String> __this__success = new ArrayList<String>(other.success);
        this.success = __this__success;
      }
      if (other.isSetIre()) {
        this.ire = new org.apache.airavata.model.error.InvalidRequestException(other.ire);
      }
      if (other.isSetAce()) {
        this.ace = new org.apache.airavata.model.error.AiravataClientException(other.ace);
      }
      if (other.isSetAse()) {
        this.ase = new org.apache.airavata.model.error.AiravataSystemException(other.ase);
      }
      if (other.isSetAe()) {
        this.ae = new org.apache.airavata.model.error.AuthorizationException(other.ae);
      }
    }

    public getAllWorkflows_result deepCopy() {
      return new getAllWorkflows_result(this);
    }

    @Override
    public void clear() {
      this.success = null;
      this.ire = null;
      this.ace = null;
      this.ase = null;
      this.ae = null;
    }

    public int getSuccessSize() {
      return (this.success == null) ? 0 : this.success.size();
    }

    public java.util.Iterator<String> getSuccessIterator() {
      return (this.success == null) ? null : this.success.iterator();
    }

    public void addToSuccess(String elem) {
      if (this.success == null) {
        this.success = new ArrayList<String>();
      }
      this.success.add(elem);
    }

    public List<String> getSuccess() {
      return this.success;
    }

    public getAllWorkflows_result setSuccess(List<String> success) {
      this.success = success;
      return this;
    }

    public void unsetSuccess() {
      this.success = null;
    }

    /** Returns true if field success is set (has been assigned a value) and false otherwise */
    public boolean isSetSuccess() {
      return this.success != null;
    }

    public void setSuccessIsSet(boolean value) {
      if (!value) {
        this.success = null;
      }
    }

    public org.apache.airavata.model.error.InvalidRequestException getIre() {
      return this.ire;
    }

    public getAllWorkflows_result setIre(org.apache.airavata.model.error.InvalidRequestException ire) {
      this.ire = ire;
      return this;
    }

    public void unsetIre() {
      this.ire = null;
    }

    /** Returns true if field ire is set (has been assigned a value) and false otherwise */
    public boolean isSetIre() {
      return this.ire != null;
    }

    public void setIreIsSet(boolean value) {
      if (!value) {
        this.ire = null;
      }
    }

    public org.apache.airavata.model.error.AiravataClientException getAce() {
      return this.ace;
    }

    public getAllWorkflows_result setAce(org.apache.airavata.model.error.AiravataClientException ace) {
      this.ace = ace;
      return this;
    }

    public void unsetAce() {
      this.ace = null;
    }

    /** Returns true if field ace is set (has been assigned a value) and false otherwise */
    public boolean isSetAce() {
      return this.ace != null;
    }

    public void setAceIsSet(boolean value) {
      if (!value) {
        this.ace = null;
      }
    }

    public org.apache.airavata.model.error.AiravataSystemException getAse() {
      return this.ase;
    }

    public getAllWorkflows_result setAse(org.apache.airavata.model.error.AiravataSystemException ase) {
      this.ase = ase;
      return this;
    }

    public void unsetAse() {
      this.ase = null;
    }

    /** Returns true if field ase is set (has been assigned a value) and false otherwise */
    public boolean isSetAse() {
      return this.ase != null;
    }

    public void setAseIsSet(boolean value) {
      if (!value) {
        this.ase = null;
      }
    }

    public org.apache.airavata.model.error.AuthorizationException getAe() {
      return this.ae;
    }

    public getAllWorkflows_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, Object value) {
      switch (field) {
      case SUCCESS:
        if (value == null) {
          unsetSuccess();
        } else {
          setSuccess((List<String>)value);
        }
        break;

      case IRE:
        if (value == null) {
          unsetIre();
        } else {
          setIre((org.apache.airavata.model.error.InvalidRequestException)value);
        }
        break;

      case ACE:
        if (value == null) {
          unsetAce();
        } else {
          setAce((org.apache.airavata.model.error.AiravataClientException)value);
        }
        break;

      case ASE:
        if (value == null) {
          unsetAse();
        } else {
          setAse((org.apache.airavata.model.error.AiravataSystemException)value);
        }
        break;

      case AE:
        if (value == null) {
          unsetAe();
        } else {
          setAe((org.apache.airavata.model.error.AuthorizationException)value);
        }
        break;

      }
    }

    public Object getFieldValue(_Fields field) {
      switch (field) {
      case SUCCESS:
        return getSuccess();

      case IRE:
        return getIre();

      case ACE:
        return getAce();

      case ASE:
        return getAse();

      case AE:
        return getAe();

      }
      throw new IllegalStateException();
    }

    /** Returns true if field corresponding to fieldID is set (has been assigned a value) and false otherwise */
    public boolean isSet(_Fields field) {
      if (field == null) {
        throw new IllegalArgumentException();
      }

      switch (field) {
      case SUCCESS:
        return isSetSuccess();
      case IRE:
        return isSetIre();
      case ACE:
        return isSetAce();
      case ASE:
        return isSetAse();
      case AE:
        return isSetAe();
      }
      throw new IllegalStateException();
    }

    @Override
    public boolean equals(Object that) {
      if (that == null)
        return false;
      if (that instanceof getAllWorkflows_result)
        return this.equals((getAllWorkflows_result)that);
      return false;
    }

    public boolean equals(getAllWorkflows_result that) {
      if (that == null)
        return false;

      boolean this_present_success = true && this.isSetSuccess();
      boolean that_present_success = true && that.isSetSuccess();
      if (this_present_success || that_present_success) {
        if (!(this_present_success && that_present_success))
          return false;
        if (!this.success.equals(that.success))
          return false;
      }

      boolean this_present_ire = true && this.isSetIre();
      boolean that_present_ire = true && that.isSetIre();
      if (this_present_ire || that_present_ire) {
        if (!(this_present_ire && that_present_ire))
          return false;
        if (!this.ire.equals(that.ire))
          return false;
      }

      boolean this_present_ace = true && this.isSetAce();
      boolean that_present_ace = true && that.isSetAce();
      if (this_present_ace || that_present_ace) {
        if (!(this_present_ace && that_present_ace))
          return false;
        if (!this.ace.equals(that.ace))
          return false;
      }

      boolean this_present_ase = true && this.isSetAse();
      boolean that_present_ase = true && that.isSetAse();
      if (this_present_ase || that_present_ase) {
        if (!(this_present_ase && that_present_ase))
          return false;
        if (!this.ase.equals(that.ase))
          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() {
      List<Object> list = new ArrayList<Object>();

      boolean present_success = true && (isSetSuccess());
      list.add(present_success);
      if (present_success)
        list.add(success);

      boolean present_ire = true && (isSetIre());
      list.add(present_ire);
      if (present_ire)
        list.add(ire);

      boolean present_ace = true && (isSetAce());
      list.add(present_ace);
      if (present_ace)
        list.add(ace);

      boolean present_ase = true && (isSetAse());
      list.add(present_ase);
      if (present_ase)
        list.add(ase);

      boolean present_ae = true && (isSetAe());
      list.add(present_ae);
      if (present_ae)
        list.add(ae);

      return list.hashCode();
    }

    @Override
    public int compareTo(getAllWorkflows_result other) {
      if (!getClass().equals(other.getClass())) {
        return getClass().getName().compareTo(other.getClass().getName());
      }

      int lastComparison = 0;

      lastComparison = Boolean.valueOf(isSetSuccess()).compareTo(other.isSetSuccess());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetSuccess()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.success, other.success);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = Boolean.valueOf(isSetIre()).compareTo(other.isSetIre());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetIre()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.ire, other.ire);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = Boolean.valueOf(isSetAce()).compareTo(other.isSetAce());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetAce()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.ace, other.ace);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = Boolean.valueOf(isSetAse()).compareTo(other.isSetAse());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetAse()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.ase, other.ase);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = 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 {
      schemes.get(iprot.getScheme()).getScheme().read(iprot, this);
    }

    public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException {
      schemes.get(oprot.getScheme()).getScheme().write(oprot, this);
      }

    @Override
    public String toString() {
      StringBuilder sb = new StringBuilder("getAllWorkflows_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("ire:");
      if (this.ire == null) {
        sb.append("null");
      } else {
        sb.append(this.ire);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("ace:");
      if (this.ace == null) {
        sb.append("null");
      } else {
        sb.append(this.ace);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("ase:");
      if (this.ase == null) {
        sb.append("null");
      } else {
        sb.append(this.ase);
      }
      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, 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 getAllWorkflows_resultStandardSchemeFactory implements SchemeFactory {
      public getAllWorkflows_resultStandardScheme getScheme() {
        return new getAllWorkflows_resultStandardScheme();
      }
    }

    private static class getAllWorkflows_resultStandardScheme extends StandardScheme<getAllWorkflows_result> {

      public void read(org.apache.thrift.protocol.TProtocol iprot, getAllWorkflows_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 _list272 = iprot.readListBegin();
                  struct.success = new ArrayList<String>(_list272.size);
                  String _elem273;
                  for (int _i274 = 0; _i274 < _list272.size; ++_i274)
                  {
                    _elem273 = iprot.readString();
                    struct.success.add(_elem273);
                  }
                  iprot.readListEnd();
                }
                struct.setSuccessIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 1: // IRE
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.ire = new org.apache.airavata.model.error.InvalidRequestException();
                struct.ire.read(iprot);
                struct.setIreIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 2: // ACE
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.ace = new org.apache.airavata.model.error.AiravataClientException();
                struct.ace.read(iprot);
                struct.setAceIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 3: // ASE
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.ase = new org.apache.airavata.model.error.AiravataSystemException();
                struct.ase.read(iprot);
                struct.setAseIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 4: // 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, getAllWorkflows_result struct) throws org.apache.thrift.TException {
        struct.validate();

        oprot.writeStructBegin(STRUCT_DESC);
        if (struct.success != null) {
          oprot.writeFieldBegin(SUCCESS_FIELD_DESC);
          {
            oprot.writeListBegin(new org.apache.thrift.protocol.TList(org.apache.thrift.protocol.TType.STRING, struct.success.size()));
            for (String _iter275 : struct.success)
            {
              oprot.writeString(_iter275);
            }
            oprot.writeListEnd();
          }
          oprot.writeFieldEnd();
        }
        if (struct.ire != null) {
          oprot.writeFieldBegin(IRE_FIELD_DESC);
          struct.ire.write(oprot);
          oprot.writeFieldEnd();
        }
        if (struct.ace != null) {
          oprot.writeFieldBegin(ACE_FIELD_DESC);
          struct.ace.write(oprot);
          oprot.writeFieldEnd();
        }
        if (struct.ase != null) {
          oprot.writeFieldBegin(ASE_FIELD_DESC);
          struct.ase.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 getAllWorkflows_resultTupleSchemeFactory implements SchemeFactory {
      public getAllWorkflows_resultTupleScheme getScheme() {
        return new getAllWorkflows_resultTupleScheme();
      }
    }

    private static class getAllWorkflows_resultTupleScheme extends TupleScheme<getAllWorkflows_result> {

      @Override
      public void write(org.apache.thrift.protocol.TProtocol prot, getAllWorkflows_result struct) throws org.apache.thrift.TException {
        TTupleProtocol oprot = (TTupleProtocol) prot;
        BitSet optionals = new BitSet();
        if (struct.isSetSuccess()) {
          optionals.set(0);
        }
        if (struct.isSetIre()) {
          optionals.set(1);
        }
        if (struct.isSetAce()) {
          optionals.set(2);
        }
        if (struct.isSetAse()) {
          optionals.set(3);
        }
        if (struct.isSetAe()) {
          optionals.set(4);
        }
        oprot.writeBitSet(optionals, 5);
        if (struct.isSetSuccess()) {
          {
            oprot.writeI32(struct.success.size());
            for (String _iter276 : struct.success)
            {
              oprot.writeString(_iter276);
            }
          }
        }
        if (struct.isSetIre()) {
          struct.ire.write(oprot);
        }
        if (struct.isSetAce()) {
          struct.ace.write(oprot);
        }
        if (struct.isSetAse()) {
          struct.ase.write(oprot);
        }
        if (struct.isSetAe()) {
          struct.ae.write(oprot);
        }
      }

      @Override
      public void read(org.apache.thrift.protocol.TProtocol prot, getAllWorkflows_result struct) throws org.apache.thrift.TException {
        TTupleProtocol iprot = (TTupleProtocol) prot;
        BitSet incoming = iprot.readBitSet(5);
        if (incoming.get(0)) {
          {
            org.apache.thrift.protocol.TList _list277 = new org.apache.thrift.protocol.TList(org.apache.thrift.protocol.TType.STRING, iprot.readI32());
            struct.success = new ArrayList<String>(_list277.size);
            String _elem278;
            for (int _i279 = 0; _i279 < _list277.size; ++_i279)
            {
              _elem278 = iprot.readString();
              struct.success.add(_elem278);
            }
          }
          struct.setSuccessIsSet(true);
        }
        if (incoming.get(1)) {
          struct.ire = new org.apache.airavata.model.error.InvalidRequestException();
          struct.ire.read(iprot);
          struct.setIreIsSet(true);
        }
        if (incoming.get(2)) {
          struct.ace = new org.apache.airavata.model.error.AiravataClientException();
          struct.ace.read(iprot);
          struct.setAceIsSet(true);
        }
        if (incoming.get(3)) {
          struct.ase = new org.apache.airavata.model.error.AiravataSystemException();
          struct.ase.read(iprot);
          struct.setAseIsSet(true);
        }
        if (incoming.get(4)) {
          struct.ae = new org.apache.airavata.model.error.AuthorizationException();
          struct.ae.read(iprot);
          struct.setAeIsSet(true);
        }
      }
    }

  }

  public static class getWorkflow_args implements org.apache.thrift.TBase<getWorkflow_args, getWorkflow_args._Fields>, java.io.Serializable, Cloneable, Comparable<getWorkflow_args>   {
    private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("getWorkflow_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 WORKFLOW_TEMPLATE_ID_FIELD_DESC = new org.apache.thrift.protocol.TField("workflowTemplateId", org.apache.thrift.protocol.TType.STRING, (short)2);

    private static final Map<Class<? extends IScheme>, SchemeFactory> schemes = new HashMap<Class<? extends IScheme>, SchemeFactory>();
    static {
      schemes.put(StandardScheme.class, new getWorkflow_argsStandardSchemeFactory());
      schemes.put(TupleScheme.class, new getWorkflow_argsTupleSchemeFactory());
    }

    public org.apache.airavata.model.security.AuthzToken authzToken; // required
    public String workflowTemplateId; // required

    /** 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"),
      WORKFLOW_TEMPLATE_ID((short)2, "workflowTemplateId");

      private static final Map<String, _Fields> byName = new HashMap<String, _Fields>();

      static {
        for (_Fields field : EnumSet.allOf(_Fields.class)) {
          byName.put(field.getFieldName(), field);
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, or null if its not found.
       */
      public static _Fields findByThriftId(int fieldId) {
        switch(fieldId) {
          case 1: // AUTHZ_TOKEN
            return AUTHZ_TOKEN;
          case 2: // WORKFLOW_TEMPLATE_ID
            return WORKFLOW_TEMPLATE_ID;
          default:
            return null;
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, throwing an exception
       * if it is not found.
       */
      public static _Fields findByThriftIdOrThrow(int fieldId) {
        _Fields fields = findByThriftId(fieldId);
        if (fields == null) throw new IllegalArgumentException("Field " + fieldId + " doesn't exist!");
        return fields;
      }

      /**
       * Find the _Fields constant that matches name, or null if its not found.
       */
      public static _Fields findByName(String name) {
        return byName.get(name);
      }

      private final short _thriftId;
      private final String _fieldName;

      _Fields(short thriftId, String fieldName) {
        _thriftId = thriftId;
        _fieldName = fieldName;
      }

      public short getThriftFieldId() {
        return _thriftId;
      }

      public String getFieldName() {
        return _fieldName;
      }
    }

    // isset id assignments
    public static final Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
    static {
      Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new EnumMap<_Fields, org.apache.thrift.meta_data.FieldMetaData>(_Fields.class);
      tmpMap.put(_Fields.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.WORKFLOW_TEMPLATE_ID, new org.apache.thrift.meta_data.FieldMetaData("workflowTemplateId", org.apache.thrift.TFieldRequirementType.REQUIRED, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING)));
      metaDataMap = Collections.unmodifiableMap(tmpMap);
      org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(getWorkflow_args.class, metaDataMap);
    }

    public getWorkflow_args() {
    }

    public getWorkflow_args(
      org.apache.airavata.model.security.AuthzToken authzToken,
      String workflowTemplateId)
    {
      this();
      this.authzToken = authzToken;
      this.workflowTemplateId = workflowTemplateId;
    }

    /**
     * Performs a deep copy on <i>other</i>.
     */
    public getWorkflow_args(getWorkflow_args other) {
      if (other.isSetAuthzToken()) {
        this.authzToken = new org.apache.airavata.model.security.AuthzToken(other.authzToken);
      }
      if (other.isSetWorkflowTemplateId()) {
        this.workflowTemplateId = other.workflowTemplateId;
      }
    }

    public getWorkflow_args deepCopy() {
      return new getWorkflow_args(this);
    }

    @Override
    public void clear() {
      this.authzToken = null;
      this.workflowTemplateId = null;
    }

    public org.apache.airavata.model.security.AuthzToken getAuthzToken() {
      return this.authzToken;
    }

    public getWorkflow_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 String getWorkflowTemplateId() {
      return this.workflowTemplateId;
    }

    public getWorkflow_args setWorkflowTemplateId(String workflowTemplateId) {
      this.workflowTemplateId = workflowTemplateId;
      return this;
    }

    public void unsetWorkflowTemplateId() {
      this.workflowTemplateId = null;
    }

    /** Returns true if field workflowTemplateId is set (has been assigned a value) and false otherwise */
    public boolean isSetWorkflowTemplateId() {
      return this.workflowTemplateId != null;
    }

    public void setWorkflowTemplateIdIsSet(boolean value) {
      if (!value) {
        this.workflowTemplateId = null;
      }
    }

    public void setFieldValue(_Fields field, Object value) {
      switch (field) {
      case AUTHZ_TOKEN:
        if (value == null) {
          unsetAuthzToken();
        } else {
          setAuthzToken((org.apache.airavata.model.security.AuthzToken)value);
        }
        break;

      case WORKFLOW_TEMPLATE_ID:
        if (value == null) {
          unsetWorkflowTemplateId();
        } else {
          setWorkflowTemplateId((String)value);
        }
        break;

      }
    }

    public Object getFieldValue(_Fields field) {
      switch (field) {
      case AUTHZ_TOKEN:
        return getAuthzToken();

      case WORKFLOW_TEMPLATE_ID:
        return getWorkflowTemplateId();

      }
      throw new IllegalStateException();
    }

    /** Returns true if field corresponding to fieldID is set (has been assigned a value) and false otherwise */
    public boolean isSet(_Fields field) {
      if (field == null) {
        throw new IllegalArgumentException();
      }

      switch (field) {
      case AUTHZ_TOKEN:
        return isSetAuthzToken();
      case WORKFLOW_TEMPLATE_ID:
        return isSetWorkflowTemplateId();
      }
      throw new IllegalStateException();
    }

    @Override
    public boolean equals(Object that) {
      if (that == null)
        return false;
      if (that instanceof getWorkflow_args)
        return this.equals((getWorkflow_args)that);
      return false;
    }

    public boolean equals(getWorkflow_args that) {
      if (that == null)
        return false;

      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_workflowTemplateId = true && this.isSetWorkflowTemplateId();
      boolean that_present_workflowTemplateId = true && that.isSetWorkflowTemplateId();
      if (this_present_workflowTemplateId || that_present_workflowTemplateId) {
        if (!(this_present_workflowTemplateId && that_present_workflowTemplateId))
          return false;
        if (!this.workflowTemplateId.equals(that.workflowTemplateId))
          return false;
      }

      return true;
    }

    @Override
    public int hashCode() {
      List<Object> list = new ArrayList<Object>();

      boolean present_authzToken = true && (isSetAuthzToken());
      list.add(present_authzToken);
      if (present_authzToken)
        list.add(authzToken);

      boolean present_workflowTemplateId = true && (isSetWorkflowTemplateId());
      list.add(present_workflowTemplateId);
      if (present_workflowTemplateId)
        list.add(workflowTemplateId);

      return list.hashCode();
    }

    @Override
    public int compareTo(getWorkflow_args other) {
      if (!getClass().equals(other.getClass())) {
        return getClass().getName().compareTo(other.getClass().getName());
      }

      int lastComparison = 0;

      lastComparison = 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 = Boolean.valueOf(isSetWorkflowTemplateId()).compareTo(other.isSetWorkflowTemplateId());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetWorkflowTemplateId()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.workflowTemplateId, other.workflowTemplateId);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      return 0;
    }

    public _Fields fieldForId(int fieldId) {
      return _Fields.findByThriftId(fieldId);
    }

    public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
      schemes.get(iprot.getScheme()).getScheme().read(iprot, this);
    }

    public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException {
      schemes.get(oprot.getScheme()).getScheme().write(oprot, this);
    }

    @Override
    public String toString() {
      StringBuilder sb = new StringBuilder("getWorkflow_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("workflowTemplateId:");
      if (this.workflowTemplateId == null) {
        sb.append("null");
      } else {
        sb.append(this.workflowTemplateId);
      }
      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 (workflowTemplateId == null) {
        throw new org.apache.thrift.protocol.TProtocolException("Required field 'workflowTemplateId' 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, 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 getWorkflow_argsStandardSchemeFactory implements SchemeFactory {
      public getWorkflow_argsStandardScheme getScheme() {
        return new getWorkflow_argsStandardScheme();
      }
    }

    private static class getWorkflow_argsStandardScheme extends StandardScheme<getWorkflow_args> {

      public void read(org.apache.thrift.protocol.TProtocol iprot, getWorkflow_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: // WORKFLOW_TEMPLATE_ID
              if (schemeField.type == org.apache.thrift.protocol.TType.STRING) {
                struct.workflowTemplateId = iprot.readString();
                struct.setWorkflowTemplateIdIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            default:
              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
          }
          iprot.readFieldEnd();
        }
        iprot.readStructEnd();

        // check for required fields of primitive type, which can't be checked in the validate method
        struct.validate();
      }

      public void write(org.apache.thrift.protocol.TProtocol oprot, getWorkflow_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.workflowTemplateId != null) {
          oprot.writeFieldBegin(WORKFLOW_TEMPLATE_ID_FIELD_DESC);
          oprot.writeString(struct.workflowTemplateId);
          oprot.writeFieldEnd();
        }
        oprot.writeFieldStop();
        oprot.writeStructEnd();
      }

    }

    private static class getWorkflow_argsTupleSchemeFactory implements SchemeFactory {
      public getWorkflow_argsTupleScheme getScheme() {
        return new getWorkflow_argsTupleScheme();
      }
    }

    private static class getWorkflow_argsTupleScheme extends TupleScheme<getWorkflow_args> {

      @Override
      public void write(org.apache.thrift.protocol.TProtocol prot, getWorkflow_args struct) throws org.apache.thrift.TException {
        TTupleProtocol oprot = (TTupleProtocol) prot;
        struct.authzToken.write(oprot);
        oprot.writeString(struct.workflowTemplateId);
      }

      @Override
      public void read(org.apache.thrift.protocol.TProtocol prot, getWorkflow_args struct) throws org.apache.thrift.TException {
        TTupleProtocol iprot = (TTupleProtocol) prot;
        struct.authzToken = new org.apache.airavata.model.security.AuthzToken();
        struct.authzToken.read(iprot);
        struct.setAuthzTokenIsSet(true);
        struct.workflowTemplateId = iprot.readString();
        struct.setWorkflowTemplateIdIsSet(true);
      }
    }

  }

  public static class getWorkflow_result implements org.apache.thrift.TBase<getWorkflow_result, getWorkflow_result._Fields>, java.io.Serializable, Cloneable, Comparable<getWorkflow_result>   {
    private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("getWorkflow_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 IRE_FIELD_DESC = new org.apache.thrift.protocol.TField("ire", org.apache.thrift.protocol.TType.STRUCT, (short)1);
    private static final org.apache.thrift.protocol.TField ACE_FIELD_DESC = new org.apache.thrift.protocol.TField("ace", org.apache.thrift.protocol.TType.STRUCT, (short)2);
    private static final org.apache.thrift.protocol.TField ASE_FIELD_DESC = new org.apache.thrift.protocol.TField("ase", org.apache.thrift.protocol.TType.STRUCT, (short)3);
    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)4);

    private static final Map<Class<? extends IScheme>, SchemeFactory> schemes = new HashMap<Class<? extends IScheme>, SchemeFactory>();
    static {
      schemes.put(StandardScheme.class, new getWorkflow_resultStandardSchemeFactory());
      schemes.put(TupleScheme.class, new getWorkflow_resultTupleSchemeFactory());
    }

    public org.apache.airavata.model.Workflow success; // required
    public org.apache.airavata.model.error.InvalidRequestException ire; // required
    public org.apache.airavata.model.error.AiravataClientException ace; // required
    public org.apache.airavata.model.error.AiravataSystemException ase; // 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"),
      IRE((short)1, "ire"),
      ACE((short)2, "ace"),
      ASE((short)3, "ase"),
      AE((short)4, "ae");

      private static final Map<String, _Fields> byName = new HashMap<String, _Fields>();

      static {
        for (_Fields field : EnumSet.allOf(_Fields.class)) {
          byName.put(field.getFieldName(), field);
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, or null if its not found.
       */
      public static _Fields findByThriftId(int fieldId) {
        switch(fieldId) {
          case 0: // SUCCESS
            return SUCCESS;
          case 1: // IRE
            return IRE;
          case 2: // ACE
            return ACE;
          case 3: // ASE
            return ASE;
          case 4: // 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 IllegalArgumentException("Field " + fieldId + " doesn't exist!");
        return fields;
      }

      /**
       * Find the _Fields constant that matches name, or null if its not found.
       */
      public static _Fields findByName(String name) {
        return byName.get(name);
      }

      private final short _thriftId;
      private final String _fieldName;

      _Fields(short thriftId, String fieldName) {
        _thriftId = thriftId;
        _fieldName = fieldName;
      }

      public short getThriftFieldId() {
        return _thriftId;
      }

      public String getFieldName() {
        return _fieldName;
      }
    }

    // isset id assignments
    public static final Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
    static {
      Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new EnumMap<_Fields, org.apache.thrift.meta_data.FieldMetaData>(_Fields.class);
      tmpMap.put(_Fields.SUCCESS, new org.apache.thrift.meta_data.FieldMetaData("success", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.StructMetaData(org.apache.thrift.protocol.TType.STRUCT, org.apache.airavata.model.Workflow.class)));
      tmpMap.put(_Fields.IRE, new org.apache.thrift.meta_data.FieldMetaData("ire", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRUCT)));
      tmpMap.put(_Fields.ACE, new org.apache.thrift.meta_data.FieldMetaData("ace", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRUCT)));
      tmpMap.put(_Fields.ASE, new org.apache.thrift.meta_data.FieldMetaData("ase", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRUCT)));
      tmpMap.put(_Fields.AE, new org.apache.thrift.meta_data.FieldMetaData("ae", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRUCT)));
      metaDataMap = Collections.unmodifiableMap(tmpMap);
      org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(getWorkflow_result.class, metaDataMap);
    }

    public getWorkflow_result() {
    }

    public getWorkflow_result(
      org.apache.airavata.model.Workflow success,
      org.apache.airavata.model.error.InvalidRequestException ire,
      org.apache.airavata.model.error.AiravataClientException ace,
      org.apache.airavata.model.error.AiravataSystemException ase,
      org.apache.airavata.model.error.AuthorizationException ae)
    {
      this();
      this.success = success;
      this.ire = ire;
      this.ace = ace;
      this.ase = ase;
      this.ae = ae;
    }

    /**
     * Performs a deep copy on <i>other</i>.
     */
    public getWorkflow_result(getWorkflow_result other) {
      if (other.isSetSuccess()) {
        this.success = new org.apache.airavata.model.Workflow(other.success);
      }
      if (other.isSetIre()) {
        this.ire = new org.apache.airavata.model.error.InvalidRequestException(other.ire);
      }
      if (other.isSetAce()) {
        this.ace = new org.apache.airavata.model.error.AiravataClientException(other.ace);
      }
      if (other.isSetAse()) {
        this.ase = new org.apache.airavata.model.error.AiravataSystemException(other.ase);
      }
      if (other.isSetAe()) {
        this.ae = new org.apache.airavata.model.error.AuthorizationException(other.ae);
      }
    }

    public getWorkflow_result deepCopy() {
      return new getWorkflow_result(this);
    }

    @Override
    public void clear() {
      this.success = null;
      this.ire = null;
      this.ace = null;
      this.ase = null;
      this.ae = null;
    }

    public org.apache.airavata.model.Workflow getSuccess() {
      return this.success;
    }

    public getWorkflow_result setSuccess(org.apache.airavata.model.Workflow 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.model.error.InvalidRequestException getIre() {
      return this.ire;
    }

    public getWorkflow_result setIre(org.apache.airavata.model.error.InvalidRequestException ire) {
      this.ire = ire;
      return this;
    }

    public void unsetIre() {
      this.ire = null;
    }

    /** Returns true if field ire is set (has been assigned a value) and false otherwise */
    public boolean isSetIre() {
      return this.ire != null;
    }

    public void setIreIsSet(boolean value) {
      if (!value) {
        this.ire = null;
      }
    }

    public org.apache.airavata.model.error.AiravataClientException getAce() {
      return this.ace;
    }

    public getWorkflow_result setAce(org.apache.airavata.model.error.AiravataClientException ace) {
      this.ace = ace;
      return this;
    }

    public void unsetAce() {
      this.ace = null;
    }

    /** Returns true if field ace is set (has been assigned a value) and false otherwise */
    public boolean isSetAce() {
      return this.ace != null;
    }

    public void setAceIsSet(boolean value) {
      if (!value) {
        this.ace = null;
      }
    }

    public org.apache.airavata.model.error.AiravataSystemException getAse() {
      return this.ase;
    }

    public getWorkflow_result setAse(org.apache.airavata.model.error.AiravataSystemException ase) {
      this.ase = ase;
      return this;
    }

    public void unsetAse() {
      this.ase = null;
    }

    /** Returns true if field ase is set (has been assigned a value) and false otherwise */
    public boolean isSetAse() {
      return this.ase != null;
    }

    public void setAseIsSet(boolean value) {
      if (!value) {
        this.ase = null;
      }
    }

    public org.apache.airavata.model.error.AuthorizationException getAe() {
      return this.ae;
    }

    public getWorkflow_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, Object value) {
      switch (field) {
      case SUCCESS:
        if (value == null) {
          unsetSuccess();
        } else {
          setSuccess((org.apache.airavata.model.Workflow)value);
        }
        break;

      case IRE:
        if (value == null) {
          unsetIre();
        } else {
          setIre((org.apache.airavata.model.error.InvalidRequestException)value);
        }
        break;

      case ACE:
        if (value == null) {
          unsetAce();
        } else {
          setAce((org.apache.airavata.model.error.AiravataClientException)value);
        }
        break;

      case ASE:
        if (value == null) {
          unsetAse();
        } else {
          setAse((org.apache.airavata.model.error.AiravataSystemException)value);
        }
        break;

      case AE:
        if (value == null) {
          unsetAe();
        } else {
          setAe((org.apache.airavata.model.error.AuthorizationException)value);
        }
        break;

      }
    }

    public Object getFieldValue(_Fields field) {
      switch (field) {
      case SUCCESS:
        return getSuccess();

      case IRE:
        return getIre();

      case ACE:
        return getAce();

      case ASE:
        return getAse();

      case AE:
        return getAe();

      }
      throw new IllegalStateException();
    }

    /** Returns true if field corresponding to fieldID is set (has been assigned a value) and false otherwise */
    public boolean isSet(_Fields field) {
      if (field == null) {
        throw new IllegalArgumentException();
      }

      switch (field) {
      case SUCCESS:
        return isSetSuccess();
      case IRE:
        return isSetIre();
      case ACE:
        return isSetAce();
      case ASE:
        return isSetAse();
      case AE:
        return isSetAe();
      }
      throw new IllegalStateException();
    }

    @Override
    public boolean equals(Object that) {
      if (that == null)
        return false;
      if (that instanceof getWorkflow_result)
        return this.equals((getWorkflow_result)that);
      return false;
    }

    public boolean equals(getWorkflow_result that) {
      if (that == null)
        return false;

      boolean this_present_success = true && this.isSetSuccess();
      boolean that_present_success = true && that.isSetSuccess();
      if (this_present_success || that_present_success) {
        if (!(this_present_success && that_present_success))
          return false;
        if (!this.success.equals(that.success))
          return false;
      }

      boolean this_present_ire = true && this.isSetIre();
      boolean that_present_ire = true && that.isSetIre();
      if (this_present_ire || that_present_ire) {
        if (!(this_present_ire && that_present_ire))
          return false;
        if (!this.ire.equals(that.ire))
          return false;
      }

      boolean this_present_ace = true && this.isSetAce();
      boolean that_present_ace = true && that.isSetAce();
      if (this_present_ace || that_present_ace) {
        if (!(this_present_ace && that_present_ace))
          return false;
        if (!this.ace.equals(that.ace))
          return false;
      }

      boolean this_present_ase = true && this.isSetAse();
      boolean that_present_ase = true && that.isSetAse();
      if (this_present_ase || that_present_ase) {
        if (!(this_present_ase && that_present_ase))
          return false;
        if (!this.ase.equals(that.ase))
          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() {
      List<Object> list = new ArrayList<Object>();

      boolean present_success = true && (isSetSuccess());
      list.add(present_success);
      if (present_success)
        list.add(success);

      boolean present_ire = true && (isSetIre());
      list.add(present_ire);
      if (present_ire)
        list.add(ire);

      boolean present_ace = true && (isSetAce());
      list.add(present_ace);
      if (present_ace)
        list.add(ace);

      boolean present_ase = true && (isSetAse());
      list.add(present_ase);
      if (present_ase)
        list.add(ase);

      boolean present_ae = true && (isSetAe());
      list.add(present_ae);
      if (present_ae)
        list.add(ae);

      return list.hashCode();
    }

    @Override
    public int compareTo(getWorkflow_result other) {
      if (!getClass().equals(other.getClass())) {
        return getClass().getName().compareTo(other.getClass().getName());
      }

      int lastComparison = 0;

      lastComparison = Boolean.valueOf(isSetSuccess()).compareTo(other.isSetSuccess());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetSuccess()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.success, other.success);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = Boolean.valueOf(isSetIre()).compareTo(other.isSetIre());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetIre()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.ire, other.ire);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = Boolean.valueOf(isSetAce()).compareTo(other.isSetAce());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetAce()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.ace, other.ace);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = Boolean.valueOf(isSetAse()).compareTo(other.isSetAse());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetAse()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.ase, other.ase);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = 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 {
      schemes.get(iprot.getScheme()).getScheme().read(iprot, this);
    }

    public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException {
      schemes.get(oprot.getScheme()).getScheme().write(oprot, this);
      }

    @Override
    public String toString() {
      StringBuilder sb = new StringBuilder("getWorkflow_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("ire:");
      if (this.ire == null) {
        sb.append("null");
      } else {
        sb.append(this.ire);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("ace:");
      if (this.ace == null) {
        sb.append("null");
      } else {
        sb.append(this.ace);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("ase:");
      if (this.ase == null) {
        sb.append("null");
      } else {
        sb.append(this.ase);
      }
      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, 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 getWorkflow_resultStandardSchemeFactory implements SchemeFactory {
      public getWorkflow_resultStandardScheme getScheme() {
        return new getWorkflow_resultStandardScheme();
      }
    }

    private static class getWorkflow_resultStandardScheme extends StandardScheme<getWorkflow_result> {

      public void read(org.apache.thrift.protocol.TProtocol iprot, getWorkflow_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.Workflow();
                struct.success.read(iprot);
                struct.setSuccessIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 1: // IRE
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.ire = new org.apache.airavata.model.error.InvalidRequestException();
                struct.ire.read(iprot);
                struct.setIreIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 2: // ACE
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.ace = new org.apache.airavata.model.error.AiravataClientException();
                struct.ace.read(iprot);
                struct.setAceIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 3: // ASE
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.ase = new org.apache.airavata.model.error.AiravataSystemException();
                struct.ase.read(iprot);
                struct.setAseIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 4: // 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, getWorkflow_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.ire != null) {
          oprot.writeFieldBegin(IRE_FIELD_DESC);
          struct.ire.write(oprot);
          oprot.writeFieldEnd();
        }
        if (struct.ace != null) {
          oprot.writeFieldBegin(ACE_FIELD_DESC);
          struct.ace.write(oprot);
          oprot.writeFieldEnd();
        }
        if (struct.ase != null) {
          oprot.writeFieldBegin(ASE_FIELD_DESC);
          struct.ase.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 getWorkflow_resultTupleSchemeFactory implements SchemeFactory {
      public getWorkflow_resultTupleScheme getScheme() {
        return new getWorkflow_resultTupleScheme();
      }
    }

    private static class getWorkflow_resultTupleScheme extends TupleScheme<getWorkflow_result> {

      @Override
      public void write(org.apache.thrift.protocol.TProtocol prot, getWorkflow_result struct) throws org.apache.thrift.TException {
        TTupleProtocol oprot = (TTupleProtocol) prot;
        BitSet optionals = new BitSet();
        if (struct.isSetSuccess()) {
          optionals.set(0);
        }
        if (struct.isSetIre()) {
          optionals.set(1);
        }
        if (struct.isSetAce()) {
          optionals.set(2);
        }
        if (struct.isSetAse()) {
          optionals.set(3);
        }
        if (struct.isSetAe()) {
          optionals.set(4);
        }
        oprot.writeBitSet(optionals, 5);
        if (struct.isSetSuccess()) {
          struct.success.write(oprot);
        }
        if (struct.isSetIre()) {
          struct.ire.write(oprot);
        }
        if (struct.isSetAce()) {
          struct.ace.write(oprot);
        }
        if (struct.isSetAse()) {
          struct.ase.write(oprot);
        }
        if (struct.isSetAe()) {
          struct.ae.write(oprot);
        }
      }

      @Override
      public void read(org.apache.thrift.protocol.TProtocol prot, getWorkflow_result struct) throws org.apache.thrift.TException {
        TTupleProtocol iprot = (TTupleProtocol) prot;
        BitSet incoming = iprot.readBitSet(5);
        if (incoming.get(0)) {
          struct.success = new org.apache.airavata.model.Workflow();
          struct.success.read(iprot);
          struct.setSuccessIsSet(true);
        }
        if (incoming.get(1)) {
          struct.ire = new org.apache.airavata.model.error.InvalidRequestException();
          struct.ire.read(iprot);
          struct.setIreIsSet(true);
        }
        if (incoming.get(2)) {
          struct.ace = new org.apache.airavata.model.error.AiravataClientException();
          struct.ace.read(iprot);
          struct.setAceIsSet(true);
        }
        if (incoming.get(3)) {
          struct.ase = new org.apache.airavata.model.error.AiravataSystemException();
          struct.ase.read(iprot);
          struct.setAseIsSet(true);
        }
        if (incoming.get(4)) {
          struct.ae = new org.apache.airavata.model.error.AuthorizationException();
          struct.ae.read(iprot);
          struct.setAeIsSet(true);
        }
      }
    }

  }

  public static class deleteWorkflow_args implements org.apache.thrift.TBase<deleteWorkflow_args, deleteWorkflow_args._Fields>, java.io.Serializable, Cloneable, Comparable<deleteWorkflow_args>   {
    private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("deleteWorkflow_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 WORKFLOW_TEMPLATE_ID_FIELD_DESC = new org.apache.thrift.protocol.TField("workflowTemplateId", org.apache.thrift.protocol.TType.STRING, (short)2);

    private static final Map<Class<? extends IScheme>, SchemeFactory> schemes = new HashMap<Class<? extends IScheme>, SchemeFactory>();
    static {
      schemes.put(StandardScheme.class, new deleteWorkflow_argsStandardSchemeFactory());
      schemes.put(TupleScheme.class, new deleteWorkflow_argsTupleSchemeFactory());
    }

    public org.apache.airavata.model.security.AuthzToken authzToken; // required
    public String workflowTemplateId; // required

    /** 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"),
      WORKFLOW_TEMPLATE_ID((short)2, "workflowTemplateId");

      private static final Map<String, _Fields> byName = new HashMap<String, _Fields>();

      static {
        for (_Fields field : EnumSet.allOf(_Fields.class)) {
          byName.put(field.getFieldName(), field);
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, or null if its not found.
       */
      public static _Fields findByThriftId(int fieldId) {
        switch(fieldId) {
          case 1: // AUTHZ_TOKEN
            return AUTHZ_TOKEN;
          case 2: // WORKFLOW_TEMPLATE_ID
            return WORKFLOW_TEMPLATE_ID;
          default:
            return null;
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, throwing an exception
       * if it is not found.
       */
      public static _Fields findByThriftIdOrThrow(int fieldId) {
        _Fields fields = findByThriftId(fieldId);
        if (fields == null) throw new IllegalArgumentException("Field " + fieldId + " doesn't exist!");
        return fields;
      }

      /**
       * Find the _Fields constant that matches name, or null if its not found.
       */
      public static _Fields findByName(String name) {
        return byName.get(name);
      }

      private final short _thriftId;
      private final String _fieldName;

      _Fields(short thriftId, String fieldName) {
        _thriftId = thriftId;
        _fieldName = fieldName;
      }

      public short getThriftFieldId() {
        return _thriftId;
      }

      public String getFieldName() {
        return _fieldName;
      }
    }

    // isset id assignments
    public static final Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
    static {
      Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new EnumMap<_Fields, org.apache.thrift.meta_data.FieldMetaData>(_Fields.class);
      tmpMap.put(_Fields.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.WORKFLOW_TEMPLATE_ID, new org.apache.thrift.meta_data.FieldMetaData("workflowTemplateId", org.apache.thrift.TFieldRequirementType.REQUIRED, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING)));
      metaDataMap = Collections.unmodifiableMap(tmpMap);
      org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(deleteWorkflow_args.class, metaDataMap);
    }

    public deleteWorkflow_args() {
    }

    public deleteWorkflow_args(
      org.apache.airavata.model.security.AuthzToken authzToken,
      String workflowTemplateId)
    {
      this();
      this.authzToken = authzToken;
      this.workflowTemplateId = workflowTemplateId;
    }

    /**
     * Performs a deep copy on <i>other</i>.
     */
    public deleteWorkflow_args(deleteWorkflow_args other) {
      if (other.isSetAuthzToken()) {
        this.authzToken = new org.apache.airavata.model.security.AuthzToken(other.authzToken);
      }
      if (other.isSetWorkflowTemplateId()) {
        this.workflowTemplateId = other.workflowTemplateId;
      }
    }

    public deleteWorkflow_args deepCopy() {
      return new deleteWorkflow_args(this);
    }

    @Override
    public void clear() {
      this.authzToken = null;
      this.workflowTemplateId = null;
    }

    public org.apache.airavata.model.security.AuthzToken getAuthzToken() {
      return this.authzToken;
    }

    public deleteWorkflow_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 String getWorkflowTemplateId() {
      return this.workflowTemplateId;
    }

    public deleteWorkflow_args setWorkflowTemplateId(String workflowTemplateId) {
      this.workflowTemplateId = workflowTemplateId;
      return this;
    }

    public void unsetWorkflowTemplateId() {
      this.workflowTemplateId = null;
    }

    /** Returns true if field workflowTemplateId is set (has been assigned a value) and false otherwise */
    public boolean isSetWorkflowTemplateId() {
      return this.workflowTemplateId != null;
    }

    public void setWorkflowTemplateIdIsSet(boolean value) {
      if (!value) {
        this.workflowTemplateId = null;
      }
    }

    public void setFieldValue(_Fields field, Object value) {
      switch (field) {
      case AUTHZ_TOKEN:
        if (value == null) {
          unsetAuthzToken();
        } else {
          setAuthzToken((org.apache.airavata.model.security.AuthzToken)value);
        }
        break;

      case WORKFLOW_TEMPLATE_ID:
        if (value == null) {
          unsetWorkflowTemplateId();
        } else {
          setWorkflowTemplateId((String)value);
        }
        break;

      }
    }

    public Object getFieldValue(_Fields field) {
      switch (field) {
      case AUTHZ_TOKEN:
        return getAuthzToken();

      case WORKFLOW_TEMPLATE_ID:
        return getWorkflowTemplateId();

      }
      throw new IllegalStateException();
    }

    /** Returns true if field corresponding to fieldID is set (has been assigned a value) and false otherwise */
    public boolean isSet(_Fields field) {
      if (field == null) {
        throw new IllegalArgumentException();
      }

      switch (field) {
      case AUTHZ_TOKEN:
        return isSetAuthzToken();
      case WORKFLOW_TEMPLATE_ID:
        return isSetWorkflowTemplateId();
      }
      throw new IllegalStateException();
    }

    @Override
    public boolean equals(Object that) {
      if (that == null)
        return false;
      if (that instanceof deleteWorkflow_args)
        return this.equals((deleteWorkflow_args)that);
      return false;
    }

    public boolean equals(deleteWorkflow_args that) {
      if (that == null)
        return false;

      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_workflowTemplateId = true && this.isSetWorkflowTemplateId();
      boolean that_present_workflowTemplateId = true && that.isSetWorkflowTemplateId();
      if (this_present_workflowTemplateId || that_present_workflowTemplateId) {
        if (!(this_present_workflowTemplateId && that_present_workflowTemplateId))
          return false;
        if (!this.workflowTemplateId.equals(that.workflowTemplateId))
          return false;
      }

      return true;
    }

    @Override
    public int hashCode() {
      List<Object> list = new ArrayList<Object>();

      boolean present_authzToken = true && (isSetAuthzToken());
      list.add(present_authzToken);
      if (present_authzToken)
        list.add(authzToken);

      boolean present_workflowTemplateId = true && (isSetWorkflowTemplateId());
      list.add(present_workflowTemplateId);
      if (present_workflowTemplateId)
        list.add(workflowTemplateId);

      return list.hashCode();
    }

    @Override
    public int compareTo(deleteWorkflow_args other) {
      if (!getClass().equals(other.getClass())) {
        return getClass().getName().compareTo(other.getClass().getName());
      }

      int lastComparison = 0;

      lastComparison = 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 = Boolean.valueOf(isSetWorkflowTemplateId()).compareTo(other.isSetWorkflowTemplateId());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetWorkflowTemplateId()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.workflowTemplateId, other.workflowTemplateId);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      return 0;
    }

    public _Fields fieldForId(int fieldId) {
      return _Fields.findByThriftId(fieldId);
    }

    public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
      schemes.get(iprot.getScheme()).getScheme().read(iprot, this);
    }

    public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException {
      schemes.get(oprot.getScheme()).getScheme().write(oprot, this);
    }

    @Override
    public String toString() {
      StringBuilder sb = new StringBuilder("deleteWorkflow_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("workflowTemplateId:");
      if (this.workflowTemplateId == null) {
        sb.append("null");
      } else {
        sb.append(this.workflowTemplateId);
      }
      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 (workflowTemplateId == null) {
        throw new org.apache.thrift.protocol.TProtocolException("Required field 'workflowTemplateId' 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, 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 deleteWorkflow_argsStandardSchemeFactory implements SchemeFactory {
      public deleteWorkflow_argsStandardScheme getScheme() {
        return new deleteWorkflow_argsStandardScheme();
      }
    }

    private static class deleteWorkflow_argsStandardScheme extends StandardScheme<deleteWorkflow_args> {

      public void read(org.apache.thrift.protocol.TProtocol iprot, deleteWorkflow_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: // WORKFLOW_TEMPLATE_ID
              if (schemeField.type == org.apache.thrift.protocol.TType.STRING) {
                struct.workflowTemplateId = iprot.readString();
                struct.setWorkflowTemplateIdIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            default:
              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
          }
          iprot.readFieldEnd();
        }
        iprot.readStructEnd();

        // check for required fields of primitive type, which can't be checked in the validate method
        struct.validate();
      }

      public void write(org.apache.thrift.protocol.TProtocol oprot, deleteWorkflow_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.workflowTemplateId != null) {
          oprot.writeFieldBegin(WORKFLOW_TEMPLATE_ID_FIELD_DESC);
          oprot.writeString(struct.workflowTemplateId);
          oprot.writeFieldEnd();
        }
        oprot.writeFieldStop();
        oprot.writeStructEnd();
      }

    }

    private static class deleteWorkflow_argsTupleSchemeFactory implements SchemeFactory {
      public deleteWorkflow_argsTupleScheme getScheme() {
        return new deleteWorkflow_argsTupleScheme();
      }
    }

    private static class deleteWorkflow_argsTupleScheme extends TupleScheme<deleteWorkflow_args> {

      @Override
      public void write(org.apache.thrift.protocol.TProtocol prot, deleteWorkflow_args struct) throws org.apache.thrift.TException {
        TTupleProtocol oprot = (TTupleProtocol) prot;
        struct.authzToken.write(oprot);
        oprot.writeString(struct.workflowTemplateId);
      }

      @Override
      public void read(org.apache.thrift.protocol.TProtocol prot, deleteWorkflow_args struct) throws org.apache.thrift.TException {
        TTupleProtocol iprot = (TTupleProtocol) prot;
        struct.authzToken = new org.apache.airavata.model.security.AuthzToken();
        struct.authzToken.read(iprot);
        struct.setAuthzTokenIsSet(true);
        struct.workflowTemplateId = iprot.readString();
        struct.setWorkflowTemplateIdIsSet(true);
      }
    }

  }

  public static class deleteWorkflow_result implements org.apache.thrift.TBase<deleteWorkflow_result, deleteWorkflow_result._Fields>, java.io.Serializable, Cloneable, Comparable<deleteWorkflow_result>   {
    private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("deleteWorkflow_result");

    private static final org.apache.thrift.protocol.TField IRE_FIELD_DESC = new org.apache.thrift.protocol.TField("ire", org.apache.thrift.protocol.TType.STRUCT, (short)1);
    private static final org.apache.thrift.protocol.TField ACE_FIELD_DESC = new org.apache.thrift.protocol.TField("ace", org.apache.thrift.protocol.TType.STRUCT, (short)2);
    private static final org.apache.thrift.protocol.TField ASE_FIELD_DESC = new org.apache.thrift.protocol.TField("ase", org.apache.thrift.protocol.TType.STRUCT, (short)3);
    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)4);

    private static final Map<Class<? extends IScheme>, SchemeFactory> schemes = new HashMap<Class<? extends IScheme>, SchemeFactory>();
    static {
      schemes.put(StandardScheme.class, new deleteWorkflow_resultStandardSchemeFactory());
      schemes.put(TupleScheme.class, new deleteWorkflow_resultTupleSchemeFactory());
    }

    public org.apache.airavata.model.error.InvalidRequestException ire; // required
    public org.apache.airavata.model.error.AiravataClientException ace; // required
    public org.apache.airavata.model.error.AiravataSystemException ase; // 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 {
      IRE((short)1, "ire"),
      ACE((short)2, "ace"),
      ASE((short)3, "ase"),
      AE((short)4, "ae");

      private static final Map<String, _Fields> byName = new HashMap<String, _Fields>();

      static {
        for (_Fields field : EnumSet.allOf(_Fields.class)) {
          byName.put(field.getFieldName(), field);
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, or null if its not found.
       */
      public static _Fields findByThriftId(int fieldId) {
        switch(fieldId) {
          case 1: // IRE
            return IRE;
          case 2: // ACE
            return ACE;
          case 3: // ASE
            return ASE;
          case 4: // 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 IllegalArgumentException("Field " + fieldId + " doesn't exist!");
        return fields;
      }

      /**
       * Find the _Fields constant that matches name, or null if its not found.
       */
      public static _Fields findByName(String name) {
        return byName.get(name);
      }

      private final short _thriftId;
      private final String _fieldName;

      _Fields(short thriftId, String fieldName) {
        _thriftId = thriftId;
        _fieldName = fieldName;
      }

      public short getThriftFieldId() {
        return _thriftId;
      }

      public String getFieldName() {
        return _fieldName;
      }
    }

    // isset id assignments
    public static final Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
    static {
      Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new EnumMap<_Fields, org.apache.thrift.meta_data.FieldMetaData>(_Fields.class);
      tmpMap.put(_Fields.IRE, new org.apache.thrift.meta_data.FieldMetaData("ire", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRUCT)));
      tmpMap.put(_Fields.ACE, new org.apache.thrift.meta_data.FieldMetaData("ace", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRUCT)));
      tmpMap.put(_Fields.ASE, new org.apache.thrift.meta_data.FieldMetaData("ase", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRUCT)));
      tmpMap.put(_Fields.AE, new org.apache.thrift.meta_data.FieldMetaData("ae", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRUCT)));
      metaDataMap = Collections.unmodifiableMap(tmpMap);
      org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(deleteWorkflow_result.class, metaDataMap);
    }

    public deleteWorkflow_result() {
    }

    public deleteWorkflow_result(
      org.apache.airavata.model.error.InvalidRequestException ire,
      org.apache.airavata.model.error.AiravataClientException ace,
      org.apache.airavata.model.error.AiravataSystemException ase,
      org.apache.airavata.model.error.AuthorizationException ae)
    {
      this();
      this.ire = ire;
      this.ace = ace;
      this.ase = ase;
      this.ae = ae;
    }

    /**
     * Performs a deep copy on <i>other</i>.
     */
    public deleteWorkflow_result(deleteWorkflow_result other) {
      if (other.isSetIre()) {
        this.ire = new org.apache.airavata.model.error.InvalidRequestException(other.ire);
      }
      if (other.isSetAce()) {
        this.ace = new org.apache.airavata.model.error.AiravataClientException(other.ace);
      }
      if (other.isSetAse()) {
        this.ase = new org.apache.airavata.model.error.AiravataSystemException(other.ase);
      }
      if (other.isSetAe()) {
        this.ae = new org.apache.airavata.model.error.AuthorizationException(other.ae);
      }
    }

    public deleteWorkflow_result deepCopy() {
      return new deleteWorkflow_result(this);
    }

    @Override
    public void clear() {
      this.ire = null;
      this.ace = null;
      this.ase = null;
      this.ae = null;
    }

    public org.apache.airavata.model.error.InvalidRequestException getIre() {
      return this.ire;
    }

    public deleteWorkflow_result setIre(org.apache.airavata.model.error.InvalidRequestException ire) {
      this.ire = ire;
      return this;
    }

    public void unsetIre() {
      this.ire = null;
    }

    /** Returns true if field ire is set (has been assigned a value) and false otherwise */
    public boolean isSetIre() {
      return this.ire != null;
    }

    public void setIreIsSet(boolean value) {
      if (!value) {
        this.ire = null;
      }
    }

    public org.apache.airavata.model.error.AiravataClientException getAce() {
      return this.ace;
    }

    public deleteWorkflow_result setAce(org.apache.airavata.model.error.AiravataClientException ace) {
      this.ace = ace;
      return this;
    }

    public void unsetAce() {
      this.ace = null;
    }

    /** Returns true if field ace is set (has been assigned a value) and false otherwise */
    public boolean isSetAce() {
      return this.ace != null;
    }

    public void setAceIsSet(boolean value) {
      if (!value) {
        this.ace = null;
      }
    }

    public org.apache.airavata.model.error.AiravataSystemException getAse() {
      return this.ase;
    }

    public deleteWorkflow_result setAse(org.apache.airavata.model.error.AiravataSystemException ase) {
      this.ase = ase;
      return this;
    }

    public void unsetAse() {
      this.ase = null;
    }

    /** Returns true if field ase is set (has been assigned a value) and false otherwise */
    public boolean isSetAse() {
      return this.ase != null;
    }

    public void setAseIsSet(boolean value) {
      if (!value) {
        this.ase = null;
      }
    }

    public org.apache.airavata.model.error.AuthorizationException getAe() {
      return this.ae;
    }

    public deleteWorkflow_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, Object value) {
      switch (field) {
      case IRE:
        if (value == null) {
          unsetIre();
        } else {
          setIre((org.apache.airavata.model.error.InvalidRequestException)value);
        }
        break;

      case ACE:
        if (value == null) {
          unsetAce();
        } else {
          setAce((org.apache.airavata.model.error.AiravataClientException)value);
        }
        break;

      case ASE:
        if (value == null) {
          unsetAse();
        } else {
          setAse((org.apache.airavata.model.error.AiravataSystemException)value);
        }
        break;

      case AE:
        if (value == null) {
          unsetAe();
        } else {
          setAe((org.apache.airavata.model.error.AuthorizationException)value);
        }
        break;

      }
    }

    public Object getFieldValue(_Fields field) {
      switch (field) {
      case IRE:
        return getIre();

      case ACE:
        return getAce();

      case ASE:
        return getAse();

      case AE:
        return getAe();

      }
      throw new IllegalStateException();
    }

    /** Returns true if field corresponding to fieldID is set (has been assigned a value) and false otherwise */
    public boolean isSet(_Fields field) {
      if (field == null) {
        throw new IllegalArgumentException();
      }

      switch (field) {
      case IRE:
        return isSetIre();
      case ACE:
        return isSetAce();
      case ASE:
        return isSetAse();
      case AE:
        return isSetAe();
      }
      throw new IllegalStateException();
    }

    @Override
    public boolean equals(Object that) {
      if (that == null)
        return false;
      if (that instanceof deleteWorkflow_result)
        return this.equals((deleteWorkflow_result)that);
      return false;
    }

    public boolean equals(deleteWorkflow_result that) {
      if (that == null)
        return false;

      boolean this_present_ire = true && this.isSetIre();
      boolean that_present_ire = true && that.isSetIre();
      if (this_present_ire || that_present_ire) {
        if (!(this_present_ire && that_present_ire))
          return false;
        if (!this.ire.equals(that.ire))
          return false;
      }

      boolean this_present_ace = true && this.isSetAce();
      boolean that_present_ace = true && that.isSetAce();
      if (this_present_ace || that_present_ace) {
        if (!(this_present_ace && that_present_ace))
          return false;
        if (!this.ace.equals(that.ace))
          return false;
      }

      boolean this_present_ase = true && this.isSetAse();
      boolean that_present_ase = true && that.isSetAse();
      if (this_present_ase || that_present_ase) {
        if (!(this_present_ase && that_present_ase))
          return false;
        if (!this.ase.equals(that.ase))
          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() {
      List<Object> list = new ArrayList<Object>();

      boolean present_ire = true && (isSetIre());
      list.add(present_ire);
      if (present_ire)
        list.add(ire);

      boolean present_ace = true && (isSetAce());
      list.add(present_ace);
      if (present_ace)
        list.add(ace);

      boolean present_ase = true && (isSetAse());
      list.add(present_ase);
      if (present_ase)
        list.add(ase);

      boolean present_ae = true && (isSetAe());
      list.add(present_ae);
      if (present_ae)
        list.add(ae);

      return list.hashCode();
    }

    @Override
    public int compareTo(deleteWorkflow_result other) {
      if (!getClass().equals(other.getClass())) {
        return getClass().getName().compareTo(other.getClass().getName());
      }

      int lastComparison = 0;

      lastComparison = Boolean.valueOf(isSetIre()).compareTo(other.isSetIre());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetIre()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.ire, other.ire);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = Boolean.valueOf(isSetAce()).compareTo(other.isSetAce());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetAce()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.ace, other.ace);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = Boolean.valueOf(isSetAse()).compareTo(other.isSetAse());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetAse()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.ase, other.ase);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = 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 {
      schemes.get(iprot.getScheme()).getScheme().read(iprot, this);
    }

    public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException {
      schemes.get(oprot.getScheme()).getScheme().write(oprot, this);
      }

    @Override
    public String toString() {
      StringBuilder sb = new StringBuilder("deleteWorkflow_result(");
      boolean first = true;

      sb.append("ire:");
      if (this.ire == null) {
        sb.append("null");
      } else {
        sb.append(this.ire);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("ace:");
      if (this.ace == null) {
        sb.append("null");
      } else {
        sb.append(this.ace);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("ase:");
      if (this.ase == null) {
        sb.append("null");
      } else {
        sb.append(this.ase);
      }
      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, 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 deleteWorkflow_resultStandardSchemeFactory implements SchemeFactory {
      public deleteWorkflow_resultStandardScheme getScheme() {
        return new deleteWorkflow_resultStandardScheme();
      }
    }

    private static class deleteWorkflow_resultStandardScheme extends StandardScheme<deleteWorkflow_result> {

      public void read(org.apache.thrift.protocol.TProtocol iprot, deleteWorkflow_result struct) throws org.apache.thrift.TException {
        org.apache.thrift.protocol.TField schemeField;
        iprot.readStructBegin();
        while (true)
        {
          schemeField = iprot.readFieldBegin();
          if (schemeField.type == org.apache.thrift.protocol.TType.STOP) { 
            break;
          }
          switch (schemeField.id) {
            case 1: // IRE
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.ire = new org.apache.airavata.model.error.InvalidRequestException();
                struct.ire.read(iprot);
                struct.setIreIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 2: // ACE
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.ace = new org.apache.airavata.model.error.AiravataClientException();
                struct.ace.read(iprot);
                struct.setAceIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 3: // ASE
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.ase = new org.apache.airavata.model.error.AiravataSystemException();
                struct.ase.read(iprot);
                struct.setAseIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 4: // 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, deleteWorkflow_result struct) throws org.apache.thrift.TException {
        struct.validate();

        oprot.writeStructBegin(STRUCT_DESC);
        if (struct.ire != null) {
          oprot.writeFieldBegin(IRE_FIELD_DESC);
          struct.ire.write(oprot);
          oprot.writeFieldEnd();
        }
        if (struct.ace != null) {
          oprot.writeFieldBegin(ACE_FIELD_DESC);
          struct.ace.write(oprot);
          oprot.writeFieldEnd();
        }
        if (struct.ase != null) {
          oprot.writeFieldBegin(ASE_FIELD_DESC);
          struct.ase.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 deleteWorkflow_resultTupleSchemeFactory implements SchemeFactory {
      public deleteWorkflow_resultTupleScheme getScheme() {
        return new deleteWorkflow_resultTupleScheme();
      }
    }

    private static class deleteWorkflow_resultTupleScheme extends TupleScheme<deleteWorkflow_result> {

      @Override
      public void write(org.apache.thrift.protocol.TProtocol prot, deleteWorkflow_result struct) throws org.apache.thrift.TException {
        TTupleProtocol oprot = (TTupleProtocol) prot;
        BitSet optionals = new BitSet();
        if (struct.isSetIre()) {
          optionals.set(0);
        }
        if (struct.isSetAce()) {
          optionals.set(1);
        }
        if (struct.isSetAse()) {
          optionals.set(2);
        }
        if (struct.isSetAe()) {
          optionals.set(3);
        }
        oprot.writeBitSet(optionals, 4);
        if (struct.isSetIre()) {
          struct.ire.write(oprot);
        }
        if (struct.isSetAce()) {
          struct.ace.write(oprot);
        }
        if (struct.isSetAse()) {
          struct.ase.write(oprot);
        }
        if (struct.isSetAe()) {
          struct.ae.write(oprot);
        }
      }

      @Override
      public void read(org.apache.thrift.protocol.TProtocol prot, deleteWorkflow_result struct) throws org.apache.thrift.TException {
        TTupleProtocol iprot = (TTupleProtocol) prot;
        BitSet incoming = iprot.readBitSet(4);
        if (incoming.get(0)) {
          struct.ire = new org.apache.airavata.model.error.InvalidRequestException();
          struct.ire.read(iprot);
          struct.setIreIsSet(true);
        }
        if (incoming.get(1)) {
          struct.ace = new org.apache.airavata.model.error.AiravataClientException();
          struct.ace.read(iprot);
          struct.setAceIsSet(true);
        }
        if (incoming.get(2)) {
          struct.ase = new org.apache.airavata.model.error.AiravataSystemException();
          struct.ase.read(iprot);
          struct.setAseIsSet(true);
        }
        if (incoming.get(3)) {
          struct.ae = new org.apache.airavata.model.error.AuthorizationException();
          struct.ae.read(iprot);
          struct.setAeIsSet(true);
        }
      }
    }

  }

  public static class registerWorkflow_args implements org.apache.thrift.TBase<registerWorkflow_args, registerWorkflow_args._Fields>, java.io.Serializable, Cloneable, Comparable<registerWorkflow_args>   {
    private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("registerWorkflow_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.protocol.TField WORKFLOW_FIELD_DESC = new org.apache.thrift.protocol.TField("workflow", org.apache.thrift.protocol.TType.STRUCT, (short)3);

    private static final Map<Class<? extends IScheme>, SchemeFactory> schemes = new HashMap<Class<? extends IScheme>, SchemeFactory>();
    static {
      schemes.put(StandardScheme.class, new registerWorkflow_argsStandardSchemeFactory());
      schemes.put(TupleScheme.class, new registerWorkflow_argsTupleSchemeFactory());
    }

    public org.apache.airavata.model.security.AuthzToken authzToken; // required
    public String gatewayId; // required
    public org.apache.airavata.model.Workflow workflow; // required

    /** 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"),
      WORKFLOW((short)3, "workflow");

      private static final Map<String, _Fields> byName = new HashMap<String, _Fields>();

      static {
        for (_Fields field : EnumSet.allOf(_Fields.class)) {
          byName.put(field.getFieldName(), field);
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, or null if its not found.
       */
      public static _Fields findByThriftId(int fieldId) {
        switch(fieldId) {
          case 1: // AUTHZ_TOKEN
            return AUTHZ_TOKEN;
          case 2: // GATEWAY_ID
            return GATEWAY_ID;
          case 3: // WORKFLOW
            return WORKFLOW;
          default:
            return null;
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, throwing an exception
       * if it is not found.
       */
      public static _Fields findByThriftIdOrThrow(int fieldId) {
        _Fields fields = findByThriftId(fieldId);
        if (fields == null) throw new IllegalArgumentException("Field " + fieldId + " doesn't exist!");
        return fields;
      }

      /**
       * Find the _Fields constant that matches name, or null if its not found.
       */
      public static _Fields findByName(String name) {
        return byName.get(name);
      }

      private final short _thriftId;
      private final String _fieldName;

      _Fields(short thriftId, String fieldName) {
        _thriftId = thriftId;
        _fieldName = fieldName;
      }

      public short getThriftFieldId() {
        return _thriftId;
      }

      public String getFieldName() {
        return _fieldName;
      }
    }

    // isset id assignments
    public static final Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
    static {
      Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new EnumMap<_Fields, org.apache.thrift.meta_data.FieldMetaData>(_Fields.class);
      tmpMap.put(_Fields.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)));
      tmpMap.put(_Fields.WORKFLOW, new org.apache.thrift.meta_data.FieldMetaData("workflow", org.apache.thrift.TFieldRequirementType.REQUIRED, 
          new org.apache.thrift.meta_data.StructMetaData(org.apache.thrift.protocol.TType.STRUCT, org.apache.airavata.model.Workflow.class)));
      metaDataMap = Collections.unmodifiableMap(tmpMap);
      org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(registerWorkflow_args.class, metaDataMap);
    }

    public registerWorkflow_args() {
    }

    public registerWorkflow_args(
      org.apache.airavata.model.security.AuthzToken authzToken,
      String gatewayId,
      org.apache.airavata.model.Workflow workflow)
    {
      this();
      this.authzToken = authzToken;
      this.gatewayId = gatewayId;
      this.workflow = workflow;
    }

    /**
     * Performs a deep copy on <i>other</i>.
     */
    public registerWorkflow_args(registerWorkflow_args other) {
      if (other.isSetAuthzToken()) {
        this.authzToken = new org.apache.airavata.model.security.AuthzToken(other.authzToken);
      }
      if (other.isSetGatewayId()) {
        this.gatewayId = other.gatewayId;
      }
      if (other.isSetWorkflow()) {
        this.workflow = new org.apache.airavata.model.Workflow(other.workflow);
      }
    }

    public registerWorkflow_args deepCopy() {
      return new registerWorkflow_args(this);
    }

    @Override
    public void clear() {
      this.authzToken = null;
      this.gatewayId = null;
      this.workflow = null;
    }

    public org.apache.airavata.model.security.AuthzToken getAuthzToken() {
      return this.authzToken;
    }

    public registerWorkflow_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 String getGatewayId() {
      return this.gatewayId;
    }

    public registerWorkflow_args setGatewayId(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 org.apache.airavata.model.Workflow getWorkflow() {
      return this.workflow;
    }

    public registerWorkflow_args setWorkflow(org.apache.airavata.model.Workflow workflow) {
      this.workflow = workflow;
      return this;
    }

    public void unsetWorkflow() {
      this.workflow = null;
    }

    /** Returns true if field workflow is set (has been assigned a value) and false otherwise */
    public boolean isSetWorkflow() {
      return this.workflow != null;
    }

    public void setWorkflowIsSet(boolean value) {
      if (!value) {
        this.workflow = null;
      }
    }

    public void setFieldValue(_Fields field, 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((String)value);
        }
        break;

      case WORKFLOW:
        if (value == null) {
          unsetWorkflow();
        } else {
          setWorkflow((org.apache.airavata.model.Workflow)value);
        }
        break;

      }
    }

    public Object getFieldValue(_Fields field) {
      switch (field) {
      case AUTHZ_TOKEN:
        return getAuthzToken();

      case GATEWAY_ID:
        return getGatewayId();

      case WORKFLOW:
        return getWorkflow();

      }
      throw new IllegalStateException();
    }

    /** Returns true if field corresponding to fieldID is set (has been assigned a value) and false otherwise */
    public boolean isSet(_Fields field) {
      if (field == null) {
        throw new IllegalArgumentException();
      }

      switch (field) {
      case AUTHZ_TOKEN:
        return isSetAuthzToken();
      case GATEWAY_ID:
        return isSetGatewayId();
      case WORKFLOW:
        return isSetWorkflow();
      }
      throw new IllegalStateException();
    }

    @Override
    public boolean equals(Object that) {
      if (that == null)
        return false;
      if (that instanceof registerWorkflow_args)
        return this.equals((registerWorkflow_args)that);
      return false;
    }

    public boolean equals(registerWorkflow_args that) {
      if (that == null)
        return false;

      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;
      }

      boolean this_present_workflow = true && this.isSetWorkflow();
      boolean that_present_workflow = true && that.isSetWorkflow();
      if (this_present_workflow || that_present_workflow) {
        if (!(this_present_workflow && that_present_workflow))
          return false;
        if (!this.workflow.equals(that.workflow))
          return false;
      }

      return true;
    }

    @Override
    public int hashCode() {
      List<Object> list = new ArrayList<Object>();

      boolean present_authzToken = true && (isSetAuthzToken());
      list.add(present_authzToken);
      if (present_authzToken)
        list.add(authzToken);

      boolean present_gatewayId = true && (isSetGatewayId());
      list.add(present_gatewayId);
      if (present_gatewayId)
        list.add(gatewayId);

      boolean present_workflow = true && (isSetWorkflow());
      list.add(present_workflow);
      if (present_workflow)
        list.add(workflow);

      return list.hashCode();
    }

    @Override
    public int compareTo(registerWorkflow_args other) {
      if (!getClass().equals(other.getClass())) {
        return getClass().getName().compareTo(other.getClass().getName());
      }

      int lastComparison = 0;

      lastComparison = 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 = 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;
        }
      }
      lastComparison = Boolean.valueOf(isSetWorkflow()).compareTo(other.isSetWorkflow());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetWorkflow()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.workflow, other.workflow);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      return 0;
    }

    public _Fields fieldForId(int fieldId) {
      return _Fields.findByThriftId(fieldId);
    }

    public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
      schemes.get(iprot.getScheme()).getScheme().read(iprot, this);
    }

    public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException {
      schemes.get(oprot.getScheme()).getScheme().write(oprot, this);
    }

    @Override
    public String toString() {
      StringBuilder sb = new StringBuilder("registerWorkflow_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;
      if (!first) sb.append(", ");
      sb.append("workflow:");
      if (this.workflow == null) {
        sb.append("null");
      } else {
        sb.append(this.workflow);
      }
      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());
      }
      if (workflow == null) {
        throw new org.apache.thrift.protocol.TProtocolException("Required field 'workflow' was not present! Struct: " + toString());
      }
      // check for sub-struct validity
      if (authzToken != null) {
        authzToken.validate();
      }
      if (workflow != null) {
        workflow.validate();
      }
    }

    private void writeObject(java.io.ObjectOutputStream out) throws java.io.IOException {
      try {
        write(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(out)));
      } catch (org.apache.thrift.TException te) {
        throw new java.io.IOException(te);
      }
    }

    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, ClassNotFoundException {
      try {
        read(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(in)));
      } catch (org.apache.thrift.TException te) {
        throw new java.io.IOException(te);
      }
    }

    private static class registerWorkflow_argsStandardSchemeFactory implements SchemeFactory {
      public registerWorkflow_argsStandardScheme getScheme() {
        return new registerWorkflow_argsStandardScheme();
      }
    }

    private static class registerWorkflow_argsStandardScheme extends StandardScheme<registerWorkflow_args> {

      public void read(org.apache.thrift.protocol.TProtocol iprot, registerWorkflow_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;
            case 3: // WORKFLOW
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.workflow = new org.apache.airavata.model.Workflow();
                struct.workflow.read(iprot);
                struct.setWorkflowIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            default:
              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
          }
          iprot.readFieldEnd();
        }
        iprot.readStructEnd();

        // check for required fields of primitive type, which can't be checked in the validate method
        struct.validate();
      }

      public void write(org.apache.thrift.protocol.TProtocol oprot, registerWorkflow_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();
        }
        if (struct.workflow != null) {
          oprot.writeFieldBegin(WORKFLOW_FIELD_DESC);
          struct.workflow.write(oprot);
          oprot.writeFieldEnd();
        }
        oprot.writeFieldStop();
        oprot.writeStructEnd();
      }

    }

    private static class registerWorkflow_argsTupleSchemeFactory implements SchemeFactory {
      public registerWorkflow_argsTupleScheme getScheme() {
        return new registerWorkflow_argsTupleScheme();
      }
    }

    private static class registerWorkflow_argsTupleScheme extends TupleScheme<registerWorkflow_args> {

      @Override
      public void write(org.apache.thrift.protocol.TProtocol prot, registerWorkflow_args struct) throws org.apache.thrift.TException {
        TTupleProtocol oprot = (TTupleProtocol) prot;
        struct.authzToken.write(oprot);
        oprot.writeString(struct.gatewayId);
        struct.workflow.write(oprot);
      }

      @Override
      public void read(org.apache.thrift.protocol.TProtocol prot, registerWorkflow_args struct) throws org.apache.thrift.TException {
        TTupleProtocol iprot = (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);
        struct.workflow = new org.apache.airavata.model.Workflow();
        struct.workflow.read(iprot);
        struct.setWorkflowIsSet(true);
      }
    }

  }

  public static class registerWorkflow_result implements org.apache.thrift.TBase<registerWorkflow_result, registerWorkflow_result._Fields>, java.io.Serializable, Cloneable, Comparable<registerWorkflow_result>   {
    private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("registerWorkflow_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 IRE_FIELD_DESC = new org.apache.thrift.protocol.TField("ire", org.apache.thrift.protocol.TType.STRUCT, (short)1);
    private static final org.apache.thrift.protocol.TField ACE_FIELD_DESC = new org.apache.thrift.protocol.TField("ace", org.apache.thrift.protocol.TType.STRUCT, (short)2);
    private static final org.apache.thrift.protocol.TField ASE_FIELD_DESC = new org.apache.thrift.protocol.TField("ase", org.apache.thrift.protocol.TType.STRUCT, (short)3);
    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)4);

    private static final Map<Class<? extends IScheme>, SchemeFactory> schemes = new HashMap<Class<? extends IScheme>, SchemeFactory>();
    static {
      schemes.put(StandardScheme.class, new registerWorkflow_resultStandardSchemeFactory());
      schemes.put(TupleScheme.class, new registerWorkflow_resultTupleSchemeFactory());
    }

    public String success; // required
    public org.apache.airavata.model.error.InvalidRequestException ire; // required
    public org.apache.airavata.model.error.AiravataClientException ace; // required
    public org.apache.airavata.model.error.AiravataSystemException ase; // 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"),
      IRE((short)1, "ire"),
      ACE((short)2, "ace"),
      ASE((short)3, "ase"),
      AE((short)4, "ae");

      private static final Map<String, _Fields> byName = new HashMap<String, _Fields>();

      static {
        for (_Fields field : EnumSet.allOf(_Fields.class)) {
          byName.put(field.getFieldName(), field);
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, or null if its not found.
       */
      public static _Fields findByThriftId(int fieldId) {
        switch(fieldId) {
          case 0: // SUCCESS
            return SUCCESS;
          case 1: // IRE
            return IRE;
          case 2: // ACE
            return ACE;
          case 3: // ASE
            return ASE;
          case 4: // 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 IllegalArgumentException("Field " + fieldId + " doesn't exist!");
        return fields;
      }

      /**
       * Find the _Fields constant that matches name, or null if its not found.
       */
      public static _Fields findByName(String name) {
        return byName.get(name);
      }

      private final short _thriftId;
      private final String _fieldName;

      _Fields(short thriftId, String fieldName) {
        _thriftId = thriftId;
        _fieldName = fieldName;
      }

      public short getThriftFieldId() {
        return _thriftId;
      }

      public String getFieldName() {
        return _fieldName;
      }
    }

    // isset id assignments
    public static final Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
    static {
      Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new EnumMap<_Fields, org.apache.thrift.meta_data.FieldMetaData>(_Fields.class);
      tmpMap.put(_Fields.SUCCESS, new org.apache.thrift.meta_data.FieldMetaData("success", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING)));
      tmpMap.put(_Fields.IRE, new org.apache.thrift.meta_data.FieldMetaData("ire", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRUCT)));
      tmpMap.put(_Fields.ACE, new org.apache.thrift.meta_data.FieldMetaData("ace", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRUCT)));
      tmpMap.put(_Fields.ASE, new org.apache.thrift.meta_data.FieldMetaData("ase", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRUCT)));
      tmpMap.put(_Fields.AE, new org.apache.thrift.meta_data.FieldMetaData("ae", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRUCT)));
      metaDataMap = Collections.unmodifiableMap(tmpMap);
      org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(registerWorkflow_result.class, metaDataMap);
    }

    public registerWorkflow_result() {
    }

    public registerWorkflow_result(
      String success,
      org.apache.airavata.model.error.InvalidRequestException ire,
      org.apache.airavata.model.error.AiravataClientException ace,
      org.apache.airavata.model.error.AiravataSystemException ase,
      org.apache.airavata.model.error.AuthorizationException ae)
    {
      this();
      this.success = success;
      this.ire = ire;
      this.ace = ace;
      this.ase = ase;
      this.ae = ae;
    }

    /**
     * Performs a deep copy on <i>other</i>.
     */
    public registerWorkflow_result(registerWorkflow_result other) {
      if (other.isSetSuccess()) {
        this.success = other.success;
      }
      if (other.isSetIre()) {
        this.ire = new org.apache.airavata.model.error.InvalidRequestException(other.ire);
      }
      if (other.isSetAce()) {
        this.ace = new org.apache.airavata.model.error.AiravataClientException(other.ace);
      }
      if (other.isSetAse()) {
        this.ase = new org.apache.airavata.model.error.AiravataSystemException(other.ase);
      }
      if (other.isSetAe()) {
        this.ae = new org.apache.airavata.model.error.AuthorizationException(other.ae);
      }
    }

    public registerWorkflow_result deepCopy() {
      return new registerWorkflow_result(this);
    }

    @Override
    public void clear() {
      this.success = null;
      this.ire = null;
      this.ace = null;
      this.ase = null;
      this.ae = null;
    }

    public String getSuccess() {
      return this.success;
    }

    public registerWorkflow_result setSuccess(String success) {
      this.success = success;
      return this;
    }

    public void unsetSuccess() {
      this.success = null;
    }

    /** Returns true if field success is set (has been assigned a value) and false otherwise */
    public boolean isSetSuccess() {
      return this.success != null;
    }

    public void setSuccessIsSet(boolean value) {
      if (!value) {
        this.success = null;
      }
    }

    public org.apache.airavata.model.error.InvalidRequestException getIre() {
      return this.ire;
    }

    public registerWorkflow_result setIre(org.apache.airavata.model.error.InvalidRequestException ire) {
      this.ire = ire;
      return this;
    }

    public void unsetIre() {
      this.ire = null;
    }

    /** Returns true if field ire is set (has been assigned a value) and false otherwise */
    public boolean isSetIre() {
      return this.ire != null;
    }

    public void setIreIsSet(boolean value) {
      if (!value) {
        this.ire = null;
      }
    }

    public org.apache.airavata.model.error.AiravataClientException getAce() {
      return this.ace;
    }

    public registerWorkflow_result setAce(org.apache.airavata.model.error.AiravataClientException ace) {
      this.ace = ace;
      return this;
    }

    public void unsetAce() {
      this.ace = null;
    }

    /** Returns true if field ace is set (has been assigned a value) and false otherwise */
    public boolean isSetAce() {
      return this.ace != null;
    }

    public void setAceIsSet(boolean value) {
      if (!value) {
        this.ace = null;
      }
    }

    public org.apache.airavata.model.error.AiravataSystemException getAse() {
      return this.ase;
    }

    public registerWorkflow_result setAse(org.apache.airavata.model.error.AiravataSystemException ase) {
      this.ase = ase;
      return this;
    }

    public void unsetAse() {
      this.ase = null;
    }

    /** Returns true if field ase is set (has been assigned a value) and false otherwise */
    public boolean isSetAse() {
      return this.ase != null;
    }

    public void setAseIsSet(boolean value) {
      if (!value) {
        this.ase = null;
      }
    }

    public org.apache.airavata.model.error.AuthorizationException getAe() {
      return this.ae;
    }

    public registerWorkflow_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, Object value) {
      switch (field) {
      case SUCCESS:
        if (value == null) {
          unsetSuccess();
        } else {
          setSuccess((String)value);
        }
        break;

      case IRE:
        if (value == null) {
          unsetIre();
        } else {
          setIre((org.apache.airavata.model.error.InvalidRequestException)value);
        }
        break;

      case ACE:
        if (value == null) {
          unsetAce();
        } else {
          setAce((org.apache.airavata.model.error.AiravataClientException)value);
        }
        break;

      case ASE:
        if (value == null) {
          unsetAse();
        } else {
          setAse((org.apache.airavata.model.error.AiravataSystemException)value);
        }
        break;

      case AE:
        if (value == null) {
          unsetAe();
        } else {
          setAe((org.apache.airavata.model.error.AuthorizationException)value);
        }
        break;

      }
    }

    public Object getFieldValue(_Fields field) {
      switch (field) {
      case SUCCESS:
        return getSuccess();

      case IRE:
        return getIre();

      case ACE:
        return getAce();

      case ASE:
        return getAse();

      case AE:
        return getAe();

      }
      throw new IllegalStateException();
    }

    /** Returns true if field corresponding to fieldID is set (has been assigned a value) and false otherwise */
    public boolean isSet(_Fields field) {
      if (field == null) {
        throw new IllegalArgumentException();
      }

      switch (field) {
      case SUCCESS:
        return isSetSuccess();
      case IRE:
        return isSetIre();
      case ACE:
        return isSetAce();
      case ASE:
        return isSetAse();
      case AE:
        return isSetAe();
      }
      throw new IllegalStateException();
    }

    @Override
    public boolean equals(Object that) {
      if (that == null)
        return false;
      if (that instanceof registerWorkflow_result)
        return this.equals((registerWorkflow_result)that);
      return false;
    }

    public boolean equals(registerWorkflow_result that) {
      if (that == null)
        return false;

      boolean this_present_success = true && this.isSetSuccess();
      boolean that_present_success = true && that.isSetSuccess();
      if (this_present_success || that_present_success) {
        if (!(this_present_success && that_present_success))
          return false;
        if (!this.success.equals(that.success))
          return false;
      }

      boolean this_present_ire = true && this.isSetIre();
      boolean that_present_ire = true && that.isSetIre();
      if (this_present_ire || that_present_ire) {
        if (!(this_present_ire && that_present_ire))
          return false;
        if (!this.ire.equals(that.ire))
          return false;
      }

      boolean this_present_ace = true && this.isSetAce();
      boolean that_present_ace = true && that.isSetAce();
      if (this_present_ace || that_present_ace) {
        if (!(this_present_ace && that_present_ace))
          return false;
        if (!this.ace.equals(that.ace))
          return false;
      }

      boolean this_present_ase = true && this.isSetAse();
      boolean that_present_ase = true && that.isSetAse();
      if (this_present_ase || that_present_ase) {
        if (!(this_present_ase && that_present_ase))
          return false;
        if (!this.ase.equals(that.ase))
          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() {
      List<Object> list = new ArrayList<Object>();

      boolean present_success = true && (isSetSuccess());
      list.add(present_success);
      if (present_success)
        list.add(success);

      boolean present_ire = true && (isSetIre());
      list.add(present_ire);
      if (present_ire)
        list.add(ire);

      boolean present_ace = true && (isSetAce());
      list.add(present_ace);
      if (present_ace)
        list.add(ace);

      boolean present_ase = true && (isSetAse());
      list.add(present_ase);
      if (present_ase)
        list.add(ase);

      boolean present_ae = true && (isSetAe());
      list.add(present_ae);
      if (present_ae)
        list.add(ae);

      return list.hashCode();
    }

    @Override
    public int compareTo(registerWorkflow_result other) {
      if (!getClass().equals(other.getClass())) {
        return getClass().getName().compareTo(other.getClass().getName());
      }

      int lastComparison = 0;

      lastComparison = Boolean.valueOf(isSetSuccess()).compareTo(other.isSetSuccess());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetSuccess()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.success, other.success);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = Boolean.valueOf(isSetIre()).compareTo(other.isSetIre());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetIre()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.ire, other.ire);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = Boolean.valueOf(isSetAce()).compareTo(other.isSetAce());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetAce()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.ace, other.ace);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = Boolean.valueOf(isSetAse()).compareTo(other.isSetAse());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetAse()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.ase, other.ase);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = 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 {
      schemes.get(iprot.getScheme()).getScheme().read(iprot, this);
    }

    public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException {
      schemes.get(oprot.getScheme()).getScheme().write(oprot, this);
      }

    @Override
    public String toString() {
      StringBuilder sb = new StringBuilder("registerWorkflow_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("ire:");
      if (this.ire == null) {
        sb.append("null");
      } else {
        sb.append(this.ire);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("ace:");
      if (this.ace == null) {
        sb.append("null");
      } else {
        sb.append(this.ace);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("ase:");
      if (this.ase == null) {
        sb.append("null");
      } else {
        sb.append(this.ase);
      }
      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, 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 registerWorkflow_resultStandardSchemeFactory implements SchemeFactory {
      public registerWorkflow_resultStandardScheme getScheme() {
        return new registerWorkflow_resultStandardScheme();
      }
    }

    private static class registerWorkflow_resultStandardScheme extends StandardScheme<registerWorkflow_result> {

      public void read(org.apache.thrift.protocol.TProtocol iprot, registerWorkflow_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: // IRE
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.ire = new org.apache.airavata.model.error.InvalidRequestException();
                struct.ire.read(iprot);
                struct.setIreIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 2: // ACE
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.ace = new org.apache.airavata.model.error.AiravataClientException();
                struct.ace.read(iprot);
                struct.setAceIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 3: // ASE
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.ase = new org.apache.airavata.model.error.AiravataSystemException();
                struct.ase.read(iprot);
                struct.setAseIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 4: // 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, registerWorkflow_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.ire != null) {
          oprot.writeFieldBegin(IRE_FIELD_DESC);
          struct.ire.write(oprot);
          oprot.writeFieldEnd();
        }
        if (struct.ace != null) {
          oprot.writeFieldBegin(ACE_FIELD_DESC);
          struct.ace.write(oprot);
          oprot.writeFieldEnd();
        }
        if (struct.ase != null) {
          oprot.writeFieldBegin(ASE_FIELD_DESC);
          struct.ase.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 registerWorkflow_resultTupleSchemeFactory implements SchemeFactory {
      public registerWorkflow_resultTupleScheme getScheme() {
        return new registerWorkflow_resultTupleScheme();
      }
    }

    private static class registerWorkflow_resultTupleScheme extends TupleScheme<registerWorkflow_result> {

      @Override
      public void write(org.apache.thrift.protocol.TProtocol prot, registerWorkflow_result struct) throws org.apache.thrift.TException {
        TTupleProtocol oprot = (TTupleProtocol) prot;
        BitSet optionals = new BitSet();
        if (struct.isSetSuccess()) {
          optionals.set(0);
        }
        if (struct.isSetIre()) {
          optionals.set(1);
        }
        if (struct.isSetAce()) {
          optionals.set(2);
        }
        if (struct.isSetAse()) {
          optionals.set(3);
        }
        if (struct.isSetAe()) {
          optionals.set(4);
        }
        oprot.writeBitSet(optionals, 5);
        if (struct.isSetSuccess()) {
          oprot.writeString(struct.success);
        }
        if (struct.isSetIre()) {
          struct.ire.write(oprot);
        }
        if (struct.isSetAce()) {
          struct.ace.write(oprot);
        }
        if (struct.isSetAse()) {
          struct.ase.write(oprot);
        }
        if (struct.isSetAe()) {
          struct.ae.write(oprot);
        }
      }

      @Override
      public void read(org.apache.thrift.protocol.TProtocol prot, registerWorkflow_result struct) throws org.apache.thrift.TException {
        TTupleProtocol iprot = (TTupleProtocol) prot;
        BitSet incoming = iprot.readBitSet(5);
        if (incoming.get(0)) {
          struct.success = iprot.readString();
          struct.setSuccessIsSet(true);
        }
        if (incoming.get(1)) {
          struct.ire = new org.apache.airavata.model.error.InvalidRequestException();
          struct.ire.read(iprot);
          struct.setIreIsSet(true);
        }
        if (incoming.get(2)) {
          struct.ace = new org.apache.airavata.model.error.AiravataClientException();
          struct.ace.read(iprot);
          struct.setAceIsSet(true);
        }
        if (incoming.get(3)) {
          struct.ase = new org.apache.airavata.model.error.AiravataSystemException();
          struct.ase.read(iprot);
          struct.setAseIsSet(true);
        }
        if (incoming.get(4)) {
          struct.ae = new org.apache.airavata.model.error.AuthorizationException();
          struct.ae.read(iprot);
          struct.setAeIsSet(true);
        }
      }
    }

  }

  public static class updateWorkflow_args implements org.apache.thrift.TBase<updateWorkflow_args, updateWorkflow_args._Fields>, java.io.Serializable, Cloneable, Comparable<updateWorkflow_args>   {
    private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("updateWorkflow_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 WORKFLOW_TEMPLATE_ID_FIELD_DESC = new org.apache.thrift.protocol.TField("workflowTemplateId", org.apache.thrift.protocol.TType.STRING, (short)2);
    private static final org.apache.thrift.protocol.TField WORKFLOW_FIELD_DESC = new org.apache.thrift.protocol.TField("workflow", org.apache.thrift.protocol.TType.STRUCT, (short)3);

    private static final Map<Class<? extends IScheme>, SchemeFactory> schemes = new HashMap<Class<? extends IScheme>, SchemeFactory>();
    static {
      schemes.put(StandardScheme.class, new updateWorkflow_argsStandardSchemeFactory());
      schemes.put(TupleScheme.class, new updateWorkflow_argsTupleSchemeFactory());
    }

    public org.apache.airavata.model.security.AuthzToken authzToken; // required
    public String workflowTemplateId; // required
    public org.apache.airavata.model.Workflow workflow; // required

    /** 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"),
      WORKFLOW_TEMPLATE_ID((short)2, "workflowTemplateId"),
      WORKFLOW((short)3, "workflow");

      private static final Map<String, _Fields> byName = new HashMap<String, _Fields>();

      static {
        for (_Fields field : EnumSet.allOf(_Fields.class)) {
          byName.put(field.getFieldName(), field);
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, or null if its not found.
       */
      public static _Fields findByThriftId(int fieldId) {
        switch(fieldId) {
          case 1: // AUTHZ_TOKEN
            return AUTHZ_TOKEN;
          case 2: // WORKFLOW_TEMPLATE_ID
            return WORKFLOW_TEMPLATE_ID;
          case 3: // WORKFLOW
            return WORKFLOW;
          default:
            return null;
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, throwing an exception
       * if it is not found.
       */
      public static _Fields findByThriftIdOrThrow(int fieldId) {
        _Fields fields = findByThriftId(fieldId);
        if (fields == null) throw new IllegalArgumentException("Field " + fieldId + " doesn't exist!");
        return fields;
      }

      /**
       * Find the _Fields constant that matches name, or null if its not found.
       */
      public static _Fields findByName(String name) {
        return byName.get(name);
      }

      private final short _thriftId;
      private final String _fieldName;

      _Fields(short thriftId, String fieldName) {
        _thriftId = thriftId;
        _fieldName = fieldName;
      }

      public short getThriftFieldId() {
        return _thriftId;
      }

      public String getFieldName() {
        return _fieldName;
      }
    }

    // isset id assignments
    public static final Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
    static {
      Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new EnumMap<_Fields, org.apache.thrift.meta_data.FieldMetaData>(_Fields.class);
      tmpMap.put(_Fields.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.WORKFLOW_TEMPLATE_ID, new org.apache.thrift.meta_data.FieldMetaData("workflowTemplateId", org.apache.thrift.TFieldRequirementType.REQUIRED, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING)));
      tmpMap.put(_Fields.WORKFLOW, new org.apache.thrift.meta_data.FieldMetaData("workflow", org.apache.thrift.TFieldRequirementType.REQUIRED, 
          new org.apache.thrift.meta_data.StructMetaData(org.apache.thrift.protocol.TType.STRUCT, org.apache.airavata.model.Workflow.class)));
      metaDataMap = Collections.unmodifiableMap(tmpMap);
      org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(updateWorkflow_args.class, metaDataMap);
    }

    public updateWorkflow_args() {
    }

    public updateWorkflow_args(
      org.apache.airavata.model.security.AuthzToken authzToken,
      String workflowTemplateId,
      org.apache.airavata.model.Workflow workflow)
    {
      this();
      this.authzToken = authzToken;
      this.workflowTemplateId = workflowTemplateId;
      this.workflow = workflow;
    }

    /**
     * Performs a deep copy on <i>other</i>.
     */
    public updateWorkflow_args(updateWorkflow_args other) {
      if (other.isSetAuthzToken()) {
        this.authzToken = new org.apache.airavata.model.security.AuthzToken(other.authzToken);
      }
      if (other.isSetWorkflowTemplateId()) {
        this.workflowTemplateId = other.workflowTemplateId;
      }
      if (other.isSetWorkflow()) {
        this.workflow = new org.apache.airavata.model.Workflow(other.workflow);
      }
    }

    public updateWorkflow_args deepCopy() {
      return new updateWorkflow_args(this);
    }

    @Override
    public void clear() {
      this.authzToken = null;
      this.workflowTemplateId = null;
      this.workflow = null;
    }

    public org.apache.airavata.model.security.AuthzToken getAuthzToken() {
      return this.authzToken;
    }

    public updateWorkflow_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 String getWorkflowTemplateId() {
      return this.workflowTemplateId;
    }

    public updateWorkflow_args setWorkflowTemplateId(String workflowTemplateId) {
      this.workflowTemplateId = workflowTemplateId;
      return this;
    }

    public void unsetWorkflowTemplateId() {
      this.workflowTemplateId = null;
    }

    /** Returns true if field workflowTemplateId is set (has been assigned a value) and false otherwise */
    public boolean isSetWorkflowTemplateId() {
      return this.workflowTemplateId != null;
    }

    public void setWorkflowTemplateIdIsSet(boolean value) {
      if (!value) {
        this.workflowTemplateId = null;
      }
    }

    public org.apache.airavata.model.Workflow getWorkflow() {
      return this.workflow;
    }

    public updateWorkflow_args setWorkflow(org.apache.airavata.model.Workflow workflow) {
      this.workflow = workflow;
      return this;
    }

    public void unsetWorkflow() {
      this.workflow = null;
    }

    /** Returns true if field workflow is set (has been assigned a value) and false otherwise */
    public boolean isSetWorkflow() {
      return this.workflow != null;
    }

    public void setWorkflowIsSet(boolean value) {
      if (!value) {
        this.workflow = null;
      }
    }

    public void setFieldValue(_Fields field, Object value) {
      switch (field) {
      case AUTHZ_TOKEN:
        if (value == null) {
          unsetAuthzToken();
        } else {
          setAuthzToken((org.apache.airavata.model.security.AuthzToken)value);
        }
        break;

      case WORKFLOW_TEMPLATE_ID:
        if (value == null) {
          unsetWorkflowTemplateId();
        } else {
          setWorkflowTemplateId((String)value);
        }
        break;

      case WORKFLOW:
        if (value == null) {
          unsetWorkflow();
        } else {
          setWorkflow((org.apache.airavata.model.Workflow)value);
        }
        break;

      }
    }

    public Object getFieldValue(_Fields field) {
      switch (field) {
      case AUTHZ_TOKEN:
        return getAuthzToken();

      case WORKFLOW_TEMPLATE_ID:
        return getWorkflowTemplateId();

      case WORKFLOW:
        return getWorkflow();

      }
      throw new IllegalStateException();
    }

    /** Returns true if field corresponding to fieldID is set (has been assigned a value) and false otherwise */
    public boolean isSet(_Fields field) {
      if (field == null) {
        throw new IllegalArgumentException();
      }

      switch (field) {
      case AUTHZ_TOKEN:
        return isSetAuthzToken();
      case WORKFLOW_TEMPLATE_ID:
        return isSetWorkflowTemplateId();
      case WORKFLOW:
        return isSetWorkflow();
      }
      throw new IllegalStateException();
    }

    @Override
    public boolean equals(Object that) {
      if (that == null)
        return false;
      if (that instanceof updateWorkflow_args)
        return this.equals((updateWorkflow_args)that);
      return false;
    }

    public boolean equals(updateWorkflow_args that) {
      if (that == null)
        return false;

      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_workflowTemplateId = true && this.isSetWorkflowTemplateId();
      boolean that_present_workflowTemplateId = true && that.isSetWorkflowTemplateId();
      if (this_present_workflowTemplateId || that_present_workflowTemplateId) {
        if (!(this_present_workflowTemplateId && that_present_workflowTemplateId))
          return false;
        if (!this.workflowTemplateId.equals(that.workflowTemplateId))
          return false;
      }

      boolean this_present_workflow = true && this.isSetWorkflow();
      boolean that_present_workflow = true && that.isSetWorkflow();
      if (this_present_workflow || that_present_workflow) {
        if (!(this_present_workflow && that_present_workflow))
          return false;
        if (!this.workflow.equals(that.workflow))
          return false;
      }

      return true;
    }

    @Override
    public int hashCode() {
      List<Object> list = new ArrayList<Object>();

      boolean present_authzToken = true && (isSetAuthzToken());
      list.add(present_authzToken);
      if (present_authzToken)
        list.add(authzToken);

      boolean present_workflowTemplateId = true && (isSetWorkflowTemplateId());
      list.add(present_workflowTemplateId);
      if (present_workflowTemplateId)
        list.add(workflowTemplateId);

      boolean present_workflow = true && (isSetWorkflow());
      list.add(present_workflow);
      if (present_workflow)
        list.add(workflow);

      return list.hashCode();
    }

    @Override
    public int compareTo(updateWorkflow_args other) {
      if (!getClass().equals(other.getClass())) {
        return getClass().getName().compareTo(other.getClass().getName());
      }

      int lastComparison = 0;

      lastComparison = 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 = Boolean.valueOf(isSetWorkflowTemplateId()).compareTo(other.isSetWorkflowTemplateId());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetWorkflowTemplateId()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.workflowTemplateId, other.workflowTemplateId);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = Boolean.valueOf(isSetWorkflow()).compareTo(other.isSetWorkflow());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetWorkflow()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.workflow, other.workflow);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      return 0;
    }

    public _Fields fieldForId(int fieldId) {
      return _Fields.findByThriftId(fieldId);
    }

    public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
      schemes.get(iprot.getScheme()).getScheme().read(iprot, this);
    }

    public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException {
      schemes.get(oprot.getScheme()).getScheme().write(oprot, this);
    }

    @Override
    public String toString() {
      StringBuilder sb = new StringBuilder("updateWorkflow_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("workflowTemplateId:");
      if (this.workflowTemplateId == null) {
        sb.append("null");
      } else {
        sb.append(this.workflowTemplateId);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("workflow:");
      if (this.workflow == null) {
        sb.append("null");
      } else {
        sb.append(this.workflow);
      }
      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 (workflowTemplateId == null) {
        throw new org.apache.thrift.protocol.TProtocolException("Required field 'workflowTemplateId' was not present! Struct: " + toString());
      }
      if (workflow == null) {
        throw new org.apache.thrift.protocol.TProtocolException("Required field 'workflow' was not present! Struct: " + toString());
      }
      // check for sub-struct validity
      if (authzToken != null) {
        authzToken.validate();
      }
      if (workflow != null) {
        workflow.validate();
      }
    }

    private void writeObject(java.io.ObjectOutputStream out) throws java.io.IOException {
      try {
        write(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(out)));
      } catch (org.apache.thrift.TException te) {
        throw new java.io.IOException(te);
      }
    }

    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, ClassNotFoundException {
      try {
        read(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(in)));
      } catch (org.apache.thrift.TException te) {
        throw new java.io.IOException(te);
      }
    }

    private static class updateWorkflow_argsStandardSchemeFactory implements SchemeFactory {
      public updateWorkflow_argsStandardScheme getScheme() {
        return new updateWorkflow_argsStandardScheme();
      }
    }

    private static class updateWorkflow_argsStandardScheme extends StandardScheme<updateWorkflow_args> {

      public void read(org.apache.thrift.protocol.TProtocol iprot, updateWorkflow_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: // WORKFLOW_TEMPLATE_ID
              if (schemeField.type == org.apache.thrift.protocol.TType.STRING) {
                struct.workflowTemplateId = iprot.readString();
                struct.setWorkflowTemplateIdIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 3: // WORKFLOW
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.workflow = new org.apache.airavata.model.Workflow();
                struct.workflow.read(iprot);
                struct.setWorkflowIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            default:
              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
          }
          iprot.readFieldEnd();
        }
        iprot.readStructEnd();

        // check for required fields of primitive type, which can't be checked in the validate method
        struct.validate();
      }

      public void write(org.apache.thrift.protocol.TProtocol oprot, updateWorkflow_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.workflowTemplateId != null) {
          oprot.writeFieldBegin(WORKFLOW_TEMPLATE_ID_FIELD_DESC);
          oprot.writeString(struct.workflowTemplateId);
          oprot.writeFieldEnd();
        }
        if (struct.workflow != null) {
          oprot.writeFieldBegin(WORKFLOW_FIELD_DESC);
          struct.workflow.write(oprot);
          oprot.writeFieldEnd();
        }
        oprot.writeFieldStop();
        oprot.writeStructEnd();
      }

    }

    private static class updateWorkflow_argsTupleSchemeFactory implements SchemeFactory {
      public updateWorkflow_argsTupleScheme getScheme() {
        return new updateWorkflow_argsTupleScheme();
      }
    }

    private static class updateWorkflow_argsTupleScheme extends TupleScheme<updateWorkflow_args> {

      @Override
      public void write(org.apache.thrift.protocol.TProtocol prot, updateWorkflow_args struct) throws org.apache.thrift.TException {
        TTupleProtocol oprot = (TTupleProtocol) prot;
        struct.authzToken.write(oprot);
        oprot.writeString(struct.workflowTemplateId);
        struct.workflow.write(oprot);
      }

      @Override
      public void read(org.apache.thrift.protocol.TProtocol prot, updateWorkflow_args struct) throws org.apache.thrift.TException {
        TTupleProtocol iprot = (TTupleProtocol) prot;
        struct.authzToken = new org.apache.airavata.model.security.AuthzToken();
        struct.authzToken.read(iprot);
        struct.setAuthzTokenIsSet(true);
        struct.workflowTemplateId = iprot.readString();
        struct.setWorkflowTemplateIdIsSet(true);
        struct.workflow = new org.apache.airavata.model.Workflow();
        struct.workflow.read(iprot);
        struct.setWorkflowIsSet(true);
      }
    }

  }

  public static class updateWorkflow_result implements org.apache.thrift.TBase<updateWorkflow_result, updateWorkflow_result._Fields>, java.io.Serializable, Cloneable, Comparable<updateWorkflow_result>   {
    private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("updateWorkflow_result");

    private static final org.apache.thrift.protocol.TField IRE_FIELD_DESC = new org.apache.thrift.protocol.TField("ire", org.apache.thrift.protocol.TType.STRUCT, (short)1);
    private static final org.apache.thrift.protocol.TField ACE_FIELD_DESC = new org.apache.thrift.protocol.TField("ace", org.apache.thrift.protocol.TType.STRUCT, (short)2);
    private static final org.apache.thrift.protocol.TField ASE_FIELD_DESC = new org.apache.thrift.protocol.TField("ase", org.apache.thrift.protocol.TType.STRUCT, (short)3);
    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)4);

    private static final Map<Class<? extends IScheme>, SchemeFactory> schemes = new HashMap<Class<? extends IScheme>, SchemeFactory>();
    static {
      schemes.put(StandardScheme.class, new updateWorkflow_resultStandardSchemeFactory());
      schemes.put(TupleScheme.class, new updateWorkflow_resultTupleSchemeFactory());
    }

    public org.apache.airavata.model.error.InvalidRequestException ire; // required
    public org.apache.airavata.model.error.AiravataClientException ace; // required
    public org.apache.airavata.model.error.AiravataSystemException ase; // 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 {
      IRE((short)1, "ire"),
      ACE((short)2, "ace"),
      ASE((short)3, "ase"),
      AE((short)4, "ae");

      private static final Map<String, _Fields> byName = new HashMap<String, _Fields>();

      static {
        for (_Fields field : EnumSet.allOf(_Fields.class)) {
          byName.put(field.getFieldName(), field);
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, or null if its not found.
       */
      public static _Fields findByThriftId(int fieldId) {
        switch(fieldId) {
          case 1: // IRE
            return IRE;
          case 2: // ACE
            return ACE;
          case 3: // ASE
            return ASE;
          case 4: // 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 IllegalArgumentException("Field " + fieldId + " doesn't exist!");
        return fields;
      }

      /**
       * Find the _Fields constant that matches name, or null if its not found.
       */
      public static _Fields findByName(String name) {
        return byName.get(name);
      }

      private final short _thriftId;
      private final String _fieldName;

      _Fields(short thriftId, String fieldName) {
        _thriftId = thriftId;
        _fieldName = fieldName;
      }

      public short getThriftFieldId() {
        return _thriftId;
      }

      public String getFieldName() {
        return _fieldName;
      }
    }

    // isset id assignments
    public static final Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
    static {
      Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new EnumMap<_Fields, org.apache.thrift.meta_data.FieldMetaData>(_Fields.class);
      tmpMap.put(_Fields.IRE, new org.apache.thrift.meta_data.FieldMetaData("ire", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRUCT)));
      tmpMap.put(_Fields.ACE, new org.apache.thrift.meta_data.FieldMetaData("ace", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRUCT)));
      tmpMap.put(_Fields.ASE, new org.apache.thrift.meta_data.FieldMetaData("ase", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRUCT)));
      tmpMap.put(_Fields.AE, new org.apache.thrift.meta_data.FieldMetaData("ae", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRUCT)));
      metaDataMap = Collections.unmodifiableMap(tmpMap);
      org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(updateWorkflow_result.class, metaDataMap);
    }

    public updateWorkflow_result() {
    }

    public updateWorkflow_result(
      org.apache.airavata.model.error.InvalidRequestException ire,
      org.apache.airavata.model.error.AiravataClientException ace,
      org.apache.airavata.model.error.AiravataSystemException ase,
      org.apache.airavata.model.error.AuthorizationException ae)
    {
      this();
      this.ire = ire;
      this.ace = ace;
      this.ase = ase;
      this.ae = ae;
    }

    /**
     * Performs a deep copy on <i>other</i>.
     */
    public updateWorkflow_result(updateWorkflow_result other) {
      if (other.isSetIre()) {
        this.ire = new org.apache.airavata.model.error.InvalidRequestException(other.ire);
      }
      if (other.isSetAce()) {
        this.ace = new org.apache.airavata.model.error.AiravataClientException(other.ace);
      }
      if (other.isSetAse()) {
        this.ase = new org.apache.airavata.model.error.AiravataSystemException(other.ase);
      }
      if (other.isSetAe()) {
        this.ae = new org.apache.airavata.model.error.AuthorizationException(other.ae);
      }
    }

    public updateWorkflow_result deepCopy() {
      return new updateWorkflow_result(this);
    }

    @Override
    public void clear() {
      this.ire = null;
      this.ace = null;
      this.ase = null;
      this.ae = null;
    }

    public org.apache.airavata.model.error.InvalidRequestException getIre() {
      return this.ire;
    }

    public updateWorkflow_result setIre(org.apache.airavata.model.error.InvalidRequestException ire) {
      this.ire = ire;
      return this;
    }

    public void unsetIre() {
      this.ire = null;
    }

    /** Returns true if field ire is set (has been assigned a value) and false otherwise */
    public boolean isSetIre() {
      return this.ire != null;
    }

    public void setIreIsSet(boolean value) {
      if (!value) {
        this.ire = null;
      }
    }

    public org.apache.airavata.model.error.AiravataClientException getAce() {
      return this.ace;
    }

    public updateWorkflow_result setAce(org.apache.airavata.model.error.AiravataClientException ace) {
      this.ace = ace;
      return this;
    }

    public void unsetAce() {
      this.ace = null;
    }

    /** Returns true if field ace is set (has been assigned a value) and false otherwise */
    public boolean isSetAce() {
      return this.ace != null;
    }

    public void setAceIsSet(boolean value) {
      if (!value) {
        this.ace = null;
      }
    }

    public org.apache.airavata.model.error.AiravataSystemException getAse() {
      return this.ase;
    }

    public updateWorkflow_result setAse(org.apache.airavata.model.error.AiravataSystemException ase) {
      this.ase = ase;
      return this;
    }

    public void unsetAse() {
      this.ase = null;
    }

    /** Returns true if field ase is set (has been assigned a value) and false otherwise */
    public boolean isSetAse() {
      return this.ase != null;
    }

    public void setAseIsSet(boolean value) {
      if (!value) {
        this.ase = null;
      }
    }

    public org.apache.airavata.model.error.AuthorizationException getAe() {
      return this.ae;
    }

    public updateWorkflow_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, Object value) {
      switch (field) {
      case IRE:
        if (value == null) {
          unsetIre();
        } else {
          setIre((org.apache.airavata.model.error.InvalidRequestException)value);
        }
        break;

      case ACE:
        if (value == null) {
          unsetAce();
        } else {
          setAce((org.apache.airavata.model.error.AiravataClientException)value);
        }
        break;

      case ASE:
        if (value == null) {
          unsetAse();
        } else {
          setAse((org.apache.airavata.model.error.AiravataSystemException)value);
        }
        break;

      case AE:
        if (value == null) {
          unsetAe();
        } else {
          setAe((org.apache.airavata.model.error.AuthorizationException)value);
        }
        break;

      }
    }

    public Object getFieldValue(_Fields field) {
      switch (field) {
      case IRE:
        return getIre();

      case ACE:
        return getAce();

      case ASE:
        return getAse();

      case AE:
        return getAe();

      }
      throw new IllegalStateException();
    }

    /** Returns true if field corresponding to fieldID is set (has been assigned a value) and false otherwise */
    public boolean isSet(_Fields field) {
      if (field == null) {
        throw new IllegalArgumentException();
      }

      switch (field) {
      case IRE:
        return isSetIre();
      case ACE:
        return isSetAce();
      case ASE:
        return isSetAse();
      case AE:
        return isSetAe();
      }
      throw new IllegalStateException();
    }

    @Override
    public boolean equals(Object that) {
      if (that == null)
        return false;
      if (that instanceof updateWorkflow_result)
        return this.equals((updateWorkflow_result)that);
      return false;
    }

    public boolean equals(updateWorkflow_result that) {
      if (that == null)
        return false;

      boolean this_present_ire = true && this.isSetIre();
      boolean that_present_ire = true && that.isSetIre();
      if (this_present_ire || that_present_ire) {
        if (!(this_present_ire && that_present_ire))
          return false;
        if (!this.ire.equals(that.ire))
          return false;
      }

      boolean this_present_ace = true && this.isSetAce();
      boolean that_present_ace = true && that.isSetAce();
      if (this_present_ace || that_present_ace) {
        if (!(this_present_ace && that_present_ace))
          return false;
        if (!this.ace.equals(that.ace))
          return false;
      }

      boolean this_present_ase = true && this.isSetAse();
      boolean that_present_ase = true && that.isSetAse();
      if (this_present_ase || that_present_ase) {
        if (!(this_present_ase && that_present_ase))
          return false;
        if (!this.ase.equals(that.ase))
          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() {
      List<Object> list = new ArrayList<Object>();

      boolean present_ire = true && (isSetIre());
      list.add(present_ire);
      if (present_ire)
        list.add(ire);

      boolean present_ace = true && (isSetAce());
      list.add(present_ace);
      if (present_ace)
        list.add(ace);

      boolean present_ase = true && (isSetAse());
      list.add(present_ase);
      if (present_ase)
        list.add(ase);

      boolean present_ae = true && (isSetAe());
      list.add(present_ae);
      if (present_ae)
        list.add(ae);

      return list.hashCode();
    }

    @Override
    public int compareTo(updateWorkflow_result other) {
      if (!getClass().equals(other.getClass())) {
        return getClass().getName().compareTo(other.getClass().getName());
      }

      int lastComparison = 0;

      lastComparison = Boolean.valueOf(isSetIre()).compareTo(other.isSetIre());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetIre()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.ire, other.ire);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = Boolean.valueOf(isSetAce()).compareTo(other.isSetAce());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetAce()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.ace, other.ace);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = Boolean.valueOf(isSetAse()).compareTo(other.isSetAse());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetAse()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.ase, other.ase);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = 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 {
      schemes.get(iprot.getScheme()).getScheme().read(iprot, this);
    }

    public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException {
      schemes.get(oprot.getScheme()).getScheme().write(oprot, this);
      }

    @Override
    public String toString() {
      StringBuilder sb = new StringBuilder("updateWorkflow_result(");
      boolean first = true;

      sb.append("ire:");
      if (this.ire == null) {
        sb.append("null");
      } else {
        sb.append(this.ire);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("ace:");
      if (this.ace == null) {
        sb.append("null");
      } else {
        sb.append(this.ace);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("ase:");
      if (this.ase == null) {
        sb.append("null");
      } else {
        sb.append(this.ase);
      }
      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, 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 updateWorkflow_resultStandardSchemeFactory implements SchemeFactory {
      public updateWorkflow_resultStandardScheme getScheme() {
        return new updateWorkflow_resultStandardScheme();
      }
    }

    private static class updateWorkflow_resultStandardScheme extends StandardScheme<updateWorkflow_result> {

      public void read(org.apache.thrift.protocol.TProtocol iprot, updateWorkflow_result struct) throws org.apache.thrift.TException {
        org.apache.thrift.protocol.TField schemeField;
        iprot.readStructBegin();
        while (true)
        {
          schemeField = iprot.readFieldBegin();
          if (schemeField.type == org.apache.thrift.protocol.TType.STOP) { 
            break;
          }
          switch (schemeField.id) {
            case 1: // IRE
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.ire = new org.apache.airavata.model.error.InvalidRequestException();
                struct.ire.read(iprot);
                struct.setIreIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 2: // ACE
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.ace = new org.apache.airavata.model.error.AiravataClientException();
                struct.ace.read(iprot);
                struct.setAceIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 3: // ASE
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.ase = new org.apache.airavata.model.error.AiravataSystemException();
                struct.ase.read(iprot);
                struct.setAseIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 4: // 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, updateWorkflow_result struct) throws org.apache.thrift.TException {
        struct.validate();

        oprot.writeStructBegin(STRUCT_DESC);
        if (struct.ire != null) {
          oprot.writeFieldBegin(IRE_FIELD_DESC);
          struct.ire.write(oprot);
          oprot.writeFieldEnd();
        }
        if (struct.ace != null) {
          oprot.writeFieldBegin(ACE_FIELD_DESC);
          struct.ace.write(oprot);
          oprot.writeFieldEnd();
        }
        if (struct.ase != null) {
          oprot.writeFieldBegin(ASE_FIELD_DESC);
          struct.ase.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 updateWorkflow_resultTupleSchemeFactory implements SchemeFactory {
      public updateWorkflow_resultTupleScheme getScheme() {
        return new updateWorkflow_resultTupleScheme();
      }
    }

    private static class updateWorkflow_resultTupleScheme extends TupleScheme<updateWorkflow_result> {

      @Override
      public void write(org.apache.thrift.protocol.TProtocol prot, updateWorkflow_result struct) throws org.apache.thrift.TException {
        TTupleProtocol oprot = (TTupleProtocol) prot;
        BitSet optionals = new BitSet();
        if (struct.isSetIre()) {
          optionals.set(0);
        }
        if (struct.isSetAce()) {
          optionals.set(1);
        }
        if (struct.isSetAse()) {
          optionals.set(2);
        }
        if (struct.isSetAe()) {
          optionals.set(3);
        }
        oprot.writeBitSet(optionals, 4);
        if (struct.isSetIre()) {
          struct.ire.write(oprot);
        }
        if (struct.isSetAce()) {
          struct.ace.write(oprot);
        }
        if (struct.isSetAse()) {
          struct.ase.write(oprot);
        }
        if (struct.isSetAe()) {
          struct.ae.write(oprot);
        }
      }

      @Override
      public void read(org.apache.thrift.protocol.TProtocol prot, updateWorkflow_result struct) throws org.apache.thrift.TException {
        TTupleProtocol iprot = (TTupleProtocol) prot;
        BitSet incoming = iprot.readBitSet(4);
        if (incoming.get(0)) {
          struct.ire = new org.apache.airavata.model.error.InvalidRequestException();
          struct.ire.read(iprot);
          struct.setIreIsSet(true);
        }
        if (incoming.get(1)) {
          struct.ace = new org.apache.airavata.model.error.AiravataClientException();
          struct.ace.read(iprot);
          struct.setAceIsSet(true);
        }
        if (incoming.get(2)) {
          struct.ase = new org.apache.airavata.model.error.AiravataSystemException();
          struct.ase.read(iprot);
          struct.setAseIsSet(true);
        }
        if (incoming.get(3)) {
          struct.ae = new org.apache.airavata.model.error.AuthorizationException();
          struct.ae.read(iprot);
          struct.setAeIsSet(true);
        }
      }
    }

  }

  public static class getWorkflowTemplateId_args implements org.apache.thrift.TBase<getWorkflowTemplateId_args, getWorkflowTemplateId_args._Fields>, java.io.Serializable, Cloneable, Comparable<getWorkflowTemplateId_args>   {
    private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("getWorkflowTemplateId_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 WORKFLOW_NAME_FIELD_DESC = new org.apache.thrift.protocol.TField("workflowName", org.apache.thrift.protocol.TType.STRING, (short)2);

    private static final Map<Class<? extends IScheme>, SchemeFactory> schemes = new HashMap<Class<? extends IScheme>, SchemeFactory>();
    static {
      schemes.put(StandardScheme.class, new getWorkflowTemplateId_argsStandardSchemeFactory());
      schemes.put(TupleScheme.class, new getWorkflowTemplateId_argsTupleSchemeFactory());
    }

    public org.apache.airavata.model.security.AuthzToken authzToken; // required
    public String workflowName; // required

    /** 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"),
      WORKFLOW_NAME((short)2, "workflowName");

      private static final Map<String, _Fields> byName = new HashMap<String, _Fields>();

      static {
        for (_Fields field : EnumSet.allOf(_Fields.class)) {
          byName.put(field.getFieldName(), field);
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, or null if its not found.
       */
      public static _Fields findByThriftId(int fieldId) {
        switch(fieldId) {
          case 1: // AUTHZ_TOKEN
            return AUTHZ_TOKEN;
          case 2: // WORKFLOW_NAME
            return WORKFLOW_NAME;
          default:
            return null;
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, throwing an exception
       * if it is not found.
       */
      public static _Fields findByThriftIdOrThrow(int fieldId) {
        _Fields fields = findByThriftId(fieldId);
        if (fields == null) throw new IllegalArgumentException("Field " + fieldId + " doesn't exist!");
        return fields;
      }

      /**
       * Find the _Fields constant that matches name, or null if its not found.
       */
      public static _Fields findByName(String name) {
        return byName.get(name);
      }

      private final short _thriftId;
      private final String _fieldName;

      _Fields(short thriftId, String fieldName) {
        _thriftId = thriftId;
        _fieldName = fieldName;
      }

      public short getThriftFieldId() {
        return _thriftId;
      }

      public String getFieldName() {
        return _fieldName;
      }
    }

    // isset id assignments
    public static final Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
    static {
      Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new EnumMap<_Fields, org.apache.thrift.meta_data.FieldMetaData>(_Fields.class);
      tmpMap.put(_Fields.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.WORKFLOW_NAME, new org.apache.thrift.meta_data.FieldMetaData("workflowName", org.apache.thrift.TFieldRequirementType.REQUIRED, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING)));
      metaDataMap = Collections.unmodifiableMap(tmpMap);
      org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(getWorkflowTemplateId_args.class, metaDataMap);
    }

    public getWorkflowTemplateId_args() {
    }

    public getWorkflowTemplateId_args(
      org.apache.airavata.model.security.AuthzToken authzToken,
      String workflowName)
    {
      this();
      this.authzToken = authzToken;
      this.workflowName = workflowName;
    }

    /**
     * Performs a deep copy on <i>other</i>.
     */
    public getWorkflowTemplateId_args(getWorkflowTemplateId_args other) {
      if (other.isSetAuthzToken()) {
        this.authzToken = new org.apache.airavata.model.security.AuthzToken(other.authzToken);
      }
      if (other.isSetWorkflowName()) {
        this.workflowName = other.workflowName;
      }
    }

    public getWorkflowTemplateId_args deepCopy() {
      return new getWorkflowTemplateId_args(this);
    }

    @Override
    public void clear() {
      this.authzToken = null;
      this.workflowName = null;
    }

    public org.apache.airavata.model.security.AuthzToken getAuthzToken() {
      return this.authzToken;
    }

    public getWorkflowTemplateId_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 String getWorkflowName() {
      return this.workflowName;
    }

    public getWorkflowTemplateId_args setWorkflowName(String workflowName) {
      this.workflowName = workflowName;
      return this;
    }

    public void unsetWorkflowName() {
      this.workflowName = null;
    }

    /** Returns true if field workflowName is set (has been assigned a value) and false otherwise */
    public boolean isSetWorkflowName() {
      return this.workflowName != null;
    }

    public void setWorkflowNameIsSet(boolean value) {
      if (!value) {
        this.workflowName = null;
      }
    }

    public void setFieldValue(_Fields field, Object value) {
      switch (field) {
      case AUTHZ_TOKEN:
        if (value == null) {
          unsetAuthzToken();
        } else {
          setAuthzToken((org.apache.airavata.model.security.AuthzToken)value);
        }
        break;

      case WORKFLOW_NAME:
        if (value == null) {
          unsetWorkflowName();
        } else {
          setWorkflowName((String)value);
        }
        break;

      }
    }

    public Object getFieldValue(_Fields field) {
      switch (field) {
      case AUTHZ_TOKEN:
        return getAuthzToken();

      case WORKFLOW_NAME:
        return getWorkflowName();

      }
      throw new IllegalStateException();
    }

    /** Returns true if field corresponding to fieldID is set (has been assigned a value) and false otherwise */
    public boolean isSet(_Fields field) {
      if (field == null) {
        throw new IllegalArgumentException();
      }

      switch (field) {
      case AUTHZ_TOKEN:
        return isSetAuthzToken();
      case WORKFLOW_NAME:
        return isSetWorkflowName();
      }
      throw new IllegalStateException();
    }

    @Override
    public boolean equals(Object that) {
      if (that == null)
        return false;
      if (that instanceof getWorkflowTemplateId_args)
        return this.equals((getWorkflowTemplateId_args)that);
      return false;
    }

    public boolean equals(getWorkflowTemplateId_args that) {
      if (that == null)
        return false;

      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_workflowName = true && this.isSetWorkflowName();
      boolean that_present_workflowName = true && that.isSetWorkflowName();
      if (this_present_workflowName || that_present_workflowName) {
        if (!(this_present_workflowName && that_present_workflowName))
          return false;
        if (!this.workflowName.equals(that.workflowName))
          return false;
      }

      return true;
    }

    @Override
    public int hashCode() {
      List<Object> list = new ArrayList<Object>();

      boolean present_authzToken = true && (isSetAuthzToken());
      list.add(present_authzToken);
      if (present_authzToken)
        list.add(authzToken);

      boolean present_workflowName = true && (isSetWorkflowName());
      list.add(present_workflowName);
      if (present_workflowName)
        list.add(workflowName);

      return list.hashCode();
    }

    @Override
    public int compareTo(getWorkflowTemplateId_args other) {
      if (!getClass().equals(other.getClass())) {
        return getClass().getName().compareTo(other.getClass().getName());
      }

      int lastComparison = 0;

      lastComparison = 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 = Boolean.valueOf(isSetWorkflowName()).compareTo(other.isSetWorkflowName());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetWorkflowName()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.workflowName, other.workflowName);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      return 0;
    }

    public _Fields fieldForId(int fieldId) {
      return _Fields.findByThriftId(fieldId);
    }

    public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
      schemes.get(iprot.getScheme()).getScheme().read(iprot, this);
    }

    public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException {
      schemes.get(oprot.getScheme()).getScheme().write(oprot, this);
    }

    @Override
    public String toString() {
      StringBuilder sb = new StringBuilder("getWorkflowTemplateId_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("workflowName:");
      if (this.workflowName == null) {
        sb.append("null");
      } else {
        sb.append(this.workflowName);
      }
      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 (workflowName == null) {
        throw new org.apache.thrift.protocol.TProtocolException("Required field 'workflowName' 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, 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 getWorkflowTemplateId_argsStandardSchemeFactory implements SchemeFactory {
      public getWorkflowTemplateId_argsStandardScheme getScheme() {
        return new getWorkflowTemplateId_argsStandardScheme();
      }
    }

    private static class getWorkflowTemplateId_argsStandardScheme extends StandardScheme<getWorkflowTemplateId_args> {

      public void read(org.apache.thrift.protocol.TProtocol iprot, getWorkflowTemplateId_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: // WORKFLOW_NAME
              if (schemeField.type == org.apache.thrift.protocol.TType.STRING) {
                struct.workflowName = iprot.readString();
                struct.setWorkflowNameIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            default:
              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
          }
          iprot.readFieldEnd();
        }
        iprot.readStructEnd();

        // check for required fields of primitive type, which can't be checked in the validate method
        struct.validate();
      }

      public void write(org.apache.thrift.protocol.TProtocol oprot, getWorkflowTemplateId_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.workflowName != null) {
          oprot.writeFieldBegin(WORKFLOW_NAME_FIELD_DESC);
          oprot.writeString(struct.workflowName);
          oprot.writeFieldEnd();
        }
        oprot.writeFieldStop();
        oprot.writeStructEnd();
      }

    }

    private static class getWorkflowTemplateId_argsTupleSchemeFactory implements SchemeFactory {
      public getWorkflowTemplateId_argsTupleScheme getScheme() {
        return new getWorkflowTemplateId_argsTupleScheme();
      }
    }

    private static class getWorkflowTemplateId_argsTupleScheme extends TupleScheme<getWorkflowTemplateId_args> {

      @Override
      public void write(org.apache.thrift.protocol.TProtocol prot, getWorkflowTemplateId_args struct) throws org.apache.thrift.TException {
        TTupleProtocol oprot = (TTupleProtocol) prot;
        struct.authzToken.write(oprot);
        oprot.writeString(struct.workflowName);
      }

      @Override
      public void read(org.apache.thrift.protocol.TProtocol prot, getWorkflowTemplateId_args struct) throws org.apache.thrift.TException {
        TTupleProtocol iprot = (TTupleProtocol) prot;
        struct.authzToken = new org.apache.airavata.model.security.AuthzToken();
        struct.authzToken.read(iprot);
        struct.setAuthzTokenIsSet(true);
        struct.workflowName = iprot.readString();
        struct.setWorkflowNameIsSet(true);
      }
    }

  }

  public static class getWorkflowTemplateId_result implements org.apache.thrift.TBase<getWorkflowTemplateId_result, getWorkflowTemplateId_result._Fields>, java.io.Serializable, Cloneable, Comparable<getWorkflowTemplateId_result>   {
    private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("getWorkflowTemplateId_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 IRE_FIELD_DESC = new org.apache.thrift.protocol.TField("ire", org.apache.thrift.protocol.TType.STRUCT, (short)1);
    private static final org.apache.thrift.protocol.TField ACE_FIELD_DESC = new org.apache.thrift.protocol.TField("ace", org.apache.thrift.protocol.TType.STRUCT, (short)2);
    private static final org.apache.thrift.protocol.TField ASE_FIELD_DESC = new org.apache.thrift.protocol.TField("ase", org.apache.thrift.protocol.TType.STRUCT, (short)3);
    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)4);

    private static final Map<Class<? extends IScheme>, SchemeFactory> schemes = new HashMap<Class<? extends IScheme>, SchemeFactory>();
    static {
      schemes.put(StandardScheme.class, new getWorkflowTemplateId_resultStandardSchemeFactory());
      schemes.put(TupleScheme.class, new getWorkflowTemplateId_resultTupleSchemeFactory());
    }

    public String success; // required
    public org.apache.airavata.model.error.InvalidRequestException ire; // required
    public org.apache.airavata.model.error.AiravataClientException ace; // required
    public org.apache.airavata.model.error.AiravataSystemException ase; // 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"),
      IRE((short)1, "ire"),
      ACE((short)2, "ace"),
      ASE((short)3, "ase"),
      AE((short)4, "ae");

      private static final Map<String, _Fields> byName = new HashMap<String, _Fields>();

      static {
        for (_Fields field : EnumSet.allOf(_Fields.class)) {
          byName.put(field.getFieldName(), field);
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, or null if its not found.
       */
      public static _Fields findByThriftId(int fieldId) {
        switch(fieldId) {
          case 0: // SUCCESS
            return SUCCESS;
          case 1: // IRE
            return IRE;
          case 2: // ACE
            return ACE;
          case 3: // ASE
            return ASE;
          case 4: // 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 IllegalArgumentException("Field " + fieldId + " doesn't exist!");
        return fields;
      }

      /**
       * Find the _Fields constant that matches name, or null if its not found.
       */
      public static _Fields findByName(String name) {
        return byName.get(name);
      }

      private final short _thriftId;
      private final String _fieldName;

      _Fields(short thriftId, String fieldName) {
        _thriftId = thriftId;
        _fieldName = fieldName;
      }

      public short getThriftFieldId() {
        return _thriftId;
      }

      public String getFieldName() {
        return _fieldName;
      }
    }

    // isset id assignments
    public static final Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
    static {
      Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new EnumMap<_Fields, org.apache.thrift.meta_data.FieldMetaData>(_Fields.class);
      tmpMap.put(_Fields.SUCCESS, new org.apache.thrift.meta_data.FieldMetaData("success", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING)));
      tmpMap.put(_Fields.IRE, new org.apache.thrift.meta_data.FieldMetaData("ire", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRUCT)));
      tmpMap.put(_Fields.ACE, new org.apache.thrift.meta_data.FieldMetaData("ace", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRUCT)));
      tmpMap.put(_Fields.ASE, new org.apache.thrift.meta_data.FieldMetaData("ase", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRUCT)));
      tmpMap.put(_Fields.AE, new org.apache.thrift.meta_data.FieldMetaData("ae", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRUCT)));
      metaDataMap = Collections.unmodifiableMap(tmpMap);
      org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(getWorkflowTemplateId_result.class, metaDataMap);
    }

    public getWorkflowTemplateId_result() {
    }

    public getWorkflowTemplateId_result(
      String success,
      org.apache.airavata.model.error.InvalidRequestException ire,
      org.apache.airavata.model.error.AiravataClientException ace,
      org.apache.airavata.model.error.AiravataSystemException ase,
      org.apache.airavata.model.error.AuthorizationException ae)
    {
      this();
      this.success = success;
      this.ire = ire;
      this.ace = ace;
      this.ase = ase;
      this.ae = ae;
    }

    /**
     * Performs a deep copy on <i>other</i>.
     */
    public getWorkflowTemplateId_result(getWorkflowTemplateId_result other) {
      if (other.isSetSuccess()) {
        this.success = other.success;
      }
      if (other.isSetIre()) {
        this.ire = new org.apache.airavata.model.error.InvalidRequestException(other.ire);
      }
      if (other.isSetAce()) {
        this.ace = new org.apache.airavata.model.error.AiravataClientException(other.ace);
      }
      if (other.isSetAse()) {
        this.ase = new org.apache.airavata.model.error.AiravataSystemException(other.ase);
      }
      if (other.isSetAe()) {
        this.ae = new org.apache.airavata.model.error.AuthorizationException(other.ae);
      }
    }

    public getWorkflowTemplateId_result deepCopy() {
      return new getWorkflowTemplateId_result(this);
    }

    @Override
    public void clear() {
      this.success = null;
      this.ire = null;
      this.ace = null;
      this.ase = null;
      this.ae = null;
    }

    public String getSuccess() {
      return this.success;
    }

    public getWorkflowTemplateId_result setSuccess(String success) {
      this.success = success;
      return this;
    }

    public void unsetSuccess() {
      this.success = null;
    }

    /** Returns true if field success is set (has been assigned a value) and false otherwise */
    public boolean isSetSuccess() {
      return this.success != null;
    }

    public void setSuccessIsSet(boolean value) {
      if (!value) {
        this.success = null;
      }
    }

    public org.apache.airavata.model.error.InvalidRequestException getIre() {
      return this.ire;
    }

    public getWorkflowTemplateId_result setIre(org.apache.airavata.model.error.InvalidRequestException ire) {
      this.ire = ire;
      return this;
    }

    public void unsetIre() {
      this.ire = null;
    }

    /** Returns true if field ire is set (has been assigned a value) and false otherwise */
    public boolean isSetIre() {
      return this.ire != null;
    }

    public void setIreIsSet(boolean value) {
      if (!value) {
        this.ire = null;
      }
    }

    public org.apache.airavata.model.error.AiravataClientException getAce() {
      return this.ace;
    }

    public getWorkflowTemplateId_result setAce(org.apache.airavata.model.error.AiravataClientException ace) {
      this.ace = ace;
      return this;
    }

    public void unsetAce() {
      this.ace = null;
    }

    /** Returns true if field ace is set (has been assigned a value) and false otherwise */
    public boolean isSetAce() {
      return this.ace != null;
    }

    public void setAceIsSet(boolean value) {
      if (!value) {
        this.ace = null;
      }
    }

    public org.apache.airavata.model.error.AiravataSystemException getAse() {
      return this.ase;
    }

    public getWorkflowTemplateId_result setAse(org.apache.airavata.model.error.AiravataSystemException ase) {
      this.ase = ase;
      return this;
    }

    public void unsetAse() {
      this.ase = null;
    }

    /** Returns true if field ase is set (has been assigned a value) and false otherwise */
    public boolean isSetAse() {
      return this.ase != null;
    }

    public void setAseIsSet(boolean value) {
      if (!value) {
        this.ase = null;
      }
    }

    public org.apache.airavata.model.error.AuthorizationException getAe() {
      return this.ae;
    }

    public getWorkflowTemplateId_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, Object value) {
      switch (field) {
      case SUCCESS:
        if (value == null) {
          unsetSuccess();
        } else {
          setSuccess((String)value);
        }
        break;

      case IRE:
        if (value == null) {
          unsetIre();
        } else {
          setIre((org.apache.airavata.model.error.InvalidRequestException)value);
        }
        break;

      case ACE:
        if (value == null) {
          unsetAce();
        } else {
          setAce((org.apache.airavata.model.error.AiravataClientException)value);
        }
        break;

      case ASE:
        if (value == null) {
          unsetAse();
        } else {
          setAse((org.apache.airavata.model.error.AiravataSystemException)value);
        }
        break;

      case AE:
        if (value == null) {
          unsetAe();
        } else {
          setAe((org.apache.airavata.model.error.AuthorizationException)value);
        }
        break;

      }
    }

    public Object getFieldValue(_Fields field) {
      switch (field) {
      case SUCCESS:
        return getSuccess();

      case IRE:
        return getIre();

      case ACE:
        return getAce();

      case ASE:
        return getAse();

      case AE:
        return getAe();

      }
      throw new IllegalStateException();
    }

    /** Returns true if field corresponding to fieldID is set (has been assigned a value) and false otherwise */
    public boolean isSet(_Fields field) {
      if (field == null) {
        throw new IllegalArgumentException();
      }

      switch (field) {
      case SUCCESS:
        return isSetSuccess();
      case IRE:
        return isSetIre();
      case ACE:
        return isSetAce();
      case ASE:
        return isSetAse();
      case AE:
        return isSetAe();
      }
      throw new IllegalStateException();
    }

    @Override
    public boolean equals(Object that) {
      if (that == null)
        return false;
      if (that instanceof getWorkflowTemplateId_result)
        return this.equals((getWorkflowTemplateId_result)that);
      return false;
    }

    public boolean equals(getWorkflowTemplateId_result that) {
      if (that == null)
        return false;

      boolean this_present_success = true && this.isSetSuccess();
      boolean that_present_success = true && that.isSetSuccess();
      if (this_present_success || that_present_success) {
        if (!(this_present_success && that_present_success))
          return false;
        if (!this.success.equals(that.success))
          return false;
      }

      boolean this_present_ire = true && this.isSetIre();
      boolean that_present_ire = true && that.isSetIre();
      if (this_present_ire || that_present_ire) {
        if (!(this_present_ire && that_present_ire))
          return false;
        if (!this.ire.equals(that.ire))
          return false;
      }

      boolean this_present_ace = true && this.isSetAce();
      boolean that_present_ace = true && that.isSetAce();
      if (this_present_ace || that_present_ace) {
        if (!(this_present_ace && that_present_ace))
          return false;
        if (!this.ace.equals(that.ace))
          return false;
      }

      boolean this_present_ase = true && this.isSetAse();
      boolean that_present_ase = true && that.isSetAse();
      if (this_present_ase || that_present_ase) {
        if (!(this_present_ase && that_present_ase))
          return false;
        if (!this.ase.equals(that.ase))
          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() {
      List<Object> list = new ArrayList<Object>();

      boolean present_success = true && (isSetSuccess());
      list.add(present_success);
      if (present_success)
        list.add(success);

      boolean present_ire = true && (isSetIre());
      list.add(present_ire);
      if (present_ire)
        list.add(ire);

      boolean present_ace = true && (isSetAce());
      list.add(present_ace);
      if (present_ace)
        list.add(ace);

      boolean present_ase = true && (isSetAse());
      list.add(present_ase);
      if (present_ase)
        list.add(ase);

      boolean present_ae = true && (isSetAe());
      list.add(present_ae);
      if (present_ae)
        list.add(ae);

      return list.hashCode();
    }

    @Override
    public int compareTo(getWorkflowTemplateId_result other) {
      if (!getClass().equals(other.getClass())) {
        return getClass().getName().compareTo(other.getClass().getName());
      }

      int lastComparison = 0;

      lastComparison = Boolean.valueOf(isSetSuccess()).compareTo(other.isSetSuccess());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetSuccess()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.success, other.success);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = Boolean.valueOf(isSetIre()).compareTo(other.isSetIre());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetIre()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.ire, other.ire);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = Boolean.valueOf(isSetAce()).compareTo(other.isSetAce());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetAce()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.ace, other.ace);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = Boolean.valueOf(isSetAse()).compareTo(other.isSetAse());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetAse()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.ase, other.ase);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = 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 {
      schemes.get(iprot.getScheme()).getScheme().read(iprot, this);
    }

    public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException {
      schemes.get(oprot.getScheme()).getScheme().write(oprot, this);
      }

    @Override
    public String toString() {
      StringBuilder sb = new StringBuilder("getWorkflowTemplateId_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("ire:");
      if (this.ire == null) {
        sb.append("null");
      } else {
        sb.append(this.ire);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("ace:");
      if (this.ace == null) {
        sb.append("null");
      } else {
        sb.append(this.ace);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("ase:");
      if (this.ase == null) {
        sb.append("null");
      } else {
        sb.append(this.ase);
      }
      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, 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 getWorkflowTemplateId_resultStandardSchemeFactory implements SchemeFactory {
      public getWorkflowTemplateId_resultStandardScheme getScheme() {
        return new getWorkflowTemplateId_resultStandardScheme();
      }
    }

    private static class getWorkflowTemplateId_resultStandardScheme extends StandardScheme<getWorkflowTemplateId_result> {

      public void read(org.apache.thrift.protocol.TProtocol iprot, getWorkflowTemplateId_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: // IRE
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.ire = new org.apache.airavata.model.error.InvalidRequestException();
                struct.ire.read(iprot);
                struct.setIreIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 2: // ACE
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.ace = new org.apache.airavata.model.error.AiravataClientException();
                struct.ace.read(iprot);
                struct.setAceIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 3: // ASE
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.ase = new org.apache.airavata.model.error.AiravataSystemException();
                struct.ase.read(iprot);
                struct.setAseIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 4: // 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, getWorkflowTemplateId_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.ire != null) {
          oprot.writeFieldBegin(IRE_FIELD_DESC);
          struct.ire.write(oprot);
          oprot.writeFieldEnd();
        }
        if (struct.ace != null) {
          oprot.writeFieldBegin(ACE_FIELD_DESC);
          struct.ace.write(oprot);
          oprot.writeFieldEnd();
        }
        if (struct.ase != null) {
          oprot.writeFieldBegin(ASE_FIELD_DESC);
          struct.ase.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 getWorkflowTemplateId_resultTupleSchemeFactory implements SchemeFactory {
      public getWorkflowTemplateId_resultTupleScheme getScheme() {
        return new getWorkflowTemplateId_resultTupleScheme();
      }
    }

    private static class getWorkflowTemplateId_resultTupleScheme extends TupleScheme<getWorkflowTemplateId_result> {

      @Override
      public void write(org.apache.thrift.protocol.TProtocol prot, getWorkflowTemplateId_result struct) throws org.apache.thrift.TException {
        TTupleProtocol oprot = (TTupleProtocol) prot;
        BitSet optionals = new BitSet();
        if (struct.isSetSuccess()) {
          optionals.set(0);
        }
        if (struct.isSetIre()) {
          optionals.set(1);
        }
        if (struct.isSetAce()) {
          optionals.set(2);
        }
        if (struct.isSetAse()) {
          optionals.set(3);
        }
        if (struct.isSetAe()) {
          optionals.set(4);
        }
        oprot.writeBitSet(optionals, 5);
        if (struct.isSetSuccess()) {
          oprot.writeString(struct.success);
        }
        if (struct.isSetIre()) {
          struct.ire.write(oprot);
        }
        if (struct.isSetAce()) {
          struct.ace.write(oprot);
        }
        if (struct.isSetAse()) {
          struct.ase.write(oprot);
        }
        if (struct.isSetAe()) {
          struct.ae.write(oprot);
        }
      }

      @Override
      public void read(org.apache.thrift.protocol.TProtocol prot, getWorkflowTemplateId_result struct) throws org.apache.thrift.TException {
        TTupleProtocol iprot = (TTupleProtocol) prot;
        BitSet incoming = iprot.readBitSet(5);
        if (incoming.get(0)) {
          struct.success = iprot.readString();
          struct.setSuccessIsSet(true);
        }
        if (incoming.get(1)) {
          struct.ire = new org.apache.airavata.model.error.InvalidRequestException();
          struct.ire.read(iprot);
          struct.setIreIsSet(true);
        }
        if (incoming.get(2)) {
          struct.ace = new org.apache.airavata.model.error.AiravataClientException();
          struct.ace.read(iprot);
          struct.setAceIsSet(true);
        }
        if (incoming.get(3)) {
          struct.ase = new org.apache.airavata.model.error.AiravataSystemException();
          struct.ase.read(iprot);
          struct.setAseIsSet(true);
        }
        if (incoming.get(4)) {
          struct.ae = new org.apache.airavata.model.error.AuthorizationException();
          struct.ae.read(iprot);
          struct.setAeIsSet(true);
        }
      }
    }

  }

  public static class isWorkflowExistWithName_args implements org.apache.thrift.TBase<isWorkflowExistWithName_args, isWorkflowExistWithName_args._Fields>, java.io.Serializable, Cloneable, Comparable<isWorkflowExistWithName_args>   {
    private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("isWorkflowExistWithName_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 WORKFLOW_NAME_FIELD_DESC = new org.apache.thrift.protocol.TField("workflowName", org.apache.thrift.protocol.TType.STRING, (short)2);

    private static final Map<Class<? extends IScheme>, SchemeFactory> schemes = new HashMap<Class<? extends IScheme>, SchemeFactory>();
    static {
      schemes.put(StandardScheme.class, new isWorkflowExistWithName_argsStandardSchemeFactory());
      schemes.put(TupleScheme.class, new isWorkflowExistWithName_argsTupleSchemeFactory());
    }

    public org.apache.airavata.model.security.AuthzToken authzToken; // required
    public String workflowName; // required

    /** 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"),
      WORKFLOW_NAME((short)2, "workflowName");

      private static final Map<String, _Fields> byName = new HashMap<String, _Fields>();

      static {
        for (_Fields field : EnumSet.allOf(_Fields.class)) {
          byName.put(field.getFieldName(), field);
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, or null if its not found.
       */
      public static _Fields findByThriftId(int fieldId) {
        switch(fieldId) {
          case 1: // AUTHZ_TOKEN
            return AUTHZ_TOKEN;
          case 2: // WORKFLOW_NAME
            return WORKFLOW_NAME;
          default:
            return null;
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, throwing an exception
       * if it is not found.
       */
      public static _Fields findByThriftIdOrThrow(int fieldId) {
        _Fields fields = findByThriftId(fieldId);
        if (fields == null) throw new IllegalArgumentException("Field " + fieldId + " doesn't exist!");
        return fields;
      }

      /**
       * Find the _Fields constant that matches name, or null if its not found.
       */
      public static _Fields findByName(String name) {
        return byName.get(name);
      }

      private final short _thriftId;
      private final String _fieldName;

      _Fields(short thriftId, String fieldName) {
        _thriftId = thriftId;
        _fieldName = fieldName;
      }

      public short getThriftFieldId() {
        return _thriftId;
      }

      public String getFieldName() {
        return _fieldName;
      }
    }

    // isset id assignments
    public static final Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
    static {
      Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new EnumMap<_Fields, org.apache.thrift.meta_data.FieldMetaData>(_Fields.class);
      tmpMap.put(_Fields.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.WORKFLOW_NAME, new org.apache.thrift.meta_data.FieldMetaData("workflowName", org.apache.thrift.TFieldRequirementType.REQUIRED, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING)));
      metaDataMap = Collections.unmodifiableMap(tmpMap);
      org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(isWorkflowExistWithName_args.class, metaDataMap);
    }

    public isWorkflowExistWithName_args() {
    }

    public isWorkflowExistWithName_args(
      org.apache.airavata.model.security.AuthzToken authzToken,
      String workflowName)
    {
      this();
      this.authzToken = authzToken;
      this.workflowName = workflowName;
    }

    /**
     * Performs a deep copy on <i>other</i>.
     */
    public isWorkflowExistWithName_args(isWorkflowExistWithName_args other) {
      if (other.isSetAuthzToken()) {
        this.authzToken = new org.apache.airavata.model.security.AuthzToken(other.authzToken);
      }
      if (other.isSetWorkflowName()) {
        this.workflowName = other.workflowName;
      }
    }

    public isWorkflowExistWithName_args deepCopy() {
      return new isWorkflowExistWithName_args(this);
    }

    @Override
    public void clear() {
      this.authzToken = null;
      this.workflowName = null;
    }

    public org.apache.airavata.model.security.AuthzToken getAuthzToken() {
      return this.authzToken;
    }

    public isWorkflowExistWithName_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 String getWorkflowName() {
      return this.workflowName;
    }

    public isWorkflowExistWithName_args setWorkflowName(String workflowName) {
      this.workflowName = workflowName;
      return this;
    }

    public void unsetWorkflowName() {
      this.workflowName = null;
    }

    /** Returns true if field workflowName is set (has been assigned a value) and false otherwise */
    public boolean isSetWorkflowName() {
      return this.workflowName != null;
    }

    public void setWorkflowNameIsSet(boolean value) {
      if (!value) {
        this.workflowName = null;
      }
    }

    public void setFieldValue(_Fields field, Object value) {
      switch (field) {
      case AUTHZ_TOKEN:
        if (value == null) {
          unsetAuthzToken();
        } else {
          setAuthzToken((org.apache.airavata.model.security.AuthzToken)value);
        }
        break;

      case WORKFLOW_NAME:
        if (value == null) {
          unsetWorkflowName();
        } else {
          setWorkflowName((String)value);
        }
        break;

      }
    }

    public Object getFieldValue(_Fields field) {
      switch (field) {
      case AUTHZ_TOKEN:
        return getAuthzToken();

      case WORKFLOW_NAME:
        return getWorkflowName();

      }
      throw new IllegalStateException();
    }

    /** Returns true if field corresponding to fieldID is set (has been assigned a value) and false otherwise */
    public boolean isSet(_Fields field) {
      if (field == null) {
        throw new IllegalArgumentException();
      }

      switch (field) {
      case AUTHZ_TOKEN:
        return isSetAuthzToken();
      case WORKFLOW_NAME:
        return isSetWorkflowName();
      }
      throw new IllegalStateException();
    }

    @Override
    public boolean equals(Object that) {
      if (that == null)
        return false;
      if (that instanceof isWorkflowExistWithName_args)
        return this.equals((isWorkflowExistWithName_args)that);
      return false;
    }

    public boolean equals(isWorkflowExistWithName_args that) {
      if (that == null)
        return false;

      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_workflowName = true && this.isSetWorkflowName();
      boolean that_present_workflowName = true && that.isSetWorkflowName();
      if (this_present_workflowName || that_present_workflowName) {
        if (!(this_present_workflowName && that_present_workflowName))
          return false;
        if (!this.workflowName.equals(that.workflowName))
          return false;
      }

      return true;
    }

    @Override
    public int hashCode() {
      List<Object> list = new ArrayList<Object>();

      boolean present_authzToken = true && (isSetAuthzToken());
      list.add(present_authzToken);
      if (present_authzToken)
        list.add(authzToken);

      boolean present_workflowName = true && (isSetWorkflowName());
      list.add(present_workflowName);
      if (present_workflowName)
        list.add(workflowName);

      return list.hashCode();
    }

    @Override
    public int compareTo(isWorkflowExistWithName_args other) {
      if (!getClass().equals(other.getClass())) {
        return getClass().getName().compareTo(other.getClass().getName());
      }

      int lastComparison = 0;

      lastComparison = 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 = Boolean.valueOf(isSetWorkflowName()).compareTo(other.isSetWorkflowName());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetWorkflowName()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.workflowName, other.workflowName);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      return 0;
    }

    public _Fields fieldForId(int fieldId) {
      return _Fields.findByThriftId(fieldId);
    }

    public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
      schemes.get(iprot.getScheme()).getScheme().read(iprot, this);
    }

    public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException {
      schemes.get(oprot.getScheme()).getScheme().write(oprot, this);
    }

    @Override
    public String toString() {
      StringBuilder sb = new StringBuilder("isWorkflowExistWithName_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("workflowName:");
      if (this.workflowName == null) {
        sb.append("null");
      } else {
        sb.append(this.workflowName);
      }
      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 (workflowName == null) {
        throw new org.apache.thrift.protocol.TProtocolException("Required field 'workflowName' 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, 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 isWorkflowExistWithName_argsStandardSchemeFactory implements SchemeFactory {
      public isWorkflowExistWithName_argsStandardScheme getScheme() {
        return new isWorkflowExistWithName_argsStandardScheme();
      }
    }

    private static class isWorkflowExistWithName_argsStandardScheme extends StandardScheme<isWorkflowExistWithName_args> {

      public void read(org.apache.thrift.protocol.TProtocol iprot, isWorkflowExistWithName_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: // WORKFLOW_NAME
              if (schemeField.type == org.apache.thrift.protocol.TType.STRING) {
                struct.workflowName = iprot.readString();
                struct.setWorkflowNameIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            default:
              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
          }
          iprot.readFieldEnd();
        }
        iprot.readStructEnd();

        // check for required fields of primitive type, which can't be checked in the validate method
        struct.validate();
      }

      public void write(org.apache.thrift.protocol.TProtocol oprot, isWorkflowExistWithName_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.workflowName != null) {
          oprot.writeFieldBegin(WORKFLOW_NAME_FIELD_DESC);
          oprot.writeString(struct.workflowName);
          oprot.writeFieldEnd();
        }
        oprot.writeFieldStop();
        oprot.writeStructEnd();
      }

    }

    private static class isWorkflowExistWithName_argsTupleSchemeFactory implements SchemeFactory {
      public isWorkflowExistWithName_argsTupleScheme getScheme() {
        return new isWorkflowExistWithName_argsTupleScheme();
      }
    }

    private static class isWorkflowExistWithName_argsTupleScheme extends TupleScheme<isWorkflowExistWithName_args> {

      @Override
      public void write(org.apache.thrift.protocol.TProtocol prot, isWorkflowExistWithName_args struct) throws org.apache.thrift.TException {
        TTupleProtocol oprot = (TTupleProtocol) prot;
        struct.authzToken.write(oprot);
        oprot.writeString(struct.workflowName);
      }

      @Override
      public void read(org.apache.thrift.protocol.TProtocol prot, isWorkflowExistWithName_args struct) throws org.apache.thrift.TException {
        TTupleProtocol iprot = (TTupleProtocol) prot;
        struct.authzToken = new org.apache.airavata.model.security.AuthzToken();
        struct.authzToken.read(iprot);
        struct.setAuthzTokenIsSet(true);
        struct.workflowName = iprot.readString();
        struct.setWorkflowNameIsSet(true);
      }
    }

  }

  public static class isWorkflowExistWithName_result implements org.apache.thrift.TBase<isWorkflowExistWithName_result, isWorkflowExistWithName_result._Fields>, java.io.Serializable, Cloneable, Comparable<isWorkflowExistWithName_result>   {
    private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("isWorkflowExistWithName_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 IRE_FIELD_DESC = new org.apache.thrift.protocol.TField("ire", org.apache.thrift.protocol.TType.STRUCT, (short)1);
    private static final org.apache.thrift.protocol.TField ACE_FIELD_DESC = new org.apache.thrift.protocol.TField("ace", org.apache.thrift.protocol.TType.STRUCT, (short)2);
    private static final org.apache.thrift.protocol.TField ASE_FIELD_DESC = new org.apache.thrift.protocol.TField("ase", org.apache.thrift.protocol.TType.STRUCT, (short)3);
    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)4);

    private static final Map<Class<? extends IScheme>, SchemeFactory> schemes = new HashMap<Class<? extends IScheme>, SchemeFactory>();
    static {
      schemes.put(StandardScheme.class, new isWorkflowExistWithName_resultStandardSchemeFactory());
      schemes.put(TupleScheme.class, new isWorkflowExistWithName_resultTupleSchemeFactory());
    }

    public boolean success; // required
    public org.apache.airavata.model.error.InvalidRequestException ire; // required
    public org.apache.airavata.model.error.AiravataClientException ace; // required
    public org.apache.airavata.model.error.AiravataSystemException ase; // 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"),
      IRE((short)1, "ire"),
      ACE((short)2, "ace"),
      ASE((short)3, "ase"),
      AE((short)4, "ae");

      private static final Map<String, _Fields> byName = new HashMap<String, _Fields>();

      static {
        for (_Fields field : EnumSet.allOf(_Fields.class)) {
          byName.put(field.getFieldName(), field);
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, or null if its not found.
       */
      public static _Fields findByThriftId(int fieldId) {
        switch(fieldId) {
          case 0: // SUCCESS
            return SUCCESS;
          case 1: // IRE
            return IRE;
          case 2: // ACE
            return ACE;
          case 3: // ASE
            return ASE;
          case 4: // 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 IllegalArgumentException("Field " + fieldId + " doesn't exist!");
        return fields;
      }

      /**
       * Find the _Fields constant that matches name, or null if its not found.
       */
      public static _Fields findByName(String name) {
        return byName.get(name);
      }

      private final short _thriftId;
      private final String _fieldName;

      _Fields(short thriftId, String fieldName) {
        _thriftId = thriftId;
        _fieldName = fieldName;
      }

      public short getThriftFieldId() {
        return _thriftId;
      }

      public String getFieldName() {
        return _fieldName;
      }
    }

    // isset id assignments
    private static final int __SUCCESS_ISSET_ID = 0;
    private byte __isset_bitfield = 0;
    public static final Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
    static {
      Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new EnumMap<_Fields, org.apache.thrift.meta_data.FieldMetaData>(_Fields.class);
      tmpMap.put(_Fields.SUCCESS, new org.apache.thrift.meta_data.FieldMetaData("success", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.BOOL)));
      tmpMap.put(_Fields.IRE, new org.apache.thrift.meta_data.FieldMetaData("ire", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRUCT)));
      tmpMap.put(_Fields.ACE, new org.apache.thrift.meta_data.FieldMetaData("ace", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRUCT)));
      tmpMap.put(_Fields.ASE, new org.apache.thrift.meta_data.FieldMetaData("ase", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRUCT)));
      tmpMap.put(_Fields.AE, new org.apache.thrift.meta_data.FieldMetaData("ae", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRUCT)));
      metaDataMap = Collections.unmodifiableMap(tmpMap);
      org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(isWorkflowExistWithName_result.class, metaDataMap);
    }

    public isWorkflowExistWithName_result() {
    }

    public isWorkflowExistWithName_result(
      boolean success,
      org.apache.airavata.model.error.InvalidRequestException ire,
      org.apache.airavata.model.error.AiravataClientException ace,
      org.apache.airavata.model.error.AiravataSystemException ase,
      org.apache.airavata.model.error.AuthorizationException ae)
    {
      this();
      this.success = success;
      setSuccessIsSet(true);
      this.ire = ire;
      this.ace = ace;
      this.ase = ase;
      this.ae = ae;
    }

    /**
     * Performs a deep copy on <i>other</i>.
     */
    public isWorkflowExistWithName_result(isWorkflowExistWithName_result other) {
      __isset_bitfield = other.__isset_bitfield;
      this.success = other.success;
      if (other.isSetIre()) {
        this.ire = new org.apache.airavata.model.error.InvalidRequestException(other.ire);
      }
      if (other.isSetAce()) {
        this.ace = new org.apache.airavata.model.error.AiravataClientException(other.ace);
      }
      if (other.isSetAse()) {
        this.ase = new org.apache.airavata.model.error.AiravataSystemException(other.ase);
      }
      if (other.isSetAe()) {
        this.ae = new org.apache.airavata.model.error.AuthorizationException(other.ae);
      }
    }

    public isWorkflowExistWithName_result deepCopy() {
      return new isWorkflowExistWithName_result(this);
    }

    @Override
    public void clear() {
      setSuccessIsSet(false);
      this.success = false;
      this.ire = null;
      this.ace = null;
      this.ase = null;
      this.ae = null;
    }

    public boolean isSuccess() {
      return this.success;
    }

    public isWorkflowExistWithName_result setSuccess(boolean success) {
      this.success = success;
      setSuccessIsSet(true);
      return this;
    }

    public void unsetSuccess() {
      __isset_bitfield = EncodingUtils.clearBit(__isset_bitfield, __SUCCESS_ISSET_ID);
    }

    /** Returns true if field success is set (has been assigned a value) and false otherwise */
    public boolean isSetSuccess() {
      return EncodingUtils.testBit(__isset_bitfield, __SUCCESS_ISSET_ID);
    }

    public void setSuccessIsSet(boolean value) {
      __isset_bitfield = EncodingUtils.setBit(__isset_bitfield, __SUCCESS_ISSET_ID, value);
    }

    public org.apache.airavata.model.error.InvalidRequestException getIre() {
      return this.ire;
    }

    public isWorkflowExistWithName_result setIre(org.apache.airavata.model.error.InvalidRequestException ire) {
      this.ire = ire;
      return this;
    }

    public void unsetIre() {
      this.ire = null;
    }

    /** Returns true if field ire is set (has been assigned a value) and false otherwise */
    public boolean isSetIre() {
      return this.ire != null;
    }

    public void setIreIsSet(boolean value) {
      if (!value) {
        this.ire = null;
      }
    }

    public org.apache.airavata.model.error.AiravataClientException getAce() {
      return this.ace;
    }

    public isWorkflowExistWithName_result setAce(org.apache.airavata.model.error.AiravataClientException ace) {
      this.ace = ace;
      return this;
    }

    public void unsetAce() {
      this.ace = null;
    }

    /** Returns true if field ace is set (has been assigned a value) and false otherwise */
    public boolean isSetAce() {
      return this.ace != null;
    }

    public void setAceIsSet(boolean value) {
      if (!value) {
        this.ace = null;
      }
    }

    public org.apache.airavata.model.error.AiravataSystemException getAse() {
      return this.ase;
    }

    public isWorkflowExistWithName_result setAse(org.apache.airavata.model.error.AiravataSystemException ase) {
      this.ase = ase;
      return this;
    }

    public void unsetAse() {
      this.ase = null;
    }

    /** Returns true if field ase is set (has been assigned a value) and false otherwise */
    public boolean isSetAse() {
      return this.ase != null;
    }

    public void setAseIsSet(boolean value) {
      if (!value) {
        this.ase = null;
      }
    }

    public org.apache.airavata.model.error.AuthorizationException getAe() {
      return this.ae;
    }

    public isWorkflowExistWithName_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, Object value) {
      switch (field) {
      case SUCCESS:
        if (value == null) {
          unsetSuccess();
        } else {
          setSuccess((Boolean)value);
        }
        break;

      case IRE:
        if (value == null) {
          unsetIre();
        } else {
          setIre((org.apache.airavata.model.error.InvalidRequestException)value);
        }
        break;

      case ACE:
        if (value == null) {
          unsetAce();
        } else {
          setAce((org.apache.airavata.model.error.AiravataClientException)value);
        }
        break;

      case ASE:
        if (value == null) {
          unsetAse();
        } else {
          setAse((org.apache.airavata.model.error.AiravataSystemException)value);
        }
        break;

      case AE:
        if (value == null) {
          unsetAe();
        } else {
          setAe((org.apache.airavata.model.error.AuthorizationException)value);
        }
        break;

      }
    }

    public Object getFieldValue(_Fields field) {
      switch (field) {
      case SUCCESS:
        return Boolean.valueOf(isSuccess());

      case IRE:
        return getIre();

      case ACE:
        return getAce();

      case ASE:
        return getAse();

      case AE:
        return getAe();

      }
      throw new IllegalStateException();
    }

    /** Returns true if field corresponding to fieldID is set (has been assigned a value) and false otherwise */
    public boolean isSet(_Fields field) {
      if (field == null) {
        throw new IllegalArgumentException();
      }

      switch (field) {
      case SUCCESS:
        return isSetSuccess();
      case IRE:
        return isSetIre();
      case ACE:
        return isSetAce();
      case ASE:
        return isSetAse();
      case AE:
        return isSetAe();
      }
      throw new IllegalStateException();
    }

    @Override
    public boolean equals(Object that) {
      if (that == null)
        return false;
      if (that instanceof isWorkflowExistWithName_result)
        return this.equals((isWorkflowExistWithName_result)that);
      return false;
    }

    public boolean equals(isWorkflowExistWithName_result that) {
      if (that == null)
        return false;

      boolean this_present_success = true;
      boolean that_present_success = true;
      if (this_present_success || that_present_success) {
        if (!(this_present_success && that_present_success))
          return false;
        if (this.success != that.success)
          return false;
      }

      boolean this_present_ire = true && this.isSetIre();
      boolean that_present_ire = true && that.isSetIre();
      if (this_present_ire || that_present_ire) {
        if (!(this_present_ire && that_present_ire))
          return false;
        if (!this.ire.equals(that.ire))
          return false;
      }

      boolean this_present_ace = true && this.isSetAce();
      boolean that_present_ace = true && that.isSetAce();
      if (this_present_ace || that_present_ace) {
        if (!(this_present_ace && that_present_ace))
          return false;
        if (!this.ace.equals(that.ace))
          return false;
      }

      boolean this_present_ase = true && this.isSetAse();
      boolean that_present_ase = true && that.isSetAse();
      if (this_present_ase || that_present_ase) {
        if (!(this_present_ase && that_present_ase))
          return false;
        if (!this.ase.equals(that.ase))
          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() {
      List<Object> list = new ArrayList<Object>();

      boolean present_success = true;
      list.add(present_success);
      if (present_success)
        list.add(success);

      boolean present_ire = true && (isSetIre());
      list.add(present_ire);
      if (present_ire)
        list.add(ire);

      boolean present_ace = true && (isSetAce());
      list.add(present_ace);
      if (present_ace)
        list.add(ace);

      boolean present_ase = true && (isSetAse());
      list.add(present_ase);
      if (present_ase)
        list.add(ase);

      boolean present_ae = true && (isSetAe());
      list.add(present_ae);
      if (present_ae)
        list.add(ae);

      return list.hashCode();
    }

    @Override
    public int compareTo(isWorkflowExistWithName_result other) {
      if (!getClass().equals(other.getClass())) {
        return getClass().getName().compareTo(other.getClass().getName());
      }

      int lastComparison = 0;

      lastComparison = Boolean.valueOf(isSetSuccess()).compareTo(other.isSetSuccess());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetSuccess()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.success, other.success);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = Boolean.valueOf(isSetIre()).compareTo(other.isSetIre());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetIre()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.ire, other.ire);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = Boolean.valueOf(isSetAce()).compareTo(other.isSetAce());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetAce()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.ace, other.ace);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = Boolean.valueOf(isSetAse()).compareTo(other.isSetAse());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetAse()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.ase, other.ase);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = 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 {
      schemes.get(iprot.getScheme()).getScheme().read(iprot, this);
    }

    public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException {
      schemes.get(oprot.getScheme()).getScheme().write(oprot, this);
      }

    @Override
    public String toString() {
      StringBuilder sb = new StringBuilder("isWorkflowExistWithName_result(");
      boolean first = true;

      sb.append("success:");
      sb.append(this.success);
      first = false;
      if (!first) sb.append(", ");
      sb.append("ire:");
      if (this.ire == null) {
        sb.append("null");
      } else {
        sb.append(this.ire);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("ace:");
      if (this.ace == null) {
        sb.append("null");
      } else {
        sb.append(this.ace);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("ase:");
      if (this.ase == null) {
        sb.append("null");
      } else {
        sb.append(this.ase);
      }
      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, 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 isWorkflowExistWithName_resultStandardSchemeFactory implements SchemeFactory {
      public isWorkflowExistWithName_resultStandardScheme getScheme() {
        return new isWorkflowExistWithName_resultStandardScheme();
      }
    }

    private static class isWorkflowExistWithName_resultStandardScheme extends StandardScheme<isWorkflowExistWithName_result> {

      public void read(org.apache.thrift.protocol.TProtocol iprot, isWorkflowExistWithName_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: // IRE
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.ire = new org.apache.airavata.model.error.InvalidRequestException();
                struct.ire.read(iprot);
                struct.setIreIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 2: // ACE
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.ace = new org.apache.airavata.model.error.AiravataClientException();
                struct.ace.read(iprot);
                struct.setAceIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 3: // ASE
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.ase = new org.apache.airavata.model.error.AiravataSystemException();
                struct.ase.read(iprot);
                struct.setAseIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 4: // 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, isWorkflowExistWithName_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.ire != null) {
          oprot.writeFieldBegin(IRE_FIELD_DESC);
          struct.ire.write(oprot);
          oprot.writeFieldEnd();
        }
        if (struct.ace != null) {
          oprot.writeFieldBegin(ACE_FIELD_DESC);
          struct.ace.write(oprot);
          oprot.writeFieldEnd();
        }
        if (struct.ase != null) {
          oprot.writeFieldBegin(ASE_FIELD_DESC);
          struct.ase.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 isWorkflowExistWithName_resultTupleSchemeFactory implements SchemeFactory {
      public isWorkflowExistWithName_resultTupleScheme getScheme() {
        return new isWorkflowExistWithName_resultTupleScheme();
      }
    }

    private static class isWorkflowExistWithName_resultTupleScheme extends TupleScheme<isWorkflowExistWithName_result> {

      @Override
      public void write(org.apache.thrift.protocol.TProtocol prot, isWorkflowExistWithName_result struct) throws org.apache.thrift.TException {
        TTupleProtocol oprot = (TTupleProtocol) prot;
        BitSet optionals = new BitSet();
        if (struct.isSetSuccess()) {
          optionals.set(0);
        }
        if (struct.isSetIre()) {
          optionals.set(1);
        }
        if (struct.isSetAce()) {
          optionals.set(2);
        }
        if (struct.isSetAse()) {
          optionals.set(3);
        }
        if (struct.isSetAe()) {
          optionals.set(4);
        }
        oprot.writeBitSet(optionals, 5);
        if (struct.isSetSuccess()) {
          oprot.writeBool(struct.success);
        }
        if (struct.isSetIre()) {
          struct.ire.write(oprot);
        }
        if (struct.isSetAce()) {
          struct.ace.write(oprot);
        }
        if (struct.isSetAse()) {
          struct.ase.write(oprot);
        }
        if (struct.isSetAe()) {
          struct.ae.write(oprot);
        }
      }

      @Override
      public void read(org.apache.thrift.protocol.TProtocol prot, isWorkflowExistWithName_result struct) throws org.apache.thrift.TException {
        TTupleProtocol iprot = (TTupleProtocol) prot;
        BitSet incoming = iprot.readBitSet(5);
        if (incoming.get(0)) {
          struct.success = iprot.readBool();
          struct.setSuccessIsSet(true);
        }
        if (incoming.get(1)) {
          struct.ire = new org.apache.airavata.model.error.InvalidRequestException();
          struct.ire.read(iprot);
          struct.setIreIsSet(true);
        }
        if (incoming.get(2)) {
          struct.ace = new org.apache.airavata.model.error.AiravataClientException();
          struct.ace.read(iprot);
          struct.setAceIsSet(true);
        }
        if (incoming.get(3)) {
          struct.ase = new org.apache.airavata.model.error.AiravataSystemException();
          struct.ase.read(iprot);
          struct.setAseIsSet(true);
        }
        if (incoming.get(4)) {
          struct.ae = new org.apache.airavata.model.error.AuthorizationException();
          struct.ae.read(iprot);
          struct.setAeIsSet(true);
        }
      }
    }

  }

}
